2

This question is related to this one Clear all setIntervals

I'm using setIntervals within each function like so,

var allIntervals = [];
$(".elements").each(function() {
    var myInterval = setInterval(function() {
        // code that changes $(this)
    });
   allIntervals.push(myInterval);
});

I then clear all the intervals like this

jQuery.each(allIntervals, function(index) {
    window.clearInterval(allIntervals[index]);
});

I now realized that I want to instead clear intervals of elements that are no longer in the DOM.

So how do I link the setIntervals to each() element, then check if the element is still in the DOM, and if not, clear the Interval associated with that element?

Community
  • 1
  • 1

2 Answers2

3

You can store the element with the ID from the timeout in an object, but you have to check again to see if it's in the DOM as the stored element doesn't magically dissapear from the variable, it's just no longer in the DOM.

var allIntervals = [];

$(".elements").each(function(i, el) {
    var myInterval = setInterval(function() {
        // stuff
    }, 1000);
   allIntervals.push({id : myInterval, elem : this});
});


$.each(allIntervals, function(index, item) {
    if ( $(document).find(item.elem).length === 0 ) window.clearInterval(item.id);
});

FIDDLE

adeneo
  • 312,895
  • 29
  • 395
  • 388
  • I see in the console that it returns 5 despite it not being removed –  Dec 14 '15 at 00:18
  • This doesn't seem to work for me. What do you mean by 'check again'? –  Dec 14 '15 at 01:35
  • I mean that if you store an element in a variable, then remove the element from the DOM with `remove()`, the element is still present in the variable, just not in the DOM, see [**this**](http://jsfiddle.net/pfshgcj1/). One has to actually query the DOM once more to check that the element is gone. Also, what you see in the console in that fiddle is the index, it's zero based, so it doesn't match the numbers I added in the DIV's, I should've probably made that more consistent, like this -> http://jsfiddle.net/v9rLqc9v/1/ – adeneo Dec 14 '15 at 02:21
  • It's working for me now. So would you suggest I remove the object from the variable if the element is gone right? How would I go about doing that? would splice be the thing for that? How would I target the unneeded object and remove it? –  Dec 14 '15 at 02:25
  • That depends, do you need to remove each entry from the array if the element is removed? Are you using the array for anything else? If not, there's no reason to remove anything? – adeneo Dec 14 '15 at 02:38
  • No. I'm only using the array to clear intervals, I guess I don't need to remove it but wouldn't it eventually be checking for hundreds if not thousands of elements that don't even exist, and therefor impacting performance? –  Dec 14 '15 at 02:40
  • Again, that depends, do you have thousands of elements on the same page, and are you running this over and over again without reloading the page? If you are, then removing the objects from the array might be a good idea, as there is less to check on the next run, and there's a slight possibility the objects will be garbage collected. When the page reload, everything will be lost anyway. – adeneo Dec 14 '15 at 02:45
  • Yes, the page may be open for a long time and many elements will be removed and also new ones added. –  Dec 14 '15 at 02:47
  • 1
    Then it's probably a good idea to clean up the array as well, and you could use a filter for that -> http://jsfiddle.net/v9rLqc9v/2/ – adeneo Dec 14 '15 at 02:57
0

Use an object to store the information (with the element and the intervalid as properties), loop through the object and clear the interval if the DOM element if not available.

$(function() {

  var intervals = [];

  $(".elements").each(function() {
    var myInterval = setInterval(function() {
      // code that changes $(this)
    });
    var obj = new Object();
    obj.element = $(this);
    obj.intervalId = myInterval;

    intervals.push(obj);
  });

  $.each(intervals, function(index, val) {
     console.log(val.element);
     if (val.element.length > 0) {
         window.clearInterval(val.intervalId);
     }
  });
});
rahul
  • 184,426
  • 49
  • 232
  • 263