This works fines:
$("body").bind("mouseenter",function(event){ if(event.type == "mouseenter"){ alert("OK") } })
But in this other case the alert never gets executed
$("body").bind("mouseenter",function(event){ setTimeout(function(){ if(event.type == "mouseenter"){ alert("OK") } }) })
That is because when the variable event is called inside a setTimeout (or setInterval) it returns "mouseover" instead of "mouseenter" as it should.
So just save the actual event type and you will be just fine.
$("body").bind("mouseenter",function(event){ var eventType = event.type setTimeout(function(){ if(eventType == "mouseenter"){ alert("Mouse inside... i can feel it inside of me!") } }) })
This is not a flaw in jQuery, but in javascript closures.
ReplyDeleteMmm... the point of jQuery is to fix all the javascript mess, so i think is a jQuery bug too. It would be easy to fix it by return a copy of the variable 'event' rather than a real reference.
ReplyDeleteThere is no flaw in jQuery and there is no flaw in javascript closures.
ReplyDeleteThe code you show there will do what you have coded it to do, no more, no less. The result is not what you think it should be but that is only because of your misunderstood of javascript closures and variables scope.
Just read:
http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/
if you want to understand how it works.
Even your solution is a bad solution because still has a problem in the concept of closures and variables scope. Look at this minor change to your last code that breaks your solution though you probably think it should work.
$("body").bind("mouseenter",function(event){
var eventType = event.type;
setTimeout(function(){
if(eventType == "mouseenter"){
alert("Mouse inside... i can feel it inside of me!")
} else {
alert("I can't feel anything because eventType is: " + eventType);
}
});
eventType = "im not the mouse event type any more";
});
I don't think it should work; setTimeout is to do something after.
ReplyDeleteBut it hasn't anything to do with setTimeout but with closures and variable scope. The problem is in how you are using the closure inside setTimeout not in setTimeout itself. I suppose anyone understand that setTimeout was only an example to try to explain a flaw in jQuery. But that flaw does not exist at all. If we change the code to something correct, then it works.
ReplyDeletevar enter = function(eventType) {
if(eventType == "mouseenter"){
alert("Mouse inside... i can feel it inside of me!")
} else {
alert("I can't feel anything because eventType is: " + eventType);
}
}
window.onload = function() {
$("body").bind("mouseenter",function(event){
var eventType = event.type;
setTimeout(enter(eventType));
eventType = "im not the mouse event type any more";
});
}
There is nothing wrong with jQuery nor with javascript closures. Just use javascript closures correctly. I suggest you to read that article I'm linking or any other article explaining that topic.