是否有JavaScript/jQuery DOM更改侦听器?
本质上,我希望在是否有JavaScript/jQuery DOM更改侦听器?,javascript,jquery,google-chrome-extension,Javascript,Jquery,Google Chrome Extension,本质上,我希望在DIV的内容更改时执行脚本。由于脚本是独立的(Chrome扩展和网页脚本中的内容脚本),我需要一种方法来简单地观察DOM状态的变化。我可以设置投票,但这似乎太草率了。编辑 这个答案现在已被弃用。请看下面的答案 因为这是一个Chrome扩展,所以您最好使用标准的DOM事件-domsubtreemedited。请参阅跨浏览器对此的支持。Chrome从1.0开始就支持它 $("#someDiv").bind("DOMSubtreeModified", function() {
DIV
的内容更改时执行脚本。由于脚本是独立的(Chrome扩展和网页脚本中的内容脚本),我需要一种方法来简单地观察DOM状态的变化。我可以设置投票,但这似乎太草率了。编辑
这个答案现在已被弃用。请看下面的答案
因为这是一个Chrome扩展,所以您最好使用标准的DOM事件-domsubtreemedited
。请参阅跨浏览器对此的支持。Chrome从1.0开始就支持它
$("#someDiv").bind("DOMSubtreeModified", function() {
alert("tree changed");
});
请参阅一个工作示例。另一种方法取决于您如何更改div。 如果您使用JQuery通过其html()方法更改div的内容,那么可以扩展该方法,并在每次将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希望它用于方法链接
有关方法重写和扩展的更多信息,请查看,这是我创建闭包函数的地方。还可以在JQuery的站点上查看插件教程。很长一段时间以来,DOM3突变事件是最好的解决方案,但由于性能原因,它们一直被弃用。是不推荐的DOM3突变事件的替代品。它们作为
MutationObserver
(或者作为旧版Chrome中供应商前缀WebKitMutationObserver
):
此示例侦听文档及其整个子树上的DOM更改,并在元素属性更改和结构更改时触发。规范草案包含以下有效规范的完整列表:
儿童列表
- 如果要观察到目标儿童的突变,则设置为
true
属性
- 如果要观察到目标属性的突变,则设置为
true
字符数据
- 如果要观察到目标数据的突变,则设置为
true
子树
- 如果不仅要观察到目标基因的突变,而且还要观察到目标基因的后代,则设置为
true
属性值
- 如果
attributes
设置为true并且需要记录突变前目标的属性值,则设置为true
characterDataOldValue
- 如果
characterData
设置为true并且需要记录突变前的目标数据,则设置为true
属性过滤器
- 如果不需要观察所有属性突变,则设置为属性本地名称列表(不带命名空间)
(此列表截至2014年4月最新;您可以检查规范是否有任何更改。)除了提供的“原始”工具外,还有一些“方便”库可用于处理DOM突变
考虑:MutationObserver用子树表示每个DOM更改。因此,例如,如果您正在等待插入某个元素,则该元素可能深入到突变.mutation[i].addedNodes[j]
的子元素中
另一个问题是,当您自己的代码对突变做出反应时,会更改DOM—您通常希望将其过滤掉
解决这些问题的一个很好的便利库是(免责声明:我不是作者,只是一个满意的用户),它使您能够指定您感兴趣的查询,并准确地获得这些查询
文档中的基本用法示例:
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);
}
许多站点使用AJAX/XHR/fetch来动态添加、显示、修改内容和window.history API,而不是站点内导航,因此当前URL会以编程方式更改。这类网站称为SPA,是单页应用程序的缩写
检测页面更改的常用JS方法
- MutationObserver()以检测DOM更改:
-
-
- 简单的例子:
let lastUrl=location.href;
新的MutationObserver(()=>{
const url=location.href;
如果(url!==lastUrl){
lastUrl=url;
onUrlChange();
}
}).observe(文档,{subtree:true,childList:true});
函数onUrlChange(){
log('URL已更改!',location.href);
}
- 事件侦听器对于通过发送DOM事件来表示内容更改的站点:
pjax:end
ondocument
被许多基于pjax的网站使用,例如GitHub,
看
消息
在窗口
上使用,例如在Chrome浏览器中进行谷歌搜索,
看
yt导航完成
被Youtube使用,
看
- 通过setInterval定期检查DOM:
显然,这只在等待由id/选择器标识的特定元素出现的情况下起作用,并且它不会让您全面检测新的动态添加内容,除非您对现有内容发明某种指纹
- 伪装:
let_pushState=History.prototype.pushState;
History.prototype.pushState=函数(状态、标题、url){
_调用(this、state、title、url);
console.log('URL已更改',URL)
};
- 倾听,事件:
window.addEventListener('hashchange',e=>{
log('URL哈希已更改',e);
doSomething();
});
window.addEventListener('popstate',e=>{
console.log('State changed',e);
doSomething();
});
另外,所有这些方法都可以在WebExtension中使用。它是
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);
}