0

I have an HTML page that has timeouts. I want to freeze them when you press a button (#pauseButton) and then resume when you press it again, preferably freezing all BS4 and jQuery animations also.

<button id="pauseButton"></button>
<script>
$(document).ready(function(){
    setTimeout(function() {
        alert("This is an alert")
    },10000);
    $("#pauseButton").click(function(){
        // Pause timeouts and page
    });
});
</script>

EDIT
I have been notified that there is a possible duplicate answer, so I am now focusing on pausing animations and other page elements. That answer shows how to pause timeouts only.

Anonymous
  • 738
  • 4
  • 14
  • 36
  • interesting question. can you describe your use case in real life? – duc mai May 05 '19 at 17:01
  • I am not sure why you would want to do that. But this is already answered. See the attached link https://stackoverflow.com/questions/3969475/javascript-pause-settimeout – Emad Zamout May 05 '19 at 17:06
  • @ducmai I am using on a page that requires you to be fullscreen, but since I cannot block people from exiting fullscreen, I am trying to make an overlay preventing you from doing anything else when you are not fullscreen, and I do not want any activity in the background. – Anonymous May 05 '19 at 17:15

1 Answers1

1

There are many ways to solve this issue. Many of them are mentioned in this question as mentioned by @EmadZamout in the comments.

But, if you are looking for an easy and maybe an alternate way to solve this. Try this. Here I am using requestAnimationFrame to solve the issue

let ran = Date.now(); // contains the last updated time
let time = 0; // time in seconds
let paused = false; // store the state

const func = () => {
  if (!paused && Date.now() - ran > 1000) {
    time++;
    ran = Date.now();
    console.log('now')
  }

  if (time === 8)
    return alert('This works!');

  requestAnimationFrame(func);
}

func();

document.querySelector('button').addEventListener('click', () => paused = !paused);
<button>Change state</button>

For stopping all the animations of the website, you need to manually stop each animation.

For stopping a jQuery animation, you can use .stop() helper. An example:

let paused = false; // state of the animation
let dir = 'down'; // to store the direction of animation so that the next time continues in the correct direction
let timeDown = 2000; // to animate properly after resuming
let timeUp = 2000; // to animate properly after resuming

// the initial calling of the animation
(function() {
  slideDown();
})();


// function which resumes the animation
function animate() {
  switch (dir) {
    case 'up':
      slideUp();
      break;
    case 'down':
      slideDown();
      break;
  }
}

// a function to animate in the uppward direction
function slideUp() {
  dir = 'up'; // setting direction to up
  timeDown = 2000; // resetting the duration for slideDown function
  
  $('div').stop().animate({
    left: 0
  }, {
    duration: timeUp,
    complete: slideDown, // calling slideDown function on complete
    progress: function (animation, progress, ms) {
      timeUp = ms; // changing the duration so that it looks smooth when the animation is resumed
    }
  }); // actual animation
}

// a function to animate in the downward direction
function slideDown() {
  dir = 'down'; // setting direction to down
  timeUp = 2000; // resetting the duration for slideDown function
  
  $('div').stop().animate({
    left: 200
  }, {
    duration: timeDown,
    complete: slideUp, // calling slideUp function on complete
    progress: function (animation, progress, ms) {
      timeDown = ms; // changing the duration so that it looks smooth when the animation is resumed
    }
  }); // actual animation
}

// button click event listener
$('button').click(function() {
  if (paused)
    animate(); // to resume the animation
  else
    $('div').stop(); // to stop all the animations on the object
    
  paused = !paused; // toggling state
});
div {
  position: relative;
  width: 100px;
  height: 100px;
  background: dodgerblue;
}
<button>Pause</button>

<div></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

For bootstrap, I don't think you have any bootstrap animations which needed to be paused in this scenario which you have mentioned since bootstrap animations depend on user interactions. If you want to prevent user interaction, you can put an overlay over the website says "Paused". Or, if you don't want to do that you can use CSS property pointer-events: none to disable all the pointer events.

Now for CSS animations, you can set a property called animation-play-state to paused.

If you want to change the state of the animations to paused when the user is not on the page (As I understood for your updated questions) you can use the new visibilityState API for that. There is an event visibilitychange which is fired when there a change in visibility.

document.addEventListener("visibilitychange", function() {
  console.log( document.visibilityState );
  document.querySelector('div').innerHTML = document.visibilityState;
});
<div>
  Try opening a different tab or change the focus to another app
</div>
Advaith
  • 2,490
  • 3
  • 21
  • 36
  • This _does_ solve the timeout problem, however it doesn't solve pausing animations and other page elements. – Anonymous May 05 '19 at 17:42
  • @Anonymous to solve that issue I will need more information about the animations and other page elements which you are talking about. – Advaith May 05 '19 at 17:47
  • I have edited my answer to show what type of animations I need paused, please let me know if you need any other information. – Anonymous May 05 '19 at 17:50