在 clearInterval 后恢复函数

Resume a function after clearInterval

我有这个代码:

jQuery(function($) { // DOM is ready
    var $el = $("header tr"),
        tot = $el.length,
        c = 0;
    var timer = setInterval(function() {
        $el.removeClass("current").eq(++c % tot).addClass("current");
    }, 3000);
    $el.first().addClass("current");
    $el.on({
        mouseenter: function(e) {
            clearInterval(timer);
        }
    });
    $el.mouseout({
        timer;
    });
});

我想在鼠标悬停时暂停该功能并在鼠标移开时恢复它,但我无法正确使用后者。我该如何恢复它?

谢谢。

有两种方法:

  1. 设置一个标志,由间隔调用的函数检查,如果它是"suspended."

  2. ,则让函数不做任何事情
  3. 通过新的 setInterval 呼叫再次开始间隔。注意这里不能使用旧的timer值,需要重新传入代码

#1 示例:

jQuery(function($) { // DOM is ready
    var $el = $("header tr"),
        tot = $el.length,
        c = 0,
        suspend = false;                       // The flag
    var timer = setInterval(function() {
        if (!suspend) {                        // Check it
            $el.removeClass("current").eq(++c % tot).addClass("current");
        }
    }, 3000);
    $el.first().addClass("current");
    $el.on({
        mouseenter: function(e) {
            suspend = true;                    // Set it
        },
        mouseleave: function(e) {
            suspend = false;                   // Clear it
        }
    });
});

#2 示例:

jQuery(function($) { // DOM is ready
    var $el = $("header tr"),
        tot = $el.length,
        c = 0,
        timer = 0;

    // Move this to a reusable function
    var intervalHandler = function() {
        $el.removeClass("current").eq(++c % tot).addClass("current");
    };

    // Probably best to encapsulate the logic for starting it rather
    // than repeating that logic
    var startInterval = function() {
        timer = setInterval(intervalHandler, 3000);
    };

    // Initial timer
    startInterval();

    $el.first().addClass("current");
    $el.on({
        mouseenter: function(e) {
            clearInterval(timer);              // Stop it
        }
        mouseleave: function(e) {
            startInterval();                   // Start it
        }
    });
});

检查这些原型:

        //Initializable
        function Initializable(params) {
            this.initialize = function(key, def, private) {
                if (def !== undefined) {
                    (!!private ? params : this)[key] = (params[key] !== undefined) ? params[key] : def;
                }
            };
        }

        function PeriodicJobHandler(params) {
            Initializable.call(this, params);
            this.initialize("timeout", 1000, true);
            var getTimeout = function() {
                return params.timeout;
            };
            var jobs = [];

            function Job(params) {
                //expects params.job() function
                Initializable.call(this, params);
                this.initialize("timeout", getTimeout(), true);
                this.initialize("instant", false);
                var intervalID = undefined;

                this.start = function() {
                    if (intervalID !== undefined) {
                        return;
                    }
                    if (this.instant) {
                        params.job(true);
                    }
                    intervalID = setInterval(function() {
                        params.job(false);
                    }, params.timeout);
                };

                this.stop = function() {
                    clearInterval(intervalID);
                    intervalID = undefined;
                };
            }

            this.addJob = function(params) {
                jobs.push(new Job(params));
                return jobs.length - 1;
            };

            this.removeJob = function(index) {
                jobs[index].stop();
                jobs.splice(index, 1);
            };

            this.startJob = function(index) {
                jobs[index].start();
            };

            this.stopJob = function(index) {
                jobs[index].stop();
            };
        }

Initializable 简化了成员初始化,而 PeriodicJobHandler 能够以周期性方式管理作业。现在,让我们实际使用它:

var pjh = new PeriodicJobHandler({});
//It will run once/second. If you want to change the interval time, just define the timeout property in the object passed to addJob
var jobIndex = pjh.addJob({
    instant: true,
    job: function() {
        $el.removeClass("current").eq(++c % tot).addClass("current");
    }
});
jQuery(function($) { // DOM is ready
    var $el = $("header tr"),
        tot = $el.length,
        c = 0;
    var timer = setInterval(function() {
        $el.removeClass("current").eq(++c % tot).addClass("current");
    }, 3000);
    $el.first().addClass("current");
    $el.on({
        mouseenter: function(e) {
            jobIndex.stop();
        }
    });
    $el.mouseout({
        jobIndex.start();
    });
});

有了Javascript,就简单多了,效率也高了。 您可以在 setInterval 函数中更改间隔。 它正在检查 suspend 变量是 false 还是 true,这里 suspend 变量设置为 true,如果调用 mouseEnter 函数,如果调用 mouseLeave 函数则设置为 false。

var displayMsg = document.getElementById('msg').innerHTML;
var i = 0;
var suspend = false;
var sequence = setInterval(update, 100);

function update() {
  if (suspend == false) {
    var dispalyedMsg = '';
    dispalyedMsg = displayMsg.substring(i, displayMsg.length);
    dispalyedMsg += '    ';
    dispalyedMsg += displayMsg.substring(0, i);
    document.getElementById('msg').innerHTML = dispalyedMsg;
    i++;
    if (i > displayMsg.length) {
      i = 0;
    }
  }
}
document.getElementById('msg').addEventListener('mouseenter', mouseEnter);
document.getElementById('msg').addEventListener('mouseleave', mouseLeave);

function mouseEnter() {
  suspend = true;
}

function mouseLeave() {
  suspend = false;
}
<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    #msg {
      width: 680px;
      height: 100px;
      border: 1px solid #ccc;
      padding-left: 15px;
    }
  </style>
</head>

<body>
  <div id="msg">
    Today is only 15% discount. Hurry up to grab. Sale will end sooooooooooooon!!!!
  </div>
  <div id="output"></div>
  <script src="marquee.js"></script>
</body>

</html>