Заменить текст на сайте

Я пытаюсь заменить текст на веб-странице (любой веб-странице, на которой я хочу его запустить) с помощью JavaScript. Я не эксперт в JavaScript, поэтому я в некотором роде потерян. Если я могу помочь, я бы хотел избежать jQuery.

Через гугл я нашел этот вопрос переполнения стека. Но когда я делаю инъекцию document.body.innerHTML = document.body.innerHTML.replace('hello', 'hi'); в веб-страницу это вроде портит страницу вверх. Кажется, чтобы страница вернулась к основному тексту и форматированию.

Кроме того, мне интересно, можно ли использовать здесь код регулярного выражения. Опять же, я действительно не уверен, как его использовать. Что он будет делать, это заменить только текст веб-страницы, а не ссылки или имена файлов.

Я использую Google Chrome, если это важно.

2 ответа

Решение

Вы можете выполнить перестановки на всех текстовых узлах в DOM:

function replaceTextOnPage(from, to){
  getAllTextNodes().forEach(function(node){
    node.nodeValue = node.nodeValue.replace(new RegExp(quote(from), 'g'), to);
  });

  function getAllTextNodes(){
    var result = [];

    (function scanSubTree(node){
      if(node.childNodes.length) 
        for(var i = 0; i < node.childNodes.length; i++) 
          scanSubTree(node.childNodes[i]);
      else if(node.nodeType == Node.TEXT_NODE) 
        result.push(node);
    })(document);

    return result;
  }

  function quote(str){
    return (str+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
  }
}

Функция цитаты заимствована из этого ответа.

Использование:

replaceTextOnPage('hello', 'hi');

Обратите внимание, что вам нужно будет использовать SHIM forEach в старых браузерах или заменить этот код циклом, например:

var nodes = getAllTextNodes();
for(var i = 0; i < nodes.length; i++){
    nodes[i].nodeValue = nodes[i].nodeValue.replace(new RegExp(quote(from), 'g'), to);
}

Недавно мне пришлось столкнуться с подобной проблемой, и я придумал что-то похожее на это:

<!DOCTYPE html>
<html>
<head>
  <title>HTML JS REPLACE</title>
  <script type="text/javascript">
  function convert(elem) {
    var content = document.getElementById(elem).innerHTML; // get HTML content for the given element
    var pattern = new RegExp(/hello/gi);
    content = content.replace(pattern,'hi');
    document.getElementById(elem).innerHTML = content; // put the replace content back
  }
  </script>
</head>
<body>
  <div id="content">
    Some text that includes both hello and hi. And a hello.
  </div>
  <script type="text/javascript">
    window.onload = convert('content');
  </script>
</body>
</html>

В результате вы получите страницу со следующим текстом:

Некоторый текст, который включает и привет и привет. И привет.

в то время как первоисточник все еще говорит:

Некоторый текст, который включает и привет и привет. И привет.

Сложные биты - это всего лишь несколько - во-первых, вы хотите, чтобы триггер window.onload был включен внизу тела, поэтому DOM загружается полностью, прежде чем запускать на нем какой-либо JS. Во-вторых, у вас должен быть элемент блока верхнего уровня, которому вы назначаете уникальный идентификатор, на который вы можете ссылаться из JS. В-третьих, функция convert использует регулярное выражение, которое выполняет глобальную замену строки "hello" без учета регистра, изменяя ее на "hi".

Ваше конкретное приложение может потребовать вместо этого перехватить все события и затем проанализировать их в цикле, что может (или не может) вызвать некоторые проблемы с производительностью. Быть осторожен:)

Другие вопросы по тегам