Miro Miro - 3 months ago 13
Javascript Question

that = $(this) for a setTimeout closure not working as expected

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>




Answer

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.

Comments