简体   繁体   中英

Resume a function after clearInterval

I have this code:

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;
    });
});

I want to suspend the function on mouseover and resume it on mouse out but I cant get the latter right. How can I resume it?

Thank you.

There are two ways:

  1. Set a flag that the function being called by the interval checks, and have the function not do anything if it's "suspended."

  2. Start the interval again via a new setInterval call. Note that the old timer value cannot be used for this, you need to pass in the code again.

Example of #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
        }
    });
});

Example of #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
        }
    });
});

Checkout these prototypes:

        //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 simplifies member initialization, while PeriodicJobHandler is able to manage jobs in a periodic fashion. Now, let's use it practically:

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();
    });
});

With Javascript, it is much easy and efficient. You can change the interval in setInterval function. It is checking whether suspend variable is false or true, here suspend variable is setting to true, if mouseEnter function is called and set to false if mouseLeave function is called.

 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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM