Поиск элемента DOM с определенным текстом и изменение его - PullRequest
11 голосов
/ 26 мая 2011

Я пытаюсь выяснить, как в необработанном javascript (без jQuery и т. Д.) Найти элемент с определенным текстом и изменить этот текст.

Мое первое воплощение решения ... недостаточно. То, что я сделал, было в основном:

var x = document.body.innerHTML;
x.replace(/regular-expression/,"text");
document.body.innerHTML = x;

Наивно я думал, что преуспел в полете, особенно потому, что это было так просто. Затем я добавил изображение в свой пример и подумал, что могу проверять каждые 5 секунд (потому что эта строка может динамически вводить DOM) ... и изображение мерцало каждые 5 секунд.

К сожалению.

Итак, должен быть правильный способ сделать это. Способ, который специально выделяет определенный элемент DOM и обновляет текстовую часть этого элемента DOM.

Теперь всегда есть «рекурсивный поиск по детям, пока вы не найдете подход« самый глубокий ребенок со струной », которого я хочу избежать. И даже тогда я скептически отношусь к тому, что «изменение innerHTML на что-то другое» является правильным способом обновления элемента DOM.

Итак, как правильно искать строку в DOM? И как правильно обновить текст элемента DOM?

Ответы [ 5 ]

5 голосов
/ 26 мая 2011

Теперь всегда есть "рекурсивный поиск по дочерним элементам, пока вы не найдете подход" самый глубокий дочерний элемент со строкой ", которого я хочу избежать.

Я хочу найти элемент"в неупорядоченном случайном списке.Теперь нужно пройтись по всем элементам, пока вы не найдете подход, который вы ищете », которого я хочу избежать.

Старая таймерная магнитная лента, записывайте, слушайте, медитируйте.

Кстати, см .: Найти и заменить текст на JavaScript на Блог Джеймса Падолси

5 голосов
/ 26 мая 2011

Не используйте innerHTML с регулярным выражением, оно почти наверняка завершится неудачей для нетривиального содержимого. Кроме того, все еще существуют различия в том, как браузеры генерируют его из живого DOM. Замена innerHTML также удалит любые прослушиватели событий, добавленные как свойства элемента (например, element.onclick = fn).

Лучше всего, если у вас есть строка, заключенная в элемент с атрибутом или свойством, по которому вы можете выполнять поиск (идентификатор, класс и т. Д.), Но при этом поиск текстовых узлов является лучшим подходом.

Редактировать

Попытка использования функции выбора текста общего назначения для документа HTML может привести к очень сложному алгоритму, поскольку строка может быть частью сложной структуры, например ::

<h1>Some <span class="foo"><em>s</em>pecial</span> heading</h1>

Поиск строки «специальный заголовок» сложен, так как разбит на 2 элемента. Обтекание его другим элементом (скажем, для выделения) также не является тривиальным, поскольку получающаяся структура DOM должна быть допустимой. Например, текст, соответствующий «некоторому особенному» в приведенном выше, может быть заключен в span, но не в div.

Любая такая функция должна сопровождаться документацией с указанием ее ограничений и наиболее подходящего использования.

2 голосов
/ 26 мая 2011

Редактировать: изменен querySelectorAll, чтобы получить getElementsByTagName из предложения Роба.

Вы можете использовать функцию getElementsByTagName, чтобы получить все теги на странице. Оттуда вы можете проверить их детей и посмотреть, есть ли у них текстовые узлы в качестве детей. Если они это сделают, то вы посмотрите на их текст и посмотрите, соответствует ли он тому, что вам нужно. Вот пример, который распечатает текст каждого текстового узла в вашем документе с консольным объектом:

var elms = document.getElementsByTagName("*"),
    len = elms.length;
for(var ii = 0; ii < len; ii++) {
    var myChildred = elms[ii].childNodes;
    len2 = myChildred.length;
    for (var jj = 0; jj < len2; jj++) {
        if(myChildred[jj].nodeType === 3) {
            console.log(myChildred[jj].nodeValue);

            // example on update a text node's value
            myChildred[jj].nodeValue = myChildred[jj].nodeValue.replace(/test/,"123");
        }
    }
}

Чтобы обновить текст элемента DOM, просто обновите свойство nodeValue текстового узла.

2 голосов
/ 26 мая 2011

Забудьте регулярные выражения.

Итерируйте по каждому текстовому узлу (и делать это рекурсивно будет наиболее элегантно) и изменяйте текстовые узлы, если текст найден.Если вы просто ищете строку, вы можете использовать indexOf().

0 голосов
/ 26 мая 2011
x.replace(/regular-expression/,"text");

вернет значение, поэтому

var y = x.replace(/regular-expression/,"text");

теперь вы можете назначить новое значение.

document.body.innerHTML = y;

Но вы хотите подумать об этом, вы не хотитеполучить все тело просто для изменения одного небольшого куска кода, почему бы не получить содержимое div или любого другого элемента и т. д.

пример:

<p id='paragraph'>
    ... some text here ...
</p>

теперь вы можете использовать javascript

var para = document.getElementById('paragraph').innerHTML;
var newPara = para.replace(/regex/,'new content');

para.innerHTML = newPara;

Это должен быть самый простой способ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...