承接上一篇日志,当我们在使用setInterval来循环js方法时,会遇到一个bug。就是当用户切换网页后,再切换回来后会发现当前循环运行的js出现问题,比如动画速度发生变化或者动画卡住等。本篇日志就是来解决这个问题。

解决的思路首先是引入visibility,为网页添加这个事件的监听,就能知道网页是什么时候被切换或者正在看。mozilla的举例代码如下

document.addEventListener("visibilitychange", function() {
  if (document.visibilityState === 'visible') {
    backgroundMusic.play();
  } else {
    backgroundMusic.pause();
  }
});

从上面的代码可以看出,先要添加visibilitychange事件监听,再通过visibilityState的值来判断当前网页的可视状态,visibilityState的状态包括以下

  • 'visible' : 此时页面内容至少是部分可见. 即此页面在前景标签页中,并且窗口没有最小化.
  • 'hidden‘ : 此时页面对用户不可见. 即文档处于背景标签页或者窗口处于最小化状态,或者操作系统正处于 ‘锁屏状态’ .
  • 'prerender' : 页面此时正在渲染中, 因此是不可见的 (considered hidden for purposes of document.hidden). 文档只能从此状态开始,永远不能从其他值变为此状态.注意: 浏览器支持是可选的.

通过以上学习,我们来整理一下解决思路。首先当页面第一次打开后,先需要动画函数运行一遍,然后进行循环运行。随后进行网页可视状态监听,在切换网页时,要做以下事情,1、停止循环;2、所有动画停止;3、所有动画元素回到初始状态。在网页回到可视状态时,继续执行循环函数并重新启动循环。在下面代码中的border_loop()就是动画方法,也是上一篇日志中编写的动画方法。利用定义border_loop_start来控制setInterval启停。.border_top到.border_left都是动画涉及到的具体元素,用来控制动画停止和回到原来位置。

    border_loop();
    let border_loop_start = setInterval(border_loop,3300);
    document.addEventListener("visibilitychange",function () {
        if (document.visibilityState == 'hidden'){
            clearInterval(border_loop_start);
            $('.border_top').stop(true,true);
            $('.border_right').stop(true,true);
            $('.border_bottom').stop(true,true);
            $('.border_left').stop(true,true);
            $('.border_top').css({
                right: '100%',
                left: '-100px'
            });
            $('.border_left').css({
                top: '100%',
                bottom: '-40px'
            });
            $('.border_right').css({
                top: '-40px',
                bottom: '100%'
            });
            $('.border_bottom').css({
                right: '-100px',
                left: '100%'
            });
        }
        else {
            border_loop();
            border_loop_start = setInterval(border_loop,3300);
        }
    });

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

左半红印发表于2021.04.5th