3

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div  onmouseover="animatedStickers($(this), 17, 5, 4, 2, 3)" style="float: left; background-image: url('http://googledrive.com/host/0B-UH4_eX_YisdlJ4cU9qZ1lwM3c/Tuzki1.png'); background-size: 380px 304px; cursor: pointer; height: 64px; width: 64px; background-position: -6px -6px;  color: transparent">Tuzki</div>

<div  onmouseover="animatedStickers($(this), 16, 4, 4, 4, 3)" style="float: left; background-image: url('http://googledrive.com/host/0B-UH4_eX_YisdlJ4cU9qZ1lwM3c/Tuzki2.png'); background-size: 304px 304px; cursor: pointer; height: 64px; width: 64px; background-position: -6px -6px;  color: transparent">Tuzki</div>

<div onmouseover="animatedStickers($(this), 22, 5, 5, 2, 3)" style="float: left; background-image: url('http://googledrive.com/host/0B-UH4_eX_YisdlJ4cU9qZ1lwM3c/Tuzki3.png'); background-size: 380px 380px; cursor: pointer; height: 64px; width: 64px; background-position: -6px -6px;  color: transparent">Tuzki</div>

<script>
  var loop = 1;
        var stickerInterval = function (element, x, y, last) {            
            var pos = $(element).css('backgroundPosition').split(' ');
            var xPos = parseInt(pos[0].split('px')[0]) - 6 - 6 - 64;
            var yPos = parseInt(pos[1].split('px')[0]);
            var maxX = ((-6 - 6 - 64) * (x - 1)) - 6;
            var maxY = ((-6 - 6 - 64) * last) - 6;
            
            if (loop == y && xPos == maxY) {
                // end 1 turn
                loop = 1;
                xPos = -6;
                yPos = -6;
            } else if (loop < y && xPos < maxX) {
                xPos = -6;
                yPos = yPos -6 -6 -64;
                loop++;
            }
            $(element).css('background-position', xPos + 'px ' + yPos + 'px');
        };
        
        var animatedStickers = function (element, total, x, y, last, times) {
            $(element).removeAttr('onmouseover');                                    
            var interval = setInterval(function () { stickerInterval(element, x, y, last) }, 175);

            setTimeout(function () {
                clearInterval(interval);
                loop = 1;
                $(element).css('background-position', '-6px -6px');
                $(element).attr('onmouseover', 'animatedStickers($(this), ' + total + ', ' + x + ', ' + y + ', ' + last + ', ' + times + ')')
            }, 175 * total * times);
        };
  </script>

I wanna use multiple setInterval() and clear all of them NOT in a time.

<div id="div1" onmouseover="divOver($(this))"></div>
<div id="div2" onmouseover="divOver($(this))"></div>

<script>
var divOver = function (element) {
   var id = $(element).attr('id'); // get id

   //call setInterval() without the id
   var interval = setInterval(function(){ /* do something... */ }, 500);

   //clear interval after 1s
   setTimeout(function(){ clearInterval(interval) }, 1000);
};
</script>

That code doesn't work fine if I mouseover 2 divs at the same time.

I think: The first I mouseover on div1, function divOver creates a variable name interval. After that (haven't cleared interval yet), I mouseover on div2, function divOver comtinues creating a new variable with the same name interval. So, the first interval can be overridden. Is it right?

To avoid that problem, I think about using setInterval() with id. Something's like this:

var id = $(element).attr('id');
//var interval_ + id = setInterval(function(){ /* do something... */ }, 500);

But that's not javascript syntax. Can you give me any idea to fix this problem?

  • 3
    I don't see why that code wouldn't work. `interval` is a **local** variable. – Quentin Nov 04 '15 at 15:22
  • can you provide a fiddle ? – Gonzalo.- Nov 04 '15 at 15:22
  • 2
    SO has supported [inline live demos](https://blog.stackoverflow.com/2014/09/introducing-runnable-javascript-css-and-html-code-snippets/) for over a year now. No need to run off to externally hosted sites like JS Fiddle. – Quentin Nov 04 '15 at 15:23
  • If you'd identified your problem correctly, this would be a duplicate of [this question](http://stackoverflow.com/questions/5187530/variable-variables-in-javascript). But that is unlikely to help with your real problem. – Quentin Nov 04 '15 at 15:24
  • 1
    I still feel jsfiddle more comfortable. – Gonzalo.- Nov 04 '15 at 15:28
  • Should work as is. Your function in `setTimeout` is closing over the local `interval` variable. – Matt Burland Nov 04 '15 at 15:32
  • ES6 supports `['interval' + id] = setInterval()` to set the key name. Why not simply use `mouseover` and `mouseleave`? Also, the element you are passing to your function is _already_ jQuery, so why do `$(element)` again? Also, SO snippets are much more useful in _Stack Overflow_ as it keeps your code nice and tidy and easy to copy so we can change things and post them as answers with the least amount of hassle. – somethinghere Nov 04 '15 at 15:32
  • @Gonzalo.- I have updated my question. Please check for me again –  Nov 04 '15 at 15:37
  • [This](http://jsfiddle.net/bbyrquue/) seems to work as expected (one minor problem is that you do have a race condition as to whether or not the second interval will fire before the timeout - but that aside). So I'm not quite sure what the question is. What does `clear all of them NOT in a time` mean? – Matt Burland Nov 04 '15 at 15:38
  • @Quentin It disappears automatically after a minute. Please check again in my updated question –  Nov 04 '15 at 15:39
  • @MattBurland I mean that: If I create multiple variable with name `interval`, what will `interval` be cleared in line `clearInterval(interval)`? Clear all `interval` or first `interval` or ....? –  Nov 04 '15 at 15:41
  • As an aside, you'd be better off not attaching event handlers inline like that and instead using `.on` to attach a handler. Then you can use `.off` rather than that nasty `.removeAttr` stuff. – Matt Burland Nov 04 '15 at 15:43
  • @Mr.Wolf: It'll clear the one it closed over. In other words, your function in `setTimeout` will clear the `interval` that was current at the time you created the function. In other, other words, it will clear the `interval` that was current at the time you called `setTimeout`. It maybe worth your while to read about closures in javascript. It's hard to describe, but actually pretty simple once you figure it out. Now what was the behavior you *actually wanted*? – Matt Burland Nov 04 '15 at 15:45

1 Answers1

7

To answer your question how to maintain a record of different intervals at the same time and being able to start and stop them outside the function scope.

You need to keep an associative arrays with the intervals, such that there can be many intervals at the same time.

<div id="div1" onmouseover="divOver($(this))"></div>
<div id="div2" onmouseover="divOver($(this))"></div>

<script>
var intervals = []
var divOver = function (element) {
   var id = element.attr('id'); // get id

   //call setInterval() with the id
   intervals['i'+id] = setInterval(function(){ /* do something... */ }, 500);

   //clear interval after 1s
   setTimeout(function(){ clearInterval(intervals['i'+id]) }, 1000);
};
</script>

Though as already mentioned this does most likely not solve your real problem.

Niki van Stein
  • 10,564
  • 3
  • 29
  • 62
  • 3
    Why was this downvoted? It seems to solve the issue of not being able to declare his own variable name dynamically. – somethinghere Nov 04 '15 at 15:39
  • 1
    @somethinghere: I didn't downvote, but this does seem entirely unnecessary since the original code was closing over `interval` and therefore didn't need to be dynamically named in the first place. Of course, it's not entirely clear what behavior the OP actually wants in the first place. – Matt Burland Nov 04 '15 at 15:48
  • 1
    @MattBurland Agreed, but still, down voting on this site is a bit too shoot-first-ask-questions-later... From how I read the question, it actually answered it. It didn't solve the issue, but answered the question. Ah well. – somethinghere Nov 04 '15 at 15:49
  • 1
    @somethinghere: It would have been nice if the downvoter had bothered to comment on why they downvoted... – Matt Burland Nov 04 '15 at 15:51
  • @MattBurland So, can you tell me where is the wrong line in my js code? –  Nov 04 '15 at 15:53
  • Maybe someone wants to upvote to correct the downvote? ;) – Niki van Stein Nov 04 '15 at 16:03
  • @Mr.Wolf: Since it's not clear what you are *actually trying to achieve*, it's kind of difficult to answer. – Matt Burland Nov 04 '15 at 16:10
  • 1
    @BasvanStein: I didn't downvote, but that doesn't mean I think the downvote needs to be "corrected". – Matt Burland Nov 04 '15 at 16:11
  • People are so snotty. Good answer. –  Aug 23 '16 at 18:33
  • If the question and the problem are not exactly matched in the OP, that's not the fault of the answering user. So, whoever, please correct your downvote - the question has been answered and this is what stackoverflow is made for. – philburns May 26 '20 at 08:36