document.querySelectorAll () не работает должным образом в сценарии Greasemonkey 3.11 в Firefox 54.0.1 [duplicate]

Обновление:

Немного поздно для обновления, но поскольку я просто наткнулся на этот вопрос и заметил, что мой предыдущий ответ не тот, которым я доволен. Поскольку вопрос заключался в замене одного слова, невероятно, что никто не думал об использовании границ слов (\b)

'a cat is not a caterpillar'.replace(/\bcat\b/gi,'dog');
//"a dog is not a caterpillar"

Это простое регулярное выражение, которое позволяет избежать замены частей слов в большинстве случаев. Однако тире - по-прежнему считается границей слова. Таким образом, условные выражения могут использоваться в этом случае, чтобы избежать замены строк, таких как cool-cat:

'a cat is not a cool-cat'.replace(/\bcat\b/gi,'dog');//wrong
//"a dog is not a cool-dog" -- nips
'a cat is not a cool-cat'.replace(/(?:\b([^-]))cat(?:\b([^-]))/gi,'$1dog$2');
//"a dog is not a cool-cat"

в основном, этот вопрос такой же, как и здесь: Javascript replace & quot; '& quot; с " '' & quot;

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

var newText = "the cat looks like a cat".split('cat').join('dog');

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

var regText = "the cat looks like a cat".replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");

Выход такой же, как и принятый ответ , однако, используя выражение / cat / g в этой строке:

var oops = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/cat/g,'dog');
//returns "the dog looks like a dog, not a dogerpillar or cooldog" ?? 

На самом деле, это, вероятно, не то, что вы хотите. Что же тогда? IMHO, регулярное выражение, которое заменяет «cat» условно. (т. е. не является частью слова), например:

var caterpillar = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");
//return "the dog looks like a dog, not a caterpillar or coolcat"

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

http://www.javascriptkit.com/jsref/regexp.shtml

http://www.regular-expressions.info


Окончательное дополнение:

Учитывая, что этот вопрос по-прежнему получает много просмотров, Я думал, что могу добавить пример .replace, используемый с функцией обратного вызова. В этом случае он значительно упрощает выражение и обеспечивает еще большую гибкость, например, замену правильной капитализацией или замену как cat, так и cats за один раз:

'Two cats are not 1 Cat! They\'re just cool-cats, you caterpillar'
   .replace(/(^|.\b)(cat)(s?\b.|$)/gi,function(all,char1,cat,char2)
    {
       //check 1st, capitalize if required
       var replacement = (cat.charAt(0) === 'C' ? 'D' : 'd') + 'og';
       if (char1 === ' ' && char2 === 's')
       {//replace plurals, too
           cat = replacement + 's';
       }
       else
       {//do not replace if dashes are matched
           cat = char1 === '-' || char2 === '-' ? cat : replacement;
       }
       return char1 + cat + char2;//return replacement string
    });
//returns:
//Two dogs are not 1 Dog! They're just cool-cats, you caterpillar

337
задан Xan 10 May 2016 в 11:48
поделиться

5 ответов

Несколько лет спустя в настоящее время официально существует лучшее решение. DOM4 Mutation Observers заменяют устаревшие события мутации DOM3. Они , которые в настоящее время реализованы в современных браузерах как MutationObserver (или как префикс поставщика WebKitMutationObserver в старых версиях Chrome):

MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

var observer = new MutationObserver(function(mutations, observer) {
    // fired when a mutation occurs
    console.log(mutations, observer);
    // ...
});

// define what element should be observed by the observer
// and what types of mutations trigger the callback
observer.observe(document, {
  subtree: true,
  attributes: true
  //...
});

В этом примере прослушивается DOM изменения на document и все его поддерево, и оно будет срабатывать при изменении атрибутов элемента, а также структурных изменений. Спецификация проекта имеет полный список действительных свойств для прослушивания мутаций :

childList

  • Установите значение true, если мутации для целей дети должны быть обнаружены.

attributes

  • Установите на true, если необходимо соблюдать мутации для атрибутов цели.

characterData

  • Установите на true, если необходимо наблюдать мутации данных цели.

поддерево

  • Установите, чтобы true, если мутации не просто нацелены, но также должны наблюдаться потомки цели.

attributeOldValue

  • Установите значение true если attributes установлено значение true и значение атрибута цели до того, как необходимо записать мутацию.

characterDataOldValue

  • Установите значение true, если characterData установлено значение true и данные цели до того, как необходимо записать мутацию.

attributeFilter

  • Установить список локальных имен атрибутов (без пространства имен) если не все атрибутные мутации

(Этот список действует с апреля 2014 года; вы можете проверить спецификацию на любые изменения.)

399
ответ дан apsillers 28 August 2018 в 15:21
поделиться

Старое содержимое этого ответа теперь устарело . См. Другие ответы на основе MutationObserver.

193
ответ дан Community 28 August 2018 в 15:21
поделиться

Другой подход в зависимости от того, как вы меняете div. Если вы используете JQuery для изменения содержимого div с помощью метода html (), вы можете расширить этот метод и вызвать функцию регистрации каждый раз, когда вы помещаете html в div.

(function( $, oldHtmlMethod ){
    // Override the core html method in the jQuery object.
    $.fn.html = function(){
        // Execute the original HTML method using the
        // augmented arguments collection.

        var results = oldHtmlMethod.apply( this, arguments );
        com.invisibility.elements.findAndRegisterElements(this);
        return results;

    };
})( jQuery, jQuery.fn.html );

Мы просто перехватываем вызывает html (), вызывает функцию регистрации с этим, которая в контексте относится к целевому элементу, получающему новый контент, затем мы передаем вызов исходной функции jquery.html (). Не забудьте вернуть результаты исходного метода html (), потому что JQuery ожидает его для цепочки методов.

Для получения дополнительной информации об переопределении и расширении метода проверьте http: //www.bennadel. com / blog / 2009-Using-Self-Executing-Function-Arguments-To-Override-Core-jQuery-Methods.htm , где я скрещивал функцию закрытия. Также ознакомьтесь с учебником плагинов на сайте JQuery.

24
ответ дан Seth Malaki 28 August 2018 в 15:21
поделиться

Многие сайты используют AJAX для динамического добавления / отображения / изменения контента. Иногда он используется вместо навигации по сайту, поэтому текущий URL-адрес изменяется программно, а сценарии содержимого в этом случае автоматически не выполняются браузером, так как страница не извлекается с удаленного сервера целиком.


Обычные JS-методы обнаружения изменений страницы, доступные в сценарии контента .


Специфические расширения: обнаружение изменений URL на странице background / .

Для работы с навигацией существует расширенный API: webNavigation , webRequest , но мы будем использовать простой chrome.tabs.onUpdated прослушиватель событий, который посылает сообщение к скрипту содержимого:

  • manifest.json: declare background / event page объявить скрипт содержимого добавить "tabs" разрешено .
  • background.js
    var rxLookfor = /^https?:\/\/(www\.)?google\.(com|\w\w(\.\w\w)?)\/.*?[?#&]q=/;
    chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
        if (rxLookfor.test(changeInfo.url)) {
            chrome.tabs.sendMessage(tabId, 'url-update');
        }
    });
    
  • content.js
    chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
        if (msg === 'url-update') {
            doSomething();
        }
    });
    
25
ответ дан wOxxOm 28 August 2018 в 15:21
поделиться

В дополнение к «необработанным» инструментам, предоставленным MutationObserver API , существуют «удобные» библиотеки для работы с DOM-мутациями.

Рассмотрим: MutationObserver представляет каждый DOM изменение в терминах поддеревьев. Итак, если вы, например, ожидаете, что какой-то элемент будет вставлен, он может быть глубоко внутри детей mutations.mutation[i].addedNodes[j].

Еще одна проблема заключается в том, что ваш собственный код в ответ на мутации, изменения DOM - вы часто хотите отфильтровать его.

Хорошая библиотека удобства, разрешающая такие проблемы, - mutation-summary (отказ от ответственности: я не автор, просто доволен user), который позволяет вам указывать запросы о том, что вас интересует, и получить именно это.

Пример основного использования из документов:

var observer = new MutationSummary({
  callback: updateWidgets,
  queries: [{
    element: '[data-widget]'
  }]
});

function updateWidgets(summaries) {
  var widgetSummary = summaries[0];
  widgetSummary.added.forEach(buildNewWidget);
  widgetSummary.removed.forEach(cleanupExistingWidget);
}
3
ответ дан Xan 28 August 2018 в 15:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: