【问题标题】:Is there a jquery event that fires when a new node is inserted into the dom?将新节点插入 dom 时是否会触发 jquery 事件?
【发布时间】:2010-10-10 11:43:44
【问题描述】:

当将 dom 元素插入 dom 时,是否会触发事件 jquery?

例如假设我通过 ajax 加载一些内容并将其添加到 DOM,在其他一些 javascript 中我可以使用 .live() 添加一个事件,这样当一个与特定选择器匹配的事件被添加到 DOM 时,事件就会触发说元素。与 $(document).ready() 类似,但内容是动态添加到 DOM 中的。

我的梦想:

$('.myClass').live('ready', function() {
    alert('.myClass added to dom');
});

如果 jquery 不支持这样的事情,那么是否有另一种方法可以在不修改实际执行初始 dom 操作的代码的情况下实现此功能?

【问题讨论】:

  • 您好,要做到这一点,您需要在您的另一段 Javascript 中触发插入。 $("<div class='myClass'>").appendTo(document.body).trigger("ready");
  • 如果您在将 jQuery UI 小部件添加到您的内容的同时将其添加到 DOM,您可以只听[widget]create 事件。 (参见 api.jqueryui.com/jQuery.widget/#event-create ;注意小部件事件前缀。)

标签: jquery html


【解决方案1】:

已弃用:根据@Meglio 下面的评论,DOMNodeInserted 事件已弃用,并将在未来某个未知时间从网络上删除。为获得最佳结果,请开始了解 MutationObserver API

查看@dain 的回答below

如果您将'DOMNodeInserted' event 直接绑定到文档或正文,则每次在任何地方插入任何内容时都会执行它。如果您希望回调仅在添加特定类型的元素时运行,您最好使用delegated events

通常,如果您将一类元素添加到 DOM,您会将它们添加到一个共同的父级。所以像这样附加事件处理程序:

$('body').on('DOMNodeInserted', '#common-parent', function(e) {
  if ($(e.target).attr('class') === 'myClass') {
    console.log('hit');
  }
});

Myke's above 的答案基本相同,但由于您使用的是委托事件处理程序而不是直接事件处理程序,因此其中的代码会被较少触发。

注意:

$('body').on('DOMNodeInserted', '.myClass', function(e) {
  console.log(e.target);
});

这似乎也有效......但我不知道为什么。

【讨论】:

  • 这看起来是最好的答案。我通过定位文档来让它工作。示例:$(document).on('DOMNodeInserted', function(e) { if ($(e.target).children(":first").attr('class') === 'lpChatTextLink') { changeMessage(); } }); 这实际上确实循环了所有内容。没有对上述内容进行太多测试。
  • 我会说这无疑是现代浏览器的最佳答案,但支持只能追溯到 IE9,因此仍需要回退。
  • 已弃用:此功能已从 Web 中删除。尽管某些浏览器可能仍然支持它,但它正在被删除。不要在旧项目或新项目中使用它。使用它的页面或 Web 应用程序可能随时中断。 developer.mozilla.org/en-US/docs/Web/Guide/Events/… --- 使用 MutationObservers 代替:developer.mozilla.org/en-US/docs/Web/API/MutationObserver
  • @Meglio 的工作是“使用 Mutation Observers 而不是如果可能。” (强调补充)。另见:developer.mozilla.org/en-US/docs/Web/API/…
  • 这太简单了,太实用了,我们必须立即弃用它!...有时我讨厌网络。
【解决方案2】:

.livequery() plugin 仍然可以满足这一小众需求,如下所示:

$('.myClass').livequery(function() {
  alert('.myClass added to dom');
});

如果你向它传递只是一个像上面这样的回调函数,它将为它找到的每个新元素运行,无论是最初还是添加时。函数内部this指的是刚刚添加的元素。

.live() 监听冒泡的事件,因此不适合这种“添加元素时”的情况,在这方面,.livequery()(插件)没有完全替换为在核心中添加了.live(),只有事件冒泡部分(大部分)是。

【讨论】:

  • 对于那些好奇 livequery 是如何工作的人来说,没有 setTimeout 或任何愚蠢的东西; livequery 只是“代理”浏览器的 DOM 操作方法
  • 实际上它 愚蠢,因为它只是短路 jQuery DOM 操作方法以便在调用时执行一些代码。如果不使用 jQuery 方法更新 DOM,它将无法工作。
  • 插件似乎死了。对于现在正在查看此内容的任何人,请查看insertionQuery。使用 CSS 检测新元素的有趣库。
【解决方案3】:

如果你生活在最前沿,你可以使用 MutationObserver :)

  var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
  var list = document.querySelector('ol');

  var observer = new MutationObserver(function(mutations) {  
    mutations.forEach(function(mutation) {
      if (mutation.type === 'childList') {
        var list_values = [].slice.call(list.children)
            .map( function(node) { return node.innerHTML; })
            .filter( function(s) {
              if (s === '<br>') {
                return false;
              }
              else {
                return true;
              }
        });
        console.log(list_values);
      }
    });
  });

  observer.observe(list, {
    attributes: true, 
    childList: true, 
    characterData: true 
   });

见:https://hacks.mozilla.org/2012/05/dom-mutationobserver-reacting-to-dom-changes-without-killing-browser-performance/

编辑:这个答案已经很老了,现在除了 Opera Mini 之外的所有浏览器都支持 MutationObserver:http://caniuse.com/#feat=mutationobserver

另外,这里是 MDN 上 API 的直接链接:https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

【讨论】:

    【解决方案4】:

    没有jQuery事件,但是有一个DOM事件:DOMNodeInsertedIntoDocument。您可以使用 jQuery 的 on 方法监听 DOM 事件。所以:

    $('.myClass').on('DOMNodeInsertedIntoDocument', function() {
      alert('myClass was inserted into the DOM');
    }
    

    这可能比使用 liveQuery 更可取,因为该插件有点陈旧(2 年以上没有更新,只承诺支持 jQuery 1.2.x)。

    【讨论】:

    • 我无法让它以任何方式工作...关于如何使其工作的任何见解?
    • 这不起作用,因为您在元素插入 dom 之前将事件处理程序附加到元素,因此选择器可能返回空元素集。另一种方法是使用委托,例如 -- ** $(document.body).on('DOMNodeInsertedIntoDocument', '.myClass', function() { alert('myClass was inserted into the DOM'); }* * -- 但这也不起作用,因为 DOMNodeInsertedIntoDocument 不会冒泡。
    【解决方案5】:

    看看insertionQuery。这是一个有趣的库,它使用 CSS 来检测新元素。因为它使用 CSS,所以不会影响性能,并且您会返回与选择器匹配的实际元素。

    【讨论】:

    • 这是解决问题的一种非常聪明的方法。为 GitHub 存储库加注星标以供以后使用。
    猜你喜欢
    • 1970-01-01
    • 2011-07-03
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多