问题
I need to ensure that a page stays the way my script describes even after the DOM changes; my script has to handle these changes to the DOM such that my script doesn't only handle on the initial state.
Is there an event that I can use to handle these DOM changes?
回答1:
Taking your question in the strictest sense, something like this:
//--- Narrow the container down AMAP.
$("YOUR SELECTOR").bind ("DOMSubtreeModified", HandleDOM_ChangeWithDelay);
var zGbl_DOM_ChangeTimer = null;
function HandleDOM_ChangeWithDelay (zEvent) {
if (typeof zGbl_DOM_ChangeTimer == "number") {
clearTimeout (zGbl_DOM_ChangeTimer);
zGbl_DOM_ChangeTimer = '';
}
zGbl_DOM_ChangeTimer = setTimeout (HandleDOM_Change, 333);
}
function HandleDOM_Change () {
// YOUR CODE HERE.
}
Note that you want the intermediate delay function because the changes will come in clusters of 10 to 100's of events on a site like Youtube or Google.
You only want to fire on the last event of a cluster -- that's when the change you care about is finished.
IMPORTANT:
It's been a while since I've used the DOMSubtreeModified
approach, because it performs poorly in practice. So, I forgot I had a utility function for it.
Also, as Raynos reminds, mutation events are deprecated. So, Firefox may stop supporting these events in some future release.
One other problem: If your script also changes the nodes in the container you are monitoring, the script can get stuck in an infinite loop/recursion.
Here is the code to avoid the loop (and that global variable):
function HandleDOM_Change () {
// YOUR CODE HERE.
}
//--- Narrow the container down AMAP.
fireOnDomChange ('YOUR JQUERY SELECTOR', HandleDOM_Change, 100);
function fireOnDomChange (selector, actionFunction, delay)
{
$(selector).bind ('DOMSubtreeModified', fireOnDelay);
function fireOnDelay () {
if (typeof this.Timer == "number") {
clearTimeout (this.Timer);
}
this.Timer = setTimeout ( function() { fireActionFunction (); },
delay ? delay : 333
);
}
function fireActionFunction () {
$(selector).unbind ('DOMSubtreeModified', fireOnDelay);
actionFunction ();
$(selector).bind ('DOMSubtreeModified', fireOnDelay);
}
}
回答2:
If you are talking about binding events on DOM elements which may not exist on document.ready, then you can use either .on() or .live() to bind to any element that matches the provided selector, now or in the future.
来源:https://stackoverflow.com/questions/8369097/how-do-i-call-a-function-every-time-the-dom-changes-in-jquery