简体   繁体   English

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

[英]jquery detecting div of certain class has been added to DOM

I'm using .on() to bind events of divs that get created after the page loads.我正在使用.on()绑定在页面加载后创建的 div 事件。 It works fine for click, mouseenter... but I need to know when a new div of class MyClass has been added.它适用于单击、鼠标输入...但我需要知道何时添加了类 MyClass 的新 div。 I'm looking for this:我在找这个:

$('#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.谢谢。

Previously one could hook into jQuery's domManip method 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 domManip method 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);

Here is my plugin that does exacly that - jquery.initialize这是我的插件,它确实做到了 - jquery.initialize

Useage is the same like you'd use .each function, but with .initialize function on element, difference from .each is 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.但是现在如果新元素匹配 .some-element 选择器会出现在页面上,它将被立即初始化。 The way new item is added is not important, you dont need to care about any callbacks etc.添加新项目的方式并不重要,您不需要关心任何回调等。

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

Plugin is based on MutationObserver插件基于MutationObserver

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) 仅在最初插入时处理元素的能力(无需搜索整个文档设置或忽略“已处理”标志)。

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 的某个类的元素”的方式:您只需在 jQuery html()函数中添加一个钩子,如下所示:

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.如果您使用 jQuery,这会起作用,我就是这样做的。 And it doesn't rely on the browser-specific event DOMNodeInserted , which is not cross-browser compatible.并且它不依赖于浏览器特定的事件DOMNodeInserted ,它不是跨浏览器兼容的。 I also added the same implementation for .prepend()我还为.prepend()添加了相同的实现

Overall, this works like a charm for me, and hopefully for you too.总的来说,这对我来说就像一个魅力,希望对你也是如此。

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.已弃用 此功能已从 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 应用程序可能随时中断。

Mutation Observers are the proposed replacement for mutation events in DOM4. Mutation Observers 是 DOM4 中突变事件的建议替代品。 They are to be included in Firefox 14 and Chrome 18.它们将包含在 Firefox 14 和 Chrome 18 中。

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

MutationObserver provides developers a way to react to changes in a DOM. MutationObserver为开发人员提供了一种对 DOM 中的变化做出反应的方法。 It is designed as a replacement for Mutation Events defined in the DOM3 Events specification.它旨在替代 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();

Two additions to adeneo's answer:对adeeo的回答有两个补充:

(1) we can change the line (1) 我们可以换行

return el.classList.contains('MyClass');

To

if( el.classList ) {
    return el.classList.contains('MyClass');
} else {
    return false;
}

So we won't see the "Uncaught TypeError: Cannot read property 'contains' of undefined" error.所以我们不会看到"Uncaught TypeError: Cannot read property 'contains' of undefined"错误。

(2) add subtree: true in config to find added nodes recursively in all added elements. (2) add subtree: true in config递归地在所有添加的元素中查找添加的节点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM