maan81
maan81

Reputation: 3609

jQuery-Javascript setTimeout-clearTimeout not working

In the snippet below, I would like to call the change() function only if I have stayed continuously over a div for a period of time. If I just skim over the div, I would like to cancel out the call to the function - using clearTimeout.

I see that the clearTimeout is not working. Someone please help me. Thanks in advance.

jQuery portion :

       var obj=$('#aaa');

        var tt;
        obj.find('div').bind({
            mouseenter:function(e){
                var that = $(this)
                tt = setTimeout(function(){
                                    change(e,that)
                                },1000) // <-- time to wait before execution
            },
            mouseleave:function(e){
                clearTimeout(tt);
            }
        });

      function change(e,that){
        console.log(e)
        console.log(that)
      }

HTML portion :

  <div id='aaa'>
    <div><!--class a start-->
        <div>lkaiseulaweg</div>
        <div><!--class b start-->
            <div>ae</div>
            <div>dd</div>
        </div><!--class b end-->
    </div><!--class a end-->

    <div><!--class a start-->
        <i>numbers</i>
        <div><!--class b start-->
            <div>986</div>
            <div>345</div>
            <div>000</div>
            <div>999</div>
        </div><!--class b end-->

    </div><!--class a end-->
  </div>

Upvotes: 1

Views: 2069

Answers (5)

Beno&#238;t
Beno&#238;t

Reputation: 7427

First post: you miss a ";" after var that = $(this)

OK, seems not a problem... (but jsfiddle don't valid it !)

But for jsfiddle, you need to define change function before to use it. http://jsfiddle.net/bouillard/RTSFR/

Upvotes: -1

epascarello
epascarello

Reputation: 207501

Try hover intent which adds delays http://cherne.net/brian/resources/jquery.hoverIntent.html

Upvotes: 1

Rob W
Rob W

Reputation: 348962

You need an extra closure for each div, so that the tt variable is unique. Use .each to bind event listeners, effectively creating a new closure for each tt variable:

obj.find('div').each(function(){
    var tt;
    var that = $(this)
        that.bind({
        mouseenter:function(e){
            clearTimeout(tt); // In case something weird happens
            tt = setTimeout(function(){
                                change(e,that)
                            },1000) // <-- time to wait before execution
        },
        mouseleave:function(e){
            clearTimeout(tt);
        }
    });
});

Upvotes: 2

Tetaxa
Tetaxa

Reputation: 4393

It doesn't work because you set many timeouts and store them in the same variable so the first one you set will be overwritten by the next and so on. You can check this by removing all divs inside #aaa except one and see that it works fine.

What you need to do is clear the old timeout before you set it:

            var that = $(this);
            if(tt) clearTimeout(tt);
            tt = setTimeout(function(){
                                change(e,that)
                            },1000) // <-- time to wait before execution

Upvotes: 0

Jayantha Lal Sirisena
Jayantha Lal Sirisena

Reputation: 21366

you need to have a div with id ='aaa' some where in your HTML

<div id='aaa'><!--class a start-->
        <div>lkaiseulaweg</div>
        <div><!--class b start-->
            <div>ae</div>
            <div>dd</div>
        </div><!--class b end-->
    </div><!--class a end-->

    <div><!--class a start-->
        <i>numbers</i>
        <div><!--class b start-->
            <div>986</div>
            <div>345</div>
            <div>000</div>
            <div>999</div>
        </div><!--class b end-->

    </div><!--class a end-->

see the jsfiddle here http://jsfiddle.net/vR5hJ/

Upvotes: 0

Related Questions