javascript - Detect changes in the DOM -
i want execute function when div or input added html. possible?
for example, text input added, function should called.
2015 update, new mutationobserver
supported modern browsers:
chrome 18+, firefox 14+, ie 11+, safari 6+
if need support older ones, may try fall other approaches ones mentioned in 5 (!) year old answer below. there dragons. enjoy :)
someone else changing document? because if have full control on changes need create own domchanged
api - function or custom event - , trigger/call everywhere modify things.
the dom level-2 has mutation event types, older version of ie don't support it. note mutation events deprecated in dom3 events spec , have performance penalty.
you can try emulate mutation event onpropertychange
in ie (and fall brute-force approach if non of them available).
for full domchange interval over-kill. imagine need store current state of whole document, , examine every element's every property same.
maybe if you're interested in elements , order (as mentioned in question), getelementsbytagname("*")
can work. fire automatically if add element, remove element, replace elements or change structure of document.
i wrote proof of concept:
(function (window) { var last = +new date(); var delay = 100; // default delay // manage event queue var stack = []; function callback() { var = +new date(); if (now - last > delay) { (var = 0; < stack.length; i++) { stack[i](); } last = now; } } // public interface var ondomchange = function (fn, newdelay) { if (newdelay) delay = newdelay; stack.push(fn); }; // naive approach compatibility function naive() { var last = document.getelementsbytagname('*'); var lastlen = last.length; var timer = settimeout(function check() { // current state of document var current = document.getelementsbytagname('*'); var len = current.length; // if length different // it's obvious if (len != lastlen) { // make sure loop finishes last = []; } // go check every element in order (var = 0; < len; i++) { if (current[i] !== last[i]) { callback(); last = current; lastlen = len; break; } } // over, , over, , on again settimeout(check, delay); }, delay); } // // check mutation events support // var support = {}; var el = document.documentelement; var remain = 3; // callback tests function decide() { if (support.domnodeinserted) { window.addeventlistener("domcontentloaded", function () { if (support.domsubtreemodified) { // ff 3+, chrome el.addeventlistener('domsubtreemodified', callback, false); } else { // ff 2, safari, opera 9.6+ el.addeventlistener('domnodeinserted', callback, false); el.addeventlistener('domnoderemoved', callback, false); } }, false); } else if (document.onpropertychange) { // ie 5.5+ document.onpropertychange = callback; } else { // fallback naive(); } } // checks particular event function test(event) { el.addeventlistener(event, function fn() { support[event] = true; el.removeeventlistener(event, fn, false); if (--remain === 0) decide(); }, false); } // attach test events if (window.addeventlistener) { test('domsubtreemodified'); test('domnodeinserted'); test('domnoderemoved'); } else { decide(); } // dummy test var dummy = document.createelement("div"); el.appendchild(dummy); el.removechild(dummy); // expose window.ondomchange = ondomchange; })(window);
usage:
ondomchange(function(){ alert("the times a-changin'"); });
this works on ie 5.5+, ff 2+, chrome, safari 3+ , opera 9.6+
Comments
Post a Comment