Ответ 1
Это, конечно, взлом, но почему бы не исправить базовые методы DOM, используемые для вставки узлов? Есть несколько способов сделать это:
А. Вы знаете, к какому элементу конкретный добавляется:
var c = document.getElementById('#container');
c.__appendChild = c.appendChild;
c.appendChild = function(){
alert('new item added');
c.__appendChild.apply(c, arguments);
}
В. Вы знаете, что элемент типа будет добавлен к:
HTMLDivElement.prototype.__appendChild = HTMLDivElement.prototype.appendChild;
HTMLDivElement.prototype.appendChild = function(){
alert('new item added');
HTMLDivElement.prototype.__appendChild(this,arguments);
}
(Обратите внимание, что решение B не поддерживается IE < 8
или любым другим браузером, который не поддерживает прототипы DOM.)
Этот же метод можно так же легко использовать для всех базовых функций мутации DOM, таких как insertBefore
, replaceChild
или removeChild
.
Что общая идея, эти демонстрации могут быть адаптированы практически для любого другого варианта использования - скажем, вы хотите использовать широкую сеть и улавливать все дополнения, независимо от типа И, чтобы убедиться, что он работает все браузеры все, кроме IE < 8
? (см. пример C ниже)
UPDATE
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>');
ОБНОВЛЕНИЕ 2
Как отметил Tim Down, вышеупомянутое решение также не будет работать в IE < 8
, потому что appendChild
не является Function
и не поддерживает call
или apply
. Полагаю, вы всегда можете вернуться к неуклюжему, но надежному методу setInterval
, если typeof document.body.appendChild !== 'function'
.