【问题标题】:How can I detect when a new element has been added to the document in jquery?如何检测何时将新元素添加到 jquery 的文档中?
【发布时间】:2011-01-24 10:14:13
【问题描述】:

如何在 jquery 中检测何时将新元素添加到文档中?

说明: 我想知道何时将具有“列标题”类的元素添加到文档中。因为我计划在这些元素上运行一些 javascript。

我该怎么做?我使用 jQuery javascript 库。

【问题讨论】:

    标签: javascript jquery html css


    【解决方案1】:

    接受的答案使用 2011 年过时的插件,最高投票的答案使用 Mutation 事件,现在是 deprecated

    今天,您应该使用 MutationObserver 来检测元素何时添加到 DOM。 现在所有现代浏览器(Chrome 26+、Firefox 14+)都广泛支持 MutationObservers 、IE11、Edge、Opera 15+ 等)。

    这是一个简单的示例,说明如何使用MutationObserver 来监听元素何时添加到 DOM。

    为简洁起见,我使用 jQuery 语法来构建节点并将其插入到 DOM 中。

    var myElement = $("<div>hello world</div>")[0];
    
    var observer = new MutationObserver(function(mutations) {
       if (document.contains(myElement)) {
            console.log("It's in the DOM!");
            observer.disconnect();
        }
    });
    
    observer.observe(document, {attributes: false, childList: true, characterData: false, subtree:true});
    
    $("body").append(myElement); // console.log: It's in the DOM!
    

    只要在document 中添加或删除任何节点,observer 事件处理程序就会触发。在处理程序内部,我们然后执行contains 检查以确定myElement 现在是否在document 中。

    您无需遍历存储在 mutations 中的每个 MutationRecord,因为您可以直接对 myElement 执行 document.contains 检查。

    要提高性能,请将 document 替换为 DOM 中将包含 myElement 的特定元素。

    【讨论】:

      【解决方案2】:
      $(document).bind('DOMNodeInserted', function(e) {
          console.log(e.target, ' was inserted');
      });
      

      DOMNodeInserted 是一个 DOM 级别 3 事件。这反过来意味着,您需要一个相当新的浏览器来支持这种事件。

      参考:MDC

      【讨论】:

      • 嗯...这看起来很有趣。
      • 这是未来发展的最佳选择,IMO。不过需要注意的是,IE8 及更低版本不支持此功能。如果有人只想做一个快速而肮脏的方式来让这样的事情在 IE8 和更低版本中工作并且由于某种原因不想使用 livequery,我在下面添加了一个答案。
      • 自 2016 年起,mutation events 已弃用。建议不要在旧项目或新项目中使用这种技术。皮蒂。
      【解决方案3】:

      如果你想在上面做一些jQuery,你也可以做类似livequery (extra plugin):

      $('column-header').livequery(function()
      {
          // do things here with your column-header, like binding new events and stuff.
          // this function is called when an object is added.
          // check the API for the deletion function and so on.
      });
      

      更新: 似乎链接已断开。试试this link

      【讨论】:

      • livequery 不存在
      • @w35l3y 更新了答案中的链接。
      【解决方案4】:

      我会使用 setInterval 反复检查元素。例如。

      var curLength=0;
      setInterval(function(){
        if ($('.column-header').length!=curLength){
          curLength=$('.column-header').length;
          // do stuff here
        }
      },100);
      

      此代码将每 100 毫秒检查一次任何新的 .colum-header 元素

      【讨论】:

      • 它会很重,但没有对 NodeAdded 事件的原生支持。这是最好的。无论如何,两个实时查询突变事件都肯定使用某种 setInterval 循环。
      • 一点都不重,把Interval设置成变量,之后清空。
      【解决方案5】:

      我认为上面提到的 DOMNodeInserted 方法可能是最性感的选择,但是如果你需要一些可以在 IE8 及更低版本上运行的东西,你可以执行以下操作:

      // wrap this up in en immediately executed function so we don't 
      // junk up our global scope.
      (function() {
         // We're going to use this to store what we already know about.
         var prevFound = null;
      
         setInterval(function() {
            // get all of the nodes you care about.
            var newFound = $('.yourSelector');
      
            // get all of the nodes that weren't here last check
            var diff = newFound.not(prevFound);
      
            // do something with the newly added nodes
            diff.addClass('.justGotHere');
      
            // set the tracking variable to what you've found.
            prevFound = newFound;
         }, 100);
      })();
      

      这只是基本的想法,你可以随意改变它,用它创建一个方法,保留 setInterval 的返回值以便你可以停止它,或者你需要做的任何事情。但它应该可以完成工作。

      【讨论】:

        【解决方案6】:

        您应该查看jQuery Mutation Events。我相信这就是您正在寻找的。​​p>

        【讨论】:

        【解决方案7】:

        如果你想为类column-header的所有元素设置相同的功能 然后你可以使用 jquery live()

        $(".column-header").live("click",function(){});
        

        【讨论】:

        • 是的,但问题是它只会在点击而不是呈现时触发。
        【解决方案8】:

        如何使用投票 - 继续搜索具有“列标题”类的元素,直到找到它然后执行操作。看起来很简单。

        【讨论】:

        • 是的,这可行,但 UI 体验会有延迟。希望避免这种情况。
        • 我认为这取决于页面上的 dom 结构的深度和宽度。我不认为使用一些 jquery 插件会获得更快的性能 - 应该在某些示例上进行测试。
        【解决方案9】:

        不推荐使用直到 2013 年的 MutationEvents。如果其他人在检测 dom 中的新元素时遇到问题,您可以使用 MutationObservers 代替: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

        【讨论】:

        • 不要只是粘贴链接,详细说明你的答案。 (我来这里是因为你的答案有标记)
        【解决方案10】:
        只需更改此函数调用(观察)。 参数 1 - 要监控的元素 参数 2 - 出现时哪个元素将触发函数(参数 3)。 参数 3 - 触发功能 观察('div#application','div.viewContainer',函数(突变){ console.log('突变:',突变) })

        <html>
        <head>
        <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
        <script>
        /* Observing Easy */
        function observing(who, forWhat, callBack){
            var observer = new MutationObserver(function(mutations) {
                
                mutations.forEach(mutation => {
                    console.log(mutation.addedNodes[0])
                    if ( mutation.addedNodes[0].matches(forWhat)){
                        console.log('MATCH!');
                        if(callBack!==undefined){
                            callBack(mutation)
                        }
                    }else{
                        console.log('%cNOT match', 'color: #f00');
                    }
                });
        
            });
        
            observer.observe($(who)[0], {attributes: false, childList: true, characterData: false, subtree:false});
        }
        
        $(document).ready(function(){
        
            
            /* Observing Usage */
            observing('div#application', 'div.viewContainer', function(mutation){
                console.log('Mutation:', mutation)
            })
        
            
        
            /* Adding Elements for Test */ 
            $("#application").append($("<div>Hello World</div>")[0]);
            $("#application").append($("<div class='contentFake'>ContentClassFAKE</div>")[0])
            $("#application").append($("<div class='contentFake'>ContentClass1</div>")[0])
            $("#application").append($("<div class='viewContainer'>ContentClass2</div>")[0])
        
            setTimeout(function(){
                $("#application").append($("<div class='contentFake'>ContentClass3</div>")[0])
            }, 1000)
        
            setTimeout(function(){
                $("#application").append($("<div class='viewContainer'>ContentClass4</div>")[0])
            }, 1000)
        })
        </script>
        </head>
        <body>
            <div id="application"></div>
        </body>
        </html>

        【讨论】:

        • 虽然这段代码 sn-p 可以解决问题,但它没有解释为什么或如何回答这个问题。请include an explanation for your code,因为这确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
        • 现在只是复制和粘贴。或付款,我们解决。 ;)
        【解决方案11】:

        试试这个……

        if($('.column-header')){  
        //do something...
        } 
        

        或者你也可以做这样的事情..它会更通用

        jQuery.exists = function(selector) { return ($(selector).length > 0); }
        
        if ($(selector).exists()) {
          // Do something
        }
        

        【讨论】:

        • 问题仍然存在,何时触发该声明?
        • 是的,就是这样。我不想一次又一次地开火。
        猜你喜欢
        • 2022-01-15
        • 1970-01-01
        • 1970-01-01
        • 2016-11-30
        • 2011-12-22
        • 1970-01-01
        • 1970-01-01
        • 2012-04-07
        • 2018-05-24
        相关资源
        最近更新 更多