DOM Mutation событие в JQuery или ванили Javascript
Есть ли какие-либо события мутации DOM в JQuery или в ванильном Javascript, которые используют перекрестный браузер?
Чтобы уточнить, скажем, у меня есть сценарий на моей странице, который вставляет div в тело. У меня нет доступа к скрипту, и я не знаю, когда был добавлен div. Мне было интересно, есть ли событие мутации DOM, для которого я могу добавить слушателя, чтобы знать, когда был вставлен элемент. Я знаю, что я могу использовать таймер для периодической проверки вставки, но мне не очень нравятся накладные расходы, которые это наложит.
- Как избежать жестко закодированных асинхронных функций в Javascript / jQuery?
- Как сохранить JQuery UI упорядоченные позиции таблицы в базе данных MySQL?
- Кнопки jQuery UI Dialog из переменных
- Модальная проблема в карте Google
- Какова цель этого? (Function ($) {// здесь код функции}) (jQuery);
- Javascript: setTimeout () - нужна помощь
- Обработка событий мыши при перекрытии слоев SVG
- Javascript числа concatenate вместо добавления, но typeof - число не строка
- Не удалось распечатать iframe в IE с помощью JavaScript, вместо этого печатает родительскую страницу
- Наложение изображений JQuery?
- Отключить диапазоны временных интервалов в плагине jQuery fullcalendar
- Как преобразовать строку в объект XML в JavaScript?
- Bootprap datepicker отключает прошлые даты без текущей даты
Это, конечно, взлом, но почему бы не исправить базовые методы DOM, используемые для вставки узлов? Есть несколько способов сделать это:
A. Вы знаете, к какому конкретному элементу присоединятся:
var c = document.getElementById('#container'); c.__appendChild = c.appendChild; c.appendChild = function(){ alert('new item added'); c.__appendChild.apply(c, arguments); }
Скрипт для A
B. Вы знаете, к какому типу элемента добавятся:
HTMLDivElement.prototype.__appendChild = HTMLDivElement.prototype.appendChild; HTMLDivElement.prototype.appendChild = function(){ alert('new item added'); HTMLDivElement.prototype.__appendChild(this,arguments); }
Скрипт для B
(Обратите внимание, что решение B не поддерживается IE < 8
или любым другим браузером, который не поддерживает прототипы DOM.)
Этот же метод можно так же легко использовать во всех основных функциях DOM-мутации, таких как insertBefore
, replaceChild
или removeChild
.
Это общая идея, эти демо могут быть адаптированы для практически любого другого случая использования – скажем, вы хотите использовать широкую сеть и улавливать все дополнения независимо от типа И убедиться, что он работает во всех браузерах, кроме IE < 8
? (См. Пример C ниже)
ОБНОВИТЬ
C. Рекурсивно пройдите DOM, замените функцию на каждом элементе, чтобы вызвать обратный вызов, а затем примените тот же патч к любому добавляемому ребенку.
var DOMwatcher = function(root, callback){ var __appendChild = document.body.appendChild; var patch = function(node){ if(typeof node.appendChild !== 'undefined' && node.nodeName !== '#text'){ node.appendChild = function(incomingNode){ callback(node, incomingNode); patch(incomingNode); walk(incomingNode); __appendChild.call(node, incomingNode); }; } walk(node); }; var walk = function(node){ var i = node.childNodes.length; while(i--){ patch(node.childNodes[i]); } }; patch(root); }; DOMwatcher(document.body, function(targetElement, newElement){ alert('append detected'); }); $('#container ul li').first().append('<div><p>hi</p></div>'); $('#container ul li div p').append('<a href="#foo">bar</a>');
Скрипт для C
ОБНОВЛЕНИЕ 2
Как отметил Tim Down , вышеупомянутое решение также не будет работать в IE < 8
потому что appendChild
не является Function
и не поддерживает call
или apply
. Я полагаю, вы всегда можете вернуться к неуклюжему, но надежному методу setInterval
если typeof document.body.appendChild !== 'function'
.
Есть некоторые устаревшие события мутации DOM, такие как DOMNodeInserted
и DOMNodeInsertedIntoDocument
которые все еще работают для меня в Chrome 14 и IE9.
См. Пример на http://jsfiddle.net/Kai/WTJq6/
Посмотрите их на черновик W3C по адресу http://www.w3.org/TR/DOM-Level-3-Events/
JCADE (JQuery Create and Destroy Events) сделает это. Он использует поведение для событий мутации IE и DOM для других браузеров. Он не использует события синхронизации и не переносит методы JQuery, такие как livequery.
https://github.com/snesin/jcade
$ (Document) .create ("a", function (event) { Alert (event.target); });
Я не верю, что не без плагина, но я не удивлюсь, если я ошибаюсь.
Мои исследования нашли несколько вариантов.
Вот один из них: http://plugins.jquery.com/project/mutation-events
Вот еще один: https://www.adaptavist.com/display/jQuery/Mutation+Events
Если вы ищете альтернативу этому методу, вот http://www.jqui.net/jquery-projects/jquery-mutate-official/, который также позволяет вам добавлять события самостоятельно и следить за практически любыми изменениями , Класс переименование, изменение высоты, ширина изменение.
Для этого можно использовать плагин livequery . В версии 1.xa таймер использовался для периодической проверки любых изменений. Однако более новая ветка версии 2.x работает без периодического таймаута (непроверенная).