Reputation: 8650
I want to use setTimeout
in a button mouseout
and refer to $(this)
(the button) from the setTimeout
. I'm using that = $(this)
, then use that
in the setTimeout
but it doesn't work quite like expected.
If you go hover over each link slowly it works (1,2,3). But if you do it in fast, under 100ms, I get all 3s (3,3,3).
My guess is the closure is not working and the that
var gets overwritten but i just can't figure out why.
Could you explain what's happening?
$("nav a")
.mouseenter(function() {
//
})
.mouseout(function(event) {
that = $(this);
setTimeout(function(){
console.log( that.data('uid') );
}, 100);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
<ul>
<li><a href="" data-uid="1">One</a></li>
<li><a href="" data-uid="2">Two</a></li>
<li><a href="" data-uid="3">Three</a></li>
</ul>
</nav>
Upvotes: 0
Views: 49
Reputation: 410
Your variable is being hoisted to a global without the var keyword. You should consider using strict mode to avoid this in the future.
Edit: As @Dekel pointed out in the comments, strict mode won't actually fix your problem, but would error out when you attempt to declare a variable without the var keyword. It's just a good practice to help avoid this type of unexpected behavior.
'use strict';
$("nav a")
.mouseenter(function() {
//
})
.mouseout(function(event) {
var that = $(this);
setTimeout(function(){
console.log( that.data('uid') );
}, 100);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
<ul>
<li><a href="" data-uid="1">One</a></li>
<li><a href="" data-uid="2">Two</a></li>
<li><a href="" data-uid="3">Three</a></li>
</ul>
</nav>
Upvotes: 2
Reputation: 62616
You should set that
to be a local variable (using var
):
$("nav a")
.mouseenter(function() {
//
})
.mouseout(function(event) {
var that = $(this);
setTimeout(function(){
console.log( that.data('uid') );
}, 100);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
<ul>
<li><a href="" data-uid="1">One</a></li>
<li><a href="" data-uid="2">Two</a></li>
<li><a href="" data-uid="3">Three</a></li>
</ul>
</nav>
In you current code, that
is a global variable, and with each mouseout
you override it to be the new element.
Upvotes: 3