Сначала вы тестируете узлы #text
, чтобы узнать, содержит ли текст слово, которое вы пытаетесь выделить, но затем выполняет замену на родительском элементе .innerHTML
. Есть пара проблем с этим.
- Бесконечные замены: При изменении
.innerHTML
родительского элемента вы измените childNodes
массив. Вы делаете это так, чтобы добавить узел в массив, содержащий текст, который нужно заменить. Таким образом, при продолжении сканирования массива childNodes
вы всегда найдете (новый) узел, содержащий текст, который хотите заменить. Итак, вы снова его замените, создав еще один узел с более высоким индексом в массиве childNodes
. Повторите бесконечно.
- Использование RegExp для замены текста в
.innerHTML
. Хотя вы уже протестировали, чтобы текст, который вы хотите заменить, фактически содержался в текстовом узле, это не мешает вашему RegExp от также заменять любые соответствующие слова в фактическом HTML-элементе элемента (например, в src="yourWord"
, href="http://foo.com/yourWord/bar.html"
, или если попытки выделить такие слова, как style
, color
, background
, span
, id
, height
, width
, button
, form
, input
и т.д.).
- Вы не проверяете, хотите ли вы изменить текст в
<script>
или <style>
тегах.
- Вы проверяете, что вы изменяете только текстовые узлы (т. Е. Вы проверяете на
node.nodeType === 3
). Если вы не проверяли для этого вам также будет иметь следующие возможные проблемы, связанные с использованием .innerHTML
для изменения HTML:
- Вы могли бы в конечном итоге изменить атрибуты или фактические HTML-теги, в зависимости от того, что вы меняетесь с
.replace()
. Это может полностью нарушить макет страницы и функциональность.
- При изменении
.innerHTML
DOM для этой части страницы полностью воссоздан. Это означает, что элементы, в то время как новые элементы могут быть одного типа с одинаковыми атрибутами, любые прослушиватели событий, которые были прикреплены к старым элементам, не будут привязаны к новым элементам. Это может значительно нарушить функциональность страницы.
- Неоднократно изменяющиеся большие части DOM могут быть довольно сложными для повторной обработки страницы. В зависимости от того, как вы это сделаете, вы можете столкнуться с серьезными проблемами, связанными с восприятием пользователями.
Таким образом, если вы собираетесь использовать RegExp, чтобы заменить текст, необходимо выполнить операцию только на содержание #text
узла, а не на .innerHTML
родительского узла. Поскольку вы хотите создать дополнительные элементы HTML (например, новые элементы <span style="">
, с дочерними узлами #text
), есть некоторые сложности.
Невозможно присвоить HTML текст в текстовый узел для создания новых HTML-узлов:
Там нет никакого способа, чтобы назначить новый HTML непосредственно в текстовый узел и он оценивается как HTML, создание новых узлов. Присвоение объекту текстового узла .innerHTML
создаст такое свойство в объекте (как и на любом объекте), но не изменит текст, отображаемый на экране (то есть фактическое значение узла #text
). Таким образом, он не выполнит то, что вы хотите сделать: он не будет создавать никаких новых дочерних элементов HTML родительского узла.
Способ сделать это, который имеет наименьшее влияние на DOM страницы (то есть наименее вероятно, чтобы сломать существующий JavaScript на странице), заключается в создании <span>
для включения новых текстовых узлов, которые вы создаете (текст, который был в узел #text
, который не находится в вашем цветном <span>
) вместе с потенциально многочисленными <span>
элементами, которые вы создаете. Это приведет к замене единственного узла #text
одним элементом <span>
. Хотя это создаст дополнительные потомки, оно оставит число дочерних элементов в родительском элементе неизменным. Таким образом, любой JavaScript, который полагался на это, не будет затронут. Учитывая, что мы меняем DOM, нет возможности не разрывать другой JavaScript, но это должно свести к минимуму эту возможность.
Некоторые примеры того, как вы можете это сделать: См this answer (заменяет список слов с этими словами в кнопках) и this answer (места весь текст в <p>
элементы которых разделены пробелами в кнопки) для полных расширений, которые выполняют регулярные выражения замените его новым HTML. См. this answer, который делает в основном то же самое, но делает ссылку (имеет другую реализацию, которая пересекает DOM с помощью TreeWalker, чтобы найти узлы #text
вместо NodeIterator, как используется в двух других примерах).
Вот код, который будет выполнять замену, которую вы желающая на каждом текстовой узле в document.body
и создать новый HTML, необходимый, чтобы иметь style
быть различными в части текста:
Там это другие способы сделать это. Тем не менее, они будут генерировать более значительные изменения в структуре дочерних элементов для этого конкретного элемента (например, несколько дополнительных узлов родительского элемента). У этого есть более высокий потенциал для взлома любого JavaScript уже на странице, которая опирается на текущую структуру страницы. Фактически, любое изменение, подобное этому, может нарушить текущий JavaScript.
Код в этом ответе был изменен из кода в this other answer of mine
Вы вошли в систему, что означало 'replaceText' для значения? –
@ScottMarcus, когда я записываю 'replaceText', он показывает правильное значение, которое представляет собой, например,' teste '. Однако, если я использую это на 'element.innerHTML', он сбрасывает мою вкладку. – rafaelcpalmeida
Вы уверены, что в консоли отображается последовательность '' '' escape-последовательности? Вы пытались изменить строку: '' $ 1 "'? –