是否有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
      on
      document
      被许多基于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);
}