DOMNodeInserted equivalent in IE?
Other than using a timer to count the number of elements over time and looking for changes, I can't think of a better way to simulate this event.
Is there some sort of proprietary IE version of DOMNodeInserted? Thanks.
Solution 1:
No, there isn't. The nearest is the propertychange
event, which fires in response to a change in an attribute or CSS property of an element. It fires in response to changing the innerHTML
property of an element directly but not when the contents of the elements are altered by some other means (e.g. by using DOM methods such as appendChild()
or by altering the innerHTML
of a child element).
UPDATE 6 February 2014
As pointed out in the comments, there is a workaround. It's based on an elaborate hack and I'd recommend using mutation observers instead wherever possible. See @naugtur's answer for details. @naugtur's answer has been deleted but the solution can be found at https://github.com/naugtur/insertionQuery
Solution 2:
You can over-ride all the DOM-manipulation methods - appendChild, insertBefore, replaceChild, insertAdjacentHTML, etc - and monitor innerHTML with onpropertychange.
You might be able to come up with a solution that satisfies your requirements.
BTW, it seems that DOMNodeInserted, etc will be deprecated by browsers in the future. See http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents
Solution 3:
onreadystatechange will work in IE. A DHTML behavior must be attached to the element via htc, but the htc file does not have to exist:
if (!!document.addEventListener)
{
$(domnode).get(0).addEventListener("DOMNodeInserted", fixtext, false);
}
else
{
$(domnode).get(0).addBehavior("foo.htc");
$(domnode).get(0).attachEvent("onreadystatechange", fixtext);
}
onreadystatechange event reference
Solution 4:
A dirty workaround is to intercept the prototype methods of type Element as follows:
window.attachEvent('onload', function() {
invokeNodeInserted(document);
(function(replace) {
Element.prototype.appendChild = function(newElement, element) {
invokeNodeInserted(newElement);
return replace.apply(this, [newElement, element]);
};
})(Element.prototype.appendChild);
(function(replace) {
Element.prototype.insertBefore = function(newElement, element) {
invokeNodeInserted(newElement);
return replace.apply(this, [newElement, element]);
};
})(Element.prototype.insertBefore);
(function(replace) {
Element.prototype.replaceChild = function(newElement, element) {
invokeNodeInserted(newElement);
return replace.apply(this, [newElement, element]);
};
})(Element.prototype.replaceChild);
});