对象中的setInterval出现问题's方法

Trouble with setInterval in an object's method

本文关键字:方法 问题 setInterval 对象      更新时间:2024-05-06

我不明白为什么当我调用对象的重置方法时,计时器仍然为空。下面是我的对象的简化版本,后面是构造新对象并运行代码的jQuery。关于我的具体问题,请参阅大写评论。谢谢

    var countdownTimer = {
        // Default vars
        milliseconds: 120000,
        interval: 1000, 
        timer: false,
        /* ... stuff ... */
        countdown: function () {
            var root = this;
            var originalTime = root.milliseconds;
            /* ... stuff */
            // IN MY MIND THIS NEXT LINE SETS THE INSTANCE OF THIS OBJECT'S TIMER PROPERTY TO THE setIterval's ID.  BUT DOESN'T SEEM TO BE CORRECT. WHY?
            root.timer = setInterval(function () {
                if (root.milliseconds < 1) {
                    clearInterval(root.timer); // THIS LINE SEEMS TO WORK
                    root.countdownComplete(); // callback function
                    return false;
                }
                root.milliseconds = root.milliseconds - root.interval;
                /* .... stuff ... */
            }, root.interval);
        },
        start: function (ms) {
            if (ms) {
                this.milliseconds = ms;
            }
            if(this.timer) {
                clearInterval(this.timer);  // NOT SURE IF THIS WORKS OR NOT
            }
            this.countdown();
        },
        reset: function (ms) {
            var root = this;
            if(root.timer) {
                clearInterval(root.timer); // THIS DOES NOT WORK
            } else {
                console.log('timer not exist!!!!'); // ALWAYS END UP HERE. WHY?
            }
            /* .... stuff ... */
        },
        countdownComplete: function() {  }
    };
// Setting up click events to create instances of the countdownTimer
$(function () {
    var thisPageCountdown = 4000;
    $('[data-countdown]').on('click', '[data-countdown-start], [data-countdown-reset]', function () {
        var $this = $(this);
        var $wrap = $this.closest('[data-countdown]');
        // create instance of countdownTimer
        var myCountdown = Object.create(countdownTimer);
        if ($this.is('[data-countdown-start]')) {
            $this.hide();
            $('[data-countdown-reset]', $wrap).css('display', 'block');
            myCountdown.$wrap = $wrap;
            myCountdown.start(thisPageCountdown);
            // myCountdown.countdownComplete = function() {
            //  alert("Updated Callback!");
            // };
        } 
        if ($this.is('[data-countdown-reset')) {
            $this.hide();
            $('[data-countdown-start]', $wrap).css('display', 'block');
            // RESET CALLED HERE BUT DOESN'T WORK RIGHT. SAYS myCountdown.timer IS STILL null. WHY?
            myCountdown.reset(thisPageCountdown); 
        }
    });
});

当您在点击函数回调中使用var myCountdown = Object.create(countdownTimer);时,您只将其范围限定为该回调,一旦执行了回调,它就会被垃圾回收。您只需要创建countdownTimer的一个实例,并且它应该在单击事件处理程序之外。

var thisPageCountdown = 4000;
// create instance of countdownTimer
var myCountdown = Object.create(countdownTimer);
$('[data-countdown]').on('click', '[data-countdown-start], [data-countdown-reset]', function () {
    var $this = $(this);
    var $wrap = $this.closest('[data-countdown]');

TL;DR您可以通过避免在静态方法中使用关键字this来解决问题。

在静态javascript方法中使用关键字this时,它指的是调用点最后一个点之前的项。示例:

foo.bar(); // inside, this will refer to foo
foo.bar.foobar(); //inside, this will refer to foo.bar
var a = foo.bar.foobar();
a(); //this will refer to either null or window - oops

为了防止这种行为,您应该在静态方法中始终使用完全限定的名称引用,而不是依赖于this关键字。

以上示例:

reset: function (ms) {
  //var root = this; // don't do this
  if(countdownTimer.timer) {
    clearInterval(countdownTimer.timer); 
  } else {
    console.log('timer not exist!!!!'); 
  }
  /* .... stuff ... */
}