chrome ext: limiting DOMNodeInserted
-
13-06-2021 - |
Pergunta
I'm developing a chrome plugin that inject a class to every element in the page. But in pages such as facebook or twitter there is content loaded dynamically, so I use this code to check when this conent is loaded:
document.addEventListener('DOMNodeInserted', function() {
console.log('fatto');
}, true);
the problem is that this way, the script is fired every single time a node is inserted. Therefore I'd like to add some kind of limitation. something like: When a node is inserted fire the script and then wait 2 sec.
I'm trying something like this but no success:
var check = 1;
document.addEventListener('DOMNodeInserted', function() {
if(check == 1) {
check = 0;
setInterval( function() {
//do stuff
check = 1;
}, 1000);
console.log('fatto');
}
}, true);
thanks
Solução
I've seen this technique referred to as debouncing. Here's an example:
(function() {
var timer;
var doStuff = function() {
timer = null;
alert("Doing stuff");
};
document.addEventListener('DOMNodeInserted', function() {
if (timer) {
window.clearTimeout(timer);
}
timer = window.setTimeout(doStuff, 2000);
}, false);
})();
You can generalize this:
function addDebouncedEventListener(obj, eventType, listener, delay) {
var timer;
obj.addEventListener(eventType, function(evt) {
if (timer) {
window.clearTimeout(timer);
}
timer = window.setTimeout(function() {
timer = null;
listener.call(obj, evt);
}, delay);
}, false);
}
addDebouncedEventListener(document, 'DOMNodeInserted', function(evt) {
alert(evt.target.nodeName + " inserted");
}, 2000);
Outras dicas
I'd say:
var timeout;
document.addEventListener('DOMNodeInserted', function() {
startNewTimeout();
}, true);
function startNewTimeout() {
//only if there is no active timeout already
if(timeout === undefined) {
timeout = setTimeout( function() {
timeout = undefined;
//do stuff
}, 1000);
}
}
This script won't delay the execution of //do stuff
indefinitely. It will make sure that //do stuff
is executed max. 1sec after first DOMNodeInserted
event.