Reputation: 38
I have a div that listens for a "mouseenter" event, and fires a libraryFunction (that I cannot edit) after 5 seconds (implemented with setTimeout).
However, if the user clicks the div within those 5 seconds, the setTimeout should be cancelled, and the function should not run (implemented with clearTimeout). The click will also remove an element that the libraryFunction relies on.
Currently I have the code below:
var timeoutVar;
$("#mydiv").on("mouseenter", function(event) {
timeoutVar = setTimeout(function() {
runLibraryFunction(object);
}, 5000);
});
$("#mydiv").on("click", function(event) {
clearTimeout(timeoutVar);
removeObject(object);
});
This works for the most part, however, there is an edge case when the div is clicked just after 5 seconds, and while runLibraryFunction() in executing. Because the "click" event removes the object that the runLibraryFunction needs, and this happens while runLibraryFunction is running, runLibraryFunction then throws an error.
Is there a way to stop the runLibraryFunction() call after it has been fired?
Upvotes: 2
Views: 1426
Reputation: 28196
You could add a property to the object when starting the library function thereby protecting it from being removed like:
var timeoutVar;
$("#mydiv").on("mouseenter", function(event) {
timeoutVar = setTimeout(function() {
object.keepmealive=1;
runLibraryFunction(object);
if (object) delete object.keepmealive;
}, 5000);
});
$("#mydiv").on("click", function(event) {
clearTimeout(timeoutVar);
if (!object.keepmealive) removeObject(object);
});
This approach assumes that your library function will somehow take care of deleting or doing whatever needs to be done to object
, so once it has started running there is no necessity for the delete function any more. It will stay in place and will be ready to act on another possible future event.
Upvotes: 1
Reputation: 7404
I would unbind the event during processing, and rebind it afterwards using s recursive function like so:
var timeoutVar;
var init = function(){
$("#mydiv").on("mouseenter", function(event) {
timeoutVar = setTimeout(function() {
$("#mydiv").off()
runLibraryFunction(object, function(){
init()
});
}, 5000);
});
};
$("#mydiv").on("click", function(event) {
clearTimeout(timeoutVar);
removeObject(object);
});
init();
Upvotes: 0
Reputation: 36703
Tricky but will work
timeoutVar = setTimeout(function() {
setTimeout(function(){
if(object)
runLibraryFunction(object);
},1000);
}, 5000);
Keep rest same.
or use immediately invoked functions
timeoutVar = setTimeout(function() {
(function(object){
runLibraryFunction(object);
})(object);
}, 5000);
Now object will always be accessible
Upvotes: 2