Замените текст, но сохраните ссылки в сценариях содержимого расширений Google Chrome.

Я пытаюсь заменить слова в Google Chrome, но столкнулся с проблемой. Я могу успешно заменить определенные слова, но это убивает связанные html-ссылки.

Как сохранить ссылки живыми и при этом заменить текст?

Это код в моих сценариях содержимого расширений Chrome:

wordDict = {"the":"piano","and":"Hello", "a":"huh?"};

for (word in wordDict) {
    document.body.innerHTML = document.body.innerHTML.replace(
        new RegExp('\\b' + word + '\\b',"gi"), wordDict[word]
    );
};

person Lance    schedule 12.01.2016    source источник
comment
как насчет использования innerText вместо innerHTML?   -  person Lucas Rodrigues    schedule 12.01.2016
comment
Просто пройдясь по дереву DOM. Вместо того, чтобы выполнять глупую простую замену регулярных выражений, посмотрите на .innerTextmember каждого узла в дереве и замените текст в здесь. (а) это не коснется целей ссылки, (б) это не приведет к удалению каких-либо прослушивателей событий.   -  person enhzflep    schedule 12.01.2016
comment
Если вы можете использовать jQuery.. $('a').text("Anything");, вы также можете запустить jQuery.each() итератор   -  person miguelmpn    schedule 12.01.2016
comment
innerText, кажется, уничтожает весь веб-сайт и просто выплевывает кучу неформатированного текста — не то, к чему я стремился.   -  person Lance    schedule 12.01.2016
comment
У меня загружен jquery. Дайте мне немного времени, чтобы понять, что означает ваш код jquery, чтобы я мог отформатировать его для своей проблемы.   -  person Lance    schedule 12.01.2016
comment
Попробуйте мое решение ниже. InnerText также должен работать, но ваша замена может быть неправильной, попробуйте другие замены.   -  person miguelmpn    schedule 12.01.2016
comment
См. подробный ответ здесь: stackoverflow.com/a/34607278/2445882   -  person minj    schedule 14.01.2016


Ответы (2)


Я не эксперт по выражениям регулярных выражений, поэтому это решение найти на странице одну гиперссылку, содержащую одно слово, и заменить ее другим.

for(var i = 0, l=document.links.length; i<l; i++) {
  if(document.links[i].innerText == "Word"){
    document.links[i].innerText = "Other Word";
  }
}

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

С другой стороны, поскольку вы сказали, что у вас загружен jQuery, это решение jQuery делает то, что вы намеревались, оно ищет во всех тегах слова и заменяет их.

jQuery.each( wordDict , function( key, value ) {
  jQuery( "a" ).each(function(){
    if(jQuery(this).text().match(key)) jQuery(this).text(value);
  });
});

Каждый первый jQuery зацикливает строковый объект, а второй зацикливает все теги на странице, если есть совпадение, он изменяет текст элемента на значение объекта.

person miguelmpn    schedule 12.01.2016
comment
Не формулируйте свой ответ так, как будто вы просто вставляете случайный фрагмент кода и не уверены, что он работает. Это не делает его хорошим, даже если он работает и не помогает другим. Объясните проблему и покажите ответ, который, по вашему мнению, работает (и объясните, почему) — если это не так, кто-нибудь скажет вам об этом в комментариях. - person Xan; 13.01.2016
comment
Я проверил оба, это не значит, что это сработает для него.. Как видите, я изо всех сил пытался понять и помочь ему, может быть, эти слова были не самыми лучшими (у вас это работает?), но я просто пытался чтобы получить его отзыв о моем подходе - person miguelmpn; 13.01.2016
comment
Не вижу проблемы в том, чтобы спросить, но это буквально единственный текст, который сопровождает ваш ответ. Если бы вы могли реструктурировать его как (краткое объяснение) (код) Помогает ли это? это был бы гораздо лучший ответ. - person Xan; 13.01.2016

Хорошо! Спустя 2 недели я наконец решил проблему. Что игнорировалось, так это дочерние узлы внутри DOM. Код, который я использую ниже, эффективно обращается к дочерним узлам и сохраняет исходный вид скрипта!

function replaceText(jsonArr) {
$("body *").textFinder(function() {
    for (var key in jsonArr) {
        var matcher = new RegExp('\\b' + key + '\\b', "gi");
        this.data = this.data.replace(matcher, jsonArr[key]);
    }
});
}

// jQuery plugin to find and replace text
jQuery.fn.textFinder = function( fn ) {
this.contents().each( scan );
// callback function to scan through the child nodes recursively
function scan() {
    var node = this.nodeName.toLowerCase();
    if( node === '#text' ) {
        fn.call( this );
    } else if( this.nodeType === 1 && this.childNodes && this.childNodes[0] && node !== 'script' && node !== 'textarea' ) {
        $(this).contents().each( scan );
    }
}
return this;
};
person Lance    schedule 25.01.2016