清除带有对象功能的鼠标移动的时间间隔

问题描述 投票:1回答:1

我很难解决这个问题。我想运行一个屏幕保护程序类型的交互,如果用户闲置(无鼠标移动)的时间超过X,则它会运行,然后在用户活动时清除并停止。

我的问题是,即使屏幕保护程序最初在第一次空闲后似乎可以工作(5秒钟后空闲),因此鼠标移动才能清除/停止;它立即恢复运行(而不是等待5秒),然后screensaverBuildUp间隔似乎加快了(而不是每1秒运行一次)。

有什么想法我要去哪里错吗?

const dev = {};

dev.interactions = {

    init: function() {
        this.bindEvents();
    },

    bindEvents: function() {

        let mouseTimeout, screensaverBuildUp;
        dev.ui.body.addEventListener('mousemove', function() {
            dev.interactions.screensaverClear(screensaverBuildUp);
            clearTimeout(mouseTimeout);
            mouseTimeout = setTimeout(function() {
                dev.interactions.screensaver(screensaverBuildUp);
            }, 5000);
        });

    },

    screensaverRun: function(screensaverRun) {

        screensaverBuildUp = setInterval(function() {

            let $screensaver = document.querySelector('div.screensaver'),
                $graphics = $screensaver.querySelectorAll('img'),
                $randomGraphic = $graphics[Math.floor(Math.random() * $graphics.length)],
                $clonedRandomGraphic = $randomGraphic.cloneNode(true);

            $screensaver.style.display = 'block';

            // Math.floor(Math.random() * (max - min + 1) + min);
            $clonedRandomGraphic.removeAttribute('style');
            $clonedRandomGraphic.removeAttribute('class');
            $clonedRandomGraphic.style.top = Math.floor(Math.random() * (95 - (-5) + 1) + (-5)) + '%';
            $clonedRandomGraphic.style.left = Math.floor(Math.random() * (95 - (-5) + 1) + (-5)) + '%';
            $clonedRandomGraphic.style.transform = 'rotate(' + Math.floor(Math.random() * (360 - (-360) + 1) + (-360)) + 'deg)';
            $screensaver.appendChild($clonedRandomGraphic);

            if ($graphics.length === 50) {
                clearInterval(screensaverBuildUp);
            }

        }, 1000);

    },

    screensaverClear: function(screensaverRun) {

        clearInterval(screensaverBuildUp);

        let $screensaver = document.querySelector('div.screensaver'),
            $graphics = $screensaver.querySelectorAll('img:not(.base)');

        $screensaver.style.display = 'none';

        $graphics.forEach(function($graphic) {
            $graphic.remove();
        });

    }

};
dev.interactions.init();
javascript
1个回答
1
投票
[当您使用screensaverRunscreensaverBuildUp = setInterval(function(中声明内部设备时。这将在全局变量screensaverBuildUp上创建内部计时器,并且在绑定函数中使用dev.interactions.screensaverClear(screensaverBuildUp);清除计时器时,仅清除在绑定函数中使用screensaverBuildUp声明的变量let mouseTimeout, screensaverBuildUp;。因此,您的全局screensaverBuildUp永远不会被清除,这就是您看到它运行的原因。

我已经简化了代码以演示可行的解决方案。将鼠标悬停在要运行的区域上,您将看到控制台日志。

screensaverBuildUp: null,被声明为更高的级别,因此您所有的函数都可以访问它,但不能访问全局变量

const dev = {}; dev.interactions = { mouseTimeout: null, screensaverBuildUp: null, init: function() { this.bindEvents(); }, bindEvents: function() { document.querySelector("body").addEventListener('mousemove', function() { dev.interactions.screensaverClear(dev.interactions.screensaverBuildUp); clearTimeout( dev.interactions.mouseTimeout ); dev.interactions.mouseTimeout = setTimeout(function() { dev.interactions.screensaverRun(); console.log( "run screensaver timer" ); }, 3000); }); }, screensaverRun: function() { dev.interactions.screensaverBuildUp = setInterval(function() { console.log("interval fired") }, 1000); }, screensaverClear: function(screensaverRun) { clearInterval( dev.interactions.screensaverBuildUp ); console.log("screensaver cleared"); } }; dev.interactions.init();
body { height: 4000px }
© www.soinside.com 2019 - 2024. All rights reserved.