Stop JavaScript when it is not there or leaves the window

1

I have a jQuery slider that runs even when it is not in the window where it is located, this consumes me in vain processing resources.

Script

$(document).ready(
$(function() {

//configuracion
var width = 650;
var animationSpeed = 1000;
var pause = 7000;
var currentSlide = 1;

//cache DOM
var $slider = $('#slider');
var $slideContainer = $('.slides', $slider);
var $slides = $('.imgSlide', $slider);

var interval;

function startSlider() {
    interval = setInterval(function() {
        $slideContainer.animate({'margin-left': '-='+width}, animationSpeed, function() {
            if (++currentSlide === $slides.length) {
                currentSlide = 1;
                $slideContainer.css('margin-left', 0);
            }
        });
    }, pause);
}
function pauseSlider() {
    clearInterval(interval);
}

$slideContainer
    .on('mouseenter', pauseSlider)
    .on('mouseleave', startSlider);

startSlider();


})
);
    
asked by Asahi Sara 10.09.2016 в 19:13
source

3 answers

2

You can detect when the current document is active by means of the Visibility API . To detect if the document is active, just do this:

if(!document.hidden) {
     // parar la ejecución de scripts, etc.
}

It is also possible to add a listener to the visibility of the document, in such a way that it detects when the tab has been changed / returned.

document.addEventListener('visibilitychange', onVisibilityChange, false);

function onVisiblityChange(e) {
    if(document.hidden) {
        pauseSlider();
    } else {
        startSlider();
    }
}

Compatibility

  • Chrome 33 +
  • Firefox 18 +
  • IE 10 +
  • Opera 12
  • Safari 7 +
answered by 10.09.2016 в 19:34
1

The solution is to validate whether or not the slider exists. Since you know that the slider can identify it with #slider , what remains is as simple as adding the following condition in your code

if($('#slider').length > 0) {

}

Therefore, it would fit you as follows:

$(document).ready(function() {
    if ($('#slider').length > 0) {
        //configuracion
        var width = 650;
        var animationSpeed = 1000;
        var pause = 7000;
        var currentSlide = 1;

        //cache DOM
        var $slider = $('#slider');
        var $slideContainer = $('.slides', $slider);
        var $slides = $('.imgSlide', $slider);

        var interval;

        function startSlider() {
            interval = setInterval(function() {
                $slideContainer.animate({
                    'margin-left': '-=' + width
                }, animationSpeed, function() {
                    if (++currentSlide === $slides.length) {
                        currentSlide = 1;
                        $slideContainer.css('margin-left', 0);
                    }
                });
            }, pause);
        }

        function pauseSlider() {
            clearInterval(interval);
        }

        $slideContainer
          .on('mouseenter', pauseSlider)
          .on('mouseleave', startSlider);

        startSlider();

    }
});

Greetings

    
answered by 10.09.2016 в 23:32
1

A different option to those that you have provided in other answers could be using the function requestAnimationFrame of javascript, which allows you to execute (let's say) "recursively" the code you need to execute:

animate();

function animate() {
  requestAnimationFrame(animate);
  // Aqui iría el código que quieres que se ejecute iteradamente...
}

requestAnimationFrame returns an identifier for each call, which you can use to stop the execution of the code at the time you need it:

var requestID;
animate();

function animate() {
  requestID = requestAnimationFrame(animate);
  // El código que quieras ejecutar iteradamente iría aquí.
}

$('#stop').click(function() {
  cancelAnimationFrame(requestID);
});

The problem with the previous code is that you are not controlling how often the code will be executed. The only thing you would need to do would be to "emulate" the behavior of setTimeout or setInterval. Here is a functional example of how it would be done:

Note: Here you can find information about the support that requestAnimationFrame has in different browsers.

(function() {
  var requestID;
  var i = 0;
  var last;
  var interval = 2000; // Intervalo en milisegundos
  animate();

  function animate() {
    requestID = requestAnimationFrame(animate);
    if (canExecuteCode()) {
      // El código que quieres ejecutar:
      var node = document.createElement('DIV');
      node.innerText = ++i;
      document.body.appendChild(node);
    }
  }

  function canExecuteCode() {
    if (!last) {
      last = Date.now();
      return true;
    }
    
    var now = Date.now();
    var elapsed = now - last;
    
    if (elapsed >= interval) {
      last = now;
      return true;
    }
    
    return false;
  }

  document.getElementById('stop').addEventListener('click', function() {
    if (requestID) {
      cancelAnimationFrame(requestID);
      requestID = undefined;
    }
  });

  document.getElementById('continue').addEventListener('click', function() {
    if (!requestID) animate();
  });
})();
<body>
  <button id="stop">Stop!</button>
  <button id="continue">Continue</button>
</body>
    
answered by 11.09.2016 в 06:28