本质上,我希望在div
的内容改变时执行一个脚本。 由于脚本是分开的(Chrome扩展中的内容脚本和网页脚本),我需要一种简单地观察DOM状态变化的方法。 我可以设置投票,但这似乎太草率了。
很长一段时间以来,DOM3突变事件是最佳的可用解决方案,但由于性能原因,它们一直被弃用。 DOM4突变观察者是不推荐的DOM3突变事件的替代品。 它们目前在现代浏览器中被实现为MutationObserver
(或者在Chrome的旧版本中被实现为带有供应商前缀的WebKitMutationObserver
):
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
//...
});
此示例侦听document
及其整个子树上的DOM更改,它将在元素属性更改和结构更改时触发。 规范草案包含有效变异侦听器属性的完整列表:
ChildList
true
。属性
true
。特征数据
true
。子树
true
设置为true
AttributeOldValue
attributes
设置为true,则true
,并且需要记录变异之前目标的属性值。CharacterDataOldValue
CharacterData
设置为true,则true
,并且需要记录发生变异之前的目标数据。AttributeFilter
(此列表是截至2014年4月的最新列表;您可以查看规范中的任何更改。)
编辑
这个答案现在被否决了。 请看APSillers的答案。
由于这是针对Chrome扩展的,因此您不妨使用标准DOM事件-DOMSubtreeModified
。 请参阅跨浏览器对此事件的支持。 Chrome从1.0开始就支持它了。
$("#someDiv").bind("DOMSubtreeModified", function() {
alert("tree changed");
});
请参阅此处的工作示例。
许多站点使用AJAX动态地添加/显示/更改内容。 有时它被用来代替站点内导航,因此当前URL被编程更改,并且内容脚本不会被浏览器自动执行,因为页面并不完全是从远程服务器获取的。
>
MutationObserver(docs),以实际检测DOM更改:
用于通过发送DOM事件来通知内容更改的站点的事件侦听器:
pjax:end
在许多基于pjax的站点(如GitHub)使用的文档
上,消息
在窗口
上使用,例如在Chrome浏览器中使用Google search,spfdone
在Youtube使用的文档
上,通过setInterval定期检查DOM:
显然,这只在等待由其ID/selector标识的特定元素出现时起作用,并且它不能让您普遍检测动态添加的新内容,除非您发明了某种类型的现有内容指纹。
在注入的DOM脚本中隐藏历史API:
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();
});
侦听hashchange,popstate事件:
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事件侦听器来向内容脚本发送消息:
>
MANIFEST.JSON:
声明后台/事件页
声明内容脚本
添加“选项卡”
权限。
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();
}
});