Обновление:
Немного поздно для обновления, но поскольку я просто наткнулся на этот вопрос и заметил, что мой предыдущий ответ не тот, которым я доволен. Поскольку вопрос заключался в замене одного слова, невероятно, что никто не думал об использовании границ слов (\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
Несколько лет спустя в настоящее время официально существует лучшее решение. 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
blockquote>
- Установить список локальных имен атрибутов (без пространства имен) если не все атрибутные мутации
(Этот список действует с апреля 2014 года; вы можете проверить спецификацию на любые изменения.)
Старое содержимое этого ответа теперь устарело . См. Другие ответы на основе MutationObserver
.
Другой подход в зависимости от того, как вы меняете 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.
Многие сайты используют AJAX для динамического добавления / отображения / изменения контента. Иногда он используется вместо навигации по сайту, поэтому текущий URL-адрес изменяется программно, а сценарии содержимого в этом случае автоматически не выполняются браузером, так как страница не извлекается с удаленного сервера целиком.
pjax:end
в document
, используемое многими сайтами на основе pjax, например. GitHub, см. Как запустить jQuery до и после загрузки pjax? message
на window
, используемом, например, Поиск Google в браузере Chrome, см. Расширение Chrome обнаруживает обновление поиска Google spfdone
в document
, используемое Youtube, см. . Как определить навигацию по страницам на Youtube и изменять HTML до отображения страницы? document.head.appendChild(document.createElement('script')).text = '(' +
function() {
// injected DOM script is not a content script anymore,
// it can modify objects and functions of the page
var _pushState = history.pushState;
history.pushState = function(state, title, url) {
_pushState.call(this, state, title, url);
window.dispatchEvent(new CustomEvent('state-changed', {detail: state}));
};
// repeat the above for replaceState too
} + ')(); this.remove();'; // remove the DOM script element
// And here content script listens to our DOM script custom events
window.addEventListener('state-changed', function(e) {
console.log('History state changed', e.detail, location.hash);
doSomething();
});
window.addEventListener('hashchange', function(e) {
console.log('URL hash changed', e);
doSomething();
});
window.addEventListener('popstate', function(e) {
console.log('State changed', e);
doSomething();
});
Для работы с навигацией существует расширенный API: webNavigation , webRequest , но мы будем использовать простой chrome.tabs.onUpdated прослушиватель событий, который посылает сообщение к скрипту содержимого:
"tabs"
разрешено . 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');
}
});
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg === 'url-update') {
doSomething();
}
});
В дополнение к «необработанным» инструментам, предоставленным 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);
}