是否有JavaScript / jQuery DOM更改侦听器?

2020/09/28 12:21 · javascript ·  · 0评论

本质上,我希望DIV更改内容时执行脚本由于脚本是分开的(Chrome扩展程序和网页脚本中的内容脚本),因此我需要一种方法来简单地观察DOM状态的变化。我可以设置轮询,但这似乎草率。

长期以来,DOM3突变事件是最佳的可用解决方案,但由于性能原因,已不推荐使用它们。DOM4突变观察者代替了不推荐使用的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是否观察到目标儿童的突变。

属性

  • 设置为true是否要观察到目标属性的突变。

characterData

  • 设置为true是否将观察到目标数据的变异。

子树

  • 设置为true是否不仅要观察目标,还要观察目标的后代的突变。

attributeOldValue

  • 设置为trueif时attributes将其设置为true,并且需要记录突变之前的目标属性值。

characterDataOldValue

  • 设置为trueif如果characterData设置为true,则需要记录突变之前的目标数据。

attributeFilter

  • 如果不需要观察所有属性突变,则设置为属性本地名称(无名称空间)的列表。

(此列表是截至2014年4月的最新信息;您可以检查规格中是否有任何更改。)

编辑

现在不赞成使用此答案。a虫者的答案

由于这是针对Chrome扩展程序的,因此您最好使用标准DOM事件- DOMSubtreeModified查看各浏览器对此事件的支持从1.0开始,Chrome已支持该功能。

$("#someDiv").bind("DOMSubtreeModified", function() {
    alert("tree changed");
});

在这里查看工作示例

许多网站使用AJAX / XHR / fetch来动态添加,显示,修改内容和window.history API,而不是现场导航,因此可以通过编程方式更改当前URL。这些站点称为SPA,是“单页应用程序”的缩写。


检测页面变化的常用JS方法

  • MutationObserverdocs)从字面上检测DOM更改:

  • 通过发送DOM事件来发出内容更改信号的站点的事件侦听器:

  • 通过setInterval进行DOM的定期检查

    显然,这仅在以下情况下有效:当您等待由其ID /选择器标识的特定元素出现时,除非您发明了某种指纹识别方法,否则它不会让您普遍检测到动态添加的新内容。现有内容。

  • 隐藏真实记录API

    let _pushState = History.prototype.pushState;
    History.prototype.pushState = function (state, title, url) {
      _pushState.call(this, state, title, url);
      console.log('URL changed', url)
    };
    
  • hashchangepopstate事件:

    window.addEventListener('hashchange', e => {
      console.log('URL hash changed', e);
      doSomething();
    });
    window.addEventListener('popstate', e => {
      console.log('State changed', e);
      doSomething();
    });
    


扩展特定的方法

所有上述方法都可以在内容脚本中使用请注意,通过网页中的window.history进行程序化导航时,浏览器不会自动执行内容脚本,因为仅URL发生了更改,但页面本身保持不变(内容脚本在页面生存期内仅自动运行一次) 。

现在让我们看一下后台脚本。

后台 / 事件页面中检测URL更改

有一些用于导航的高级API:webNavigationwebRequest,但是我们将使用简单的chrome.tabs.onUpdated事件侦听器,该消息将消息发送到内容脚本:

  • manifest.json:

    声明
    背景/事件页面,

    声明
    内容脚本

    添加
    "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((msg, sender, sendResponse) => {
      if (msg === 'url-update') {
        // doSomething();
      }
    });
    

另一种方法取决于您如何更改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希望将其用于方法链接。

有关方法重写和扩展的更多信息,请访问http://www.bennadel.com/blog/2009-Using-Self-Executing-Function-Arguments-To-Override-Core-jQuery-Methods.htm,该文件位于我将闭包函数命名为crisp。还可以在JQuery的站点上查看插件教程。

除了MutationObserverAPI提供的“原始”工具之外,还存在用于处理DOM突变的“便捷”库。

考虑:MutationObserver用子树表示每个DOM更改。因此,例如,如果您正在等待插入某个元素,则该元素可能位于的子元素内部mutations.mutation[i].addedNodes[j]

另一个问题是,当您自己的代码因应突变而更改DOM时-您通常希望将其过滤掉。

一个很好的解决此类问题的便捷库是mutation-summary(免责声明:我不是作者,只是一个满意的用户),它使您可以指定对自己感兴趣的内容的查询,并获得确切的信息。

文档中的基本用法示例:

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);
}
本文地址:http://javascript.askforanswer.com/shifouyoujavascript-jquery-domgenggaizhentingqi.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!