Если вы посмотрите на:
http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-MutationEvent
В нем говорится, что в отношении DOMSubtreeModified «оно может быть запущено после одной модификации документа или, по усмотрению реализации, после нескольких изменений».
Поэтому, если вы используете другое MutationEvent, скажем, DOMNodeInserted, вы можете получить более детерминированный запуск событий (вам просто нужно добавить элемент к узлу в этом конкретном случае).
См. Ниже:
$('body').prepend( $('<div id="cow">Hello</div>') );
$('#cow').bind("DOMNodeInserted",function(){ alert('hi'); } );
$('#cow').prepend( $("<div></div>") );
Это было проверено в Chrome, кстати.
Надеюсь, это поможет ...
UPDATE:
Кроме того, вы можете добавить более одного типа события в один вызов функции. Например, добавив четыре обработчика событий для DOMNodeInserted, DOMNodeRemoved, DOMAttrModified, DOMCharacterDataModified, затем все обработчики вызывают один обработчик.
ОБНОВЛЕНИЕ: я написал небольшой скрипт, который делает то, что я только что написал в предыдущем обновлении:
$('body').prepend( $('<div id="cow">Hello</div>') );
/**
* This function registers event handlers which invoke the mutateHandler
* handler when any of the MutationEvents are fired on a node: DOMNodeInserted,
* DOMNodeRemoved, DOMAttrModified, DOMCharacterDataModified.
*
*/
var onMutate = function( mutateHandler ){
var that = this;
$(this).bind( "DOMNodeInserted", function( event ){
mutateHandler.call( that, event );
});
$(this).bind( "DOMNodeRemoved", function( event ){
mutateHandler.call( that, event );
});
$(this).bind( "DOMAttrModified", function( event ){
mutateHandler.call( that, event );
});
$(this).bind( "DOMCharacterDataModified", function( event ){
mutateHandler.call( that, event );
});
};
onMutate.call( $('#cow')[0], function(){
alert( $(this).attr('id') );
});
$('#cow').prepend( $("<div></div>") );
$('#cow').addClass( 'my_class' );