Я использую .on()
для привязки событий div, которые создаются после загрузки страницы. Он отлично работает для щелчка, мыши ... но мне нужно знать, когда был добавлен новый div класса MyClass. Я ищу это:
$('#MyContainer').on({
wascreated: function () { DoSomething($(this)); }
}, '.MyClass');
Как мне это сделать? Мне удалось написать все свое приложение без плагина, и я хочу, чтобы оно оставалось таким.
Благодарю.
Ответы:
Раньше можно было подключиться к
domManip
методу jQuery, чтобы поймать все манипуляции с jQuery dom и посмотреть, какие элементы были вставлены и т. Д., Но команда jQuery отключила это в jQuery 3.0+, поскольку обычно это не лучшее решение для подключения к методам jQuery таким образом, и они ' Мы сделали так, чтобы внутреннийdomManip
метод больше не был доступен за пределами основного кода jQuery.События мутации также устарели, поскольку раньше можно было делать что-то вроде
$(document).on('DOMNodeInserted', function(e) { if ( $(e.target).hasClass('MyClass') ) { //element with .MyClass was inserted. } });
этого следует избегать, и сегодня вместо этого следует использовать 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);
источник
Вот мой плагин, который именно это делает - jquery.initialize
Использование такое же, как если бы вы использовали
.each
функцию, но с.initialize
функцией на элементе, отличие от того,.each
что он также инициализирует элементы, добавленные в будущем, без какого-либо дополнительного кода - независимо от того, добавляете ли вы его с помощью AJAX или чего-то еще.Инициализация имеет точно такой же синтаксис, как и с функцией .each
$(".some-element").initialize( function(){ $(this).css("color", "blue"); });
Но теперь, если на странице появится новый элемент, соответствующий селектору .some-element, он будет мгновенно инициализирован. Способ добавления нового элемента не важен, вам не нужно заботиться о каких-либо обратных вызовах и т. Д.
$("<div/>").addClass('some-element').appendTo("body"); //new element will have blue color!
Плагин основан на
MutationObserver
источник
.initialize
функциюcallback
только для элементов, которые добавляются динамически (например, через Ajax), и пропустить обратный вызов для элементов, уже присутствующих при первоначальной загрузке страницы? Я пытаюсь добавить параметр дляoptions
этого, но пока у меня это не работает.$('.myClass').addClass('ignore-initialize'); $.initialize('.myClass:not(.ignore-initialize)', callback);
После просмотра этого и нескольких других сообщений я попытался свести то, что я считал лучшим из каждого, к чему-то простому, что позволило мне определить, когда класс элементов вставлен, и затем действовать с этими элементами .
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); });
Для меня важно то, что это позволяет а) целевому элементу существовать на любой глубине в «добавленных узлах» и б) иметь дело с элементом только при его первоначальной вставке (нет необходимости искать во всем параметре документа или игнорировать «уже обработанный» флаги).
источник
if(mutation.addedNodes.length)
потому чтоaddedNodes
иremovedNodes
массивы всегда вmutation
типаchildList
(проверено на IE11, Chrome53, FF49). Тем не менее +1, потому что ваш единственный ответ,addedNodes
который рассматривается (callback
вызывается только при добавлении узла); не только в этой теме, но и во многих других. Все остальные просто вызываютcallback
для всех мутаций, даже если узел удаляется.Спустя 3 года опыта я слушаю «элемент определенного класса, добавленный в DOM» : вы просто добавляете крючок в
html()
функцию jQuery , например: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);
Это работает, если вы используете jQuery, что я и делаю. И он не полагается на событие
DOMNodeInserted
, зависящее от браузера , которое не является кроссбраузерным. Я также добавил ту же реализацию для.prepend()
В целом, это работает как амулет для меня, и, надеюсь, для вас тоже.
источник
html
помощник jQuery для изменения DOM, а не просто «с помощью jQuery» в целом. Элементы, добавленные с использованием, скажем,jQuery.append
не вызовут это событие.insertionQ('#intercom-container').every(function(/element){ element.style.display = 'none'; });
вы можете использовать события мутации
http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-eventgroupings-mutationevents
РЕДАКТИРОВАТЬ
из MDN: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_events
Устарело. Эта функция удалена из Интернета. Хотя некоторые браузеры могут по-прежнему поддерживать его, в настоящее время он удаляется. Не используйте его в старых или новых проектах. Страницы или веб-приложения, использующие его, могут сломаться в любой момент.
Наблюдатели за мутациями - это предлагаемая замена событий мутации в DOM4. Они должны быть включены в Firefox 14 и Chrome 18.
https://developer.mozilla.org/en/docs/Web/API/MutationObserver
MutationObserver
предоставляет разработчикам способ реагировать на изменения в DOM. Он разработан как замена для событий мутации, определенных в спецификации событий DOM3.Пример использования
Следующий пример был взят из 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();
источник
Два дополнения к ответу adeneo:
(1) мы можем изменить строку
return el.classList.contains('MyClass');
Чтобы
if( el.classList ) { return el.classList.contains('MyClass'); } else { return false; }
Так что
"Uncaught TypeError: Cannot read property 'contains' of undefined"
ошибки мы не увидим .(2) добавить
subtree: true
вconfig
найти добавленные узлы рекурсивно во всех добавленных элементов.источник