jquery 检测某个类的 div 已添加到 DOM

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10415400/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 09:18:35  来源:igfitidea点击:

jquery detecting div of certain class has been added to DOM

jquery

提问by frenchie

I'm using .on()to bind events of divs that get created after the page loads. It works fine for click, mouseenter... but I need to know when a new div of class MyClass has been added. I'm looking for this:

我正在使用.on()绑定在页面加载后创建的 div 事件。它适用于单击、鼠标输入...但我需要知道何时添加了 MyClass 类的新 div。我在找这个:

$('#MyContainer').on({

  wascreated: function () { DoSomething($(this)); }

}, '.MyClass');

How do I do this? I've managed to write my entire app without a plugin and I want to keep it that way.

我该怎么做呢?我已经设法在没有插件的情况下编写了我的整个应用程序,我想保持这种状态。

Thanks.

谢谢。

采纳答案by frenchie

3 years of experience later, this is how I listen to "element of a certain class added to the DOM": you simply add a hook into the jQuery html()function, like this:

3年后的经验,这就是我听“添加到DOM的某个类的元素”的方式:您只需在jQueryhtml()函数中添加一个钩子,如下所示:

function Start() {

   var OldHtml = window.jQuery.fn.html;

   window.jQuery.fn.html = function () {

     var EnhancedHtml = OldHtml.apply(this, arguments);

     if (arguments.length && EnhancedHtml.find('.MyClass').length) {

         var TheElementAdded = EnhancedHtml.find('.MyClass'); //there it is
     }

     return EnhancedHtml;
   }
}

$(Start);

This works if you're using jQuery, which I do. And it doesn't rely on the browser-specific event DOMNodeInserted, which is not cross-browser compatible. I also added the same implementation for .prepend()

如果您使用的是 jQuery,这会起作用,我就是这样做的。并且它不依赖于浏览器特定的 event DOMNodeInserted,它不是跨浏览器兼容的。我还为.prepend()

Overall, this works like a charm for me, and hopefully for you too.

总的来说,这对我来说就像一个魅力,希望对你也是如此。

回答by adeneo

Previously one could hook into jQuery's domManipmethod to catch all jQuery dom manipulations and see what elements where inserted etc. but the jQuery team shut that down in jQuery 3.0+ as it's generally not a good solution to hook into jQuery methods that way, and they've made it so the internal domManipmethod no longer is available outside the core jQuery code.

以前可以挂钩 jQuery 的domManip方法来捕获所有 jQuery dom 操作并查看插入的元素等。但是 jQuery 团队在 jQuery 3.0+ 中关闭了它,因为以这种方式挂钩 jQuery 方法通常不是一个好的解决方案,而且他们'已经做到了,因此内部domManip方法在核心 jQuery 代码之外不再可用。

Mutation Events have also been deprecated, as before one could do something like

突变事件也已被弃用,因为以前可以做类似的事情

$(document).on('DOMNodeInserted', function(e) {
    if ( $(e.target).hasClass('MyClass') ) {
       //element with .MyClass was inserted.
    }
});

this should be avoided, and today Mutation Observers should be used instead, which would work like this

应该避免这种情况,今天应该使用 Mutation Observers 来代替,它会像这样工作

var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        console.log(mutation)
        if (mutation.addedNodes && mutation.addedNodes.length > 0) {
            // element added to DOM
            var hasClass = [].some.call(mutation.addedNodes, function(el) {
                return el.classList.contains('MyClass')
            });
            if (hasClass) {
                // element has class `MyClass`
                console.log('element ".MyClass" added');
            }
        }
    });
});

var config = {
    attributes: true,
    childList: true,
    characterData: true
};

observer.observe(document.body, config);

回答by pie6k

Here is my plugin that does exacly that - jquery.initialize

这是我的插件,它确实做到了 - jquery.initialize

Useage is the same like you'd use .eachfunction, but with .initializefunction on element, difference from .eachis it will also initialize elements added in future without any additional code - no matter if you add it with AJAX or anything else.

用法与您使用.each函数一样,但.initialize对于元素上的函数,不同之处.each在于它还会初始化将来添加的元素,而无需任何额外代码 - 无论您是使用 AJAX 还是其他任何方式添加它。

Initialize have exacly the same syntax as with .each function

Initialize 具有与 .each 函数完全相同的语法

$(".some-element").initialize( function(){
    $(this).css("color", "blue");
});

But now if new element matching .some-element selector will appear on page, it will be instanty initialized. The way new item is added is not important, you dont need to care about any callbacks etc.

但是现在如果新元素匹配 .some-element 选择器会出现在页面上,它将被立即初始化。添加新项目的方式并不重要,您不需要关心任何回调等。

$("<div/>").addClass('some-element').appendTo("body"); //new element will have blue color!

Plugin is based on MutationObserver

插件基于 MutationObserver

回答by jtc

After reviewing this and several other posts I tried to distill what I thought was the best of each into something simple that allowed me to detect when a class of elements is inserted and then act on those elements.

在查看了这篇文章和其他几篇文章后,我试图将我认为最好的内容提炼成一些简单的东西,使我能够检测何时插入了一类元素,然后对这些元素采取行动

function onElementInserted(containerSelector, elementSelector, callback) {

    var onMutationsObserved = function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.addedNodes.length) {
                var elements = $(mutation.addedNodes).find(elementSelector);
                for (var i = 0, len = elements.length; i < len; i++) {
                    callback(elements[i]);
                }
            }
        });
    };

    var target = $(containerSelector)[0];
    var config = { childList: true, subtree: true };
    var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
    var observer = new MutationObserver(onMutationsObserved);    
    observer.observe(target, config);

}

onElementInserted('body', '.myTargetElement', function(element) {
    console.log(element);
});

Importantly for me, this allows a) the target element to exist at any depth within "addedNodes" and b) the ability to deal with the element only when initially inserted (no need to search the entire document setting or ignoring "already-processed" flags).

对我来说重要的是,这允许 a) 目标元素存在于“已添加节点”中的任何深度和 b) 仅在最初插入时处理元素的能力(无需搜索整个文档设置或忽略“已处理”标志)。

回答by RGB

you could use mutation events

你可以使用突变事件

http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-eventgroupings-mutationevents

http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-eventgroupings-mutationevents

EDIT

编辑

from MDN: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_events

来自 MDN:https: //developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_events

Deprecated This feature has been removed from the Web. Though some browsers may still support it, it is in the process of being dropped. Do not use it in old or new projects. Pages or Web apps using it may break at any time.

已弃用 此功能已从 Web 中删除。虽然一些浏览器可能仍然支持它,但它正在被删除。不要在旧项目或新项目中使用它。使用它的页面或 Web 应用程序可能随时中断。

Mutation Observers are the proposed replacement for mutation events in DOM4. They are to be included in Firefox 14 and Chrome 18.

Mutation Observers 是 DOM4 中突变事件的建议替代品。它们将包含在 Firefox 14 和 Chrome 18 中。

https://developer.mozilla.org/en/docs/Web/API/MutationObserver

https://developer.mozilla.org/en/docs/Web/API/MutationObserver

MutationObserverprovides developers a way to react to changes in a DOM. It is designed as a replacement for Mutation Events defined in the DOM3 Events specification.

MutationObserver为开发人员提供了一种对 DOM 中的更改做出反应的方法。它旨在替代 DOM3 事件规范中定义的突变事件。

Example usage

示例用法

The following example was taken from http://hacks.mozilla.org/2012/05/dom-mutationobserver-reacting-to-dom-changes-without-killing-browser-performance/.

以下示例取自http://hacks.mozilla.org/2012/05/dom-mutationobserver-reacting-to-dom-changes-without-killing-browser-performance/

// select the target node
var target = document.querySelector('#some-id');

// create an observer instance
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    console.log(mutation.type);
  });    
});

// configuration of the observer:
var config = { attributes: true, childList: true, characterData: true };

// pass in the target node, as well as the observer options
observer.observe(target, config);

// later, you can stop observing
observer.disconnect();