Amelie Fowl
Amelie Fowl

Reputation: 83

Why clearInterval() works only once?

The basic idea is to identify if the page has a video, wait until it's over and then keep sliding the pages that don't contain the video with interval of 30 sec. It clears interval and waits until it finishes only once. In the second time it just keeps sliding like other pages.

function getPage(i) {
  return p[i];
}

var pages = '@ViewBag.pages';
var p = JSON.parse(pages.replace(/(&quot\;)/g, "\""));
var i = 0;
var mi = p.length - 1;
var interval;
var frame = document.getElementById("slider");
var frameDoc = frame.contentDocument || frame.contentWindow.document;
frame.onload = function() {
  if ($(document).find("iframe").contents().find("video").length == 1) {
    clearInterval(interval);
    console.log("interval was cleared successfully");
    console.log("the video is now playing!");
    var video = document.getElementById('slider').contentWindow.document.getElementById('video');
    video.onended = function() {
      console.log("video is finished!");
      i++;
      if (i > mi) {
        i = 0
      }
      frame.src = getPage(i);
    }
  } else {
    console.log("video is not found");
    interval = setInterval(function() {
      i++;
      if (i > mi) {
        i = 0
      }
      $.ajax({
        async: false,
        url: getPage(i),
        type: 'GET',
        success: function() {
          frame.src = getPage(i);
        }
      });

    }, 10000);
  }
}

Upvotes: 0

Views: 56

Answers (1)

AvcS
AvcS

Reputation: 2323

The problem here is that clearInterval is not getting called when the page doesn't have a video.

Let's take the following scenario, you have 2 pages without video and 1 page with video in that order

  1. First page is loaded, setInterval is started and stores the reference in variable interval.
  2. After 10000ms next page is loaded, the previous setInterval is not cleared as the page doesn't have a video, and interval is updated with a new setInterval. Now you have two setIntervals running, lets say interval1 and interval2
  3. After 10000ms, this time 2 setIntervals are executed, interval1 moves the page to 3rd page and interval2 moves the page to 1st page.
  4. You keep creating new setIntervals until you go to a page with video and when you do reach the page with video, you are clearing only one interval which is the last one. That still leaves all other intervals alive, which keep updating your page.

Solutions:

  1. Run clearInterval unconditionally inside iframe.onload
var interval;
frame.onload = function() {
  interval && clearInterval(interval);
  if ($(document).find("iframe").contents().find("video").length == 1) {
  } else {
    interval = setInterval(function() {}, 10000);
  }
}
  1. Use setTimeout as you want it to be executed only once.
frame.onload = function() {
  if ($(document).find("iframe").contents().find("video").length == 1) {
  } else {
    setTimeout(function() {}, 10000);
  }
}

PS: I prefer the second one

Upvotes: 1

Related Questions