javascript - 带有 setInterval 的 jQuery 插件作用域

标签 javascript jquery jquery-plugins timer

我正致力于在 jQuery 中编写自定义倒数计时器,并且我正在尝试将其编写为插件。我根据 http://jqueryboilerplate.com/ 中的代码编写了插件和 https://github.com/zenorocha/jquery-plugin-patterns/但我遇到了范围问题。

这是我的倒计时代码:

;(function ( $, window, document, undefined ) {
var pluginName = "countdown",
    defaults = {
        year: "",
        month: "",
        day: "",
        labels: true,
        includeMS: true
    },
    times = {
        ms: 0,
        sec: 0,
        min: 0,
        hr: 0,
        day: 0
    };

function Countdown( element, options ) {
    this.element = element;

    this.options = $.extend( {}, defaults, options );

    this._defaults = defaults;
    this._name = pluginName;

    this._times = times; // I wonder if this will cause multiple timers to fail.

    this.init();
}

Countdown.prototype = {

    init: function() {
        $container = $(document.createElement('div')).addClass('rd_countdown_container').append(
            $('<span class="days countdown_time"></span> <span class="day_label countdown_label">Days</span> <span class="hours countdown_time"></span> <span class="hour_label countdown_label">Hours</span><span class="minutes countdown_time"></span> <span class="minute_label countdown_label">Minutes</span><span class="seconds countdown_time"></span> <span class="second_label countdown_label">Seconds</span><span class="ms countdown_time"></span> <span class="ms_label countdown_label">ms</span>')
            );
        if(this.options.labels === false) { $container.children('.countdown_label').hide(); }
        if(this.options.includeMS === false) { $container.children('.ms, .ms_label').hide(); }
        $(this.element).html($container);
        this.options.endDate = new Date(this.options.year, this.options.month - 1, this.options.day);
        this.intervalTimer = setInterval(this._updateCountdown, 88);
    },

    _updateCountdown: function(e) {
        var x = 0;
        var ms = this.options.endDate - new Date();
        x = this._times.ms / 1000;
        var sec = Math.floor(x % 60);
        x = x / 60;
        var min = Math.floor(x % 60);
        x = x / 60;
        var hr = Math.floor(x % 24);
        var day = Math.floor(x / 24);

        $('.rd_countdown_container .days').text(day);
        $('.rd_countdown_container .hours').text(hr);
        $('.rd_countdown_container .minutes').text(min);
        $('.rd_countdown_container .seconds').text(sec);
        $('.rd_countdown_container .ms').text(this._pad(ms % 1000, 3));
    },

    _pad: function(num, size) {
      var s = "000000000" + num;
      return s.substr(s.length-size);
    },

    stop: function() {
        console.log("Testing stop");
        clearInterval(this.intervalTimer);
    }
};

$.fn[pluginName] = function ( options ) {
    var args = arguments;
    if (options === undefined || typeof options === 'object') {
        return this.each(function () {
            if (!$.data(this, 'plugin_' + pluginName)) {
                $.data(this, 'plugin_' + pluginName, new Countdown( this, options ));
            }
        });
    } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {
        return this.each(function () {
            var instance = $.data(this, 'plugin_' + pluginName);
            if (instance instanceof Plugin && typeof instance[options] === 'function') {
                instance[options].apply( instance, Array.prototype.slice.call( args, 1 ) );
            }
        });
    }
};
})( jQuery, window, document );

如果我对样板的理解正确,所有插件设置都存储在页面上 DOM 中实例化的对象中。

我遇到的问题是 setInterval 中调用的函数无法访问插件对象的其余部分,因此它实际上无法获得 endDate 来计算时间差。此外,当我调用 $('.countdown').countdown('stop') 时,它不会清除 setInterval 函数。

那么,jQuery 插件中是否有我遗漏的模式或只是忽略了一些非常基本的东西?此外,任何有关提高性能的建议都将不胜感激。谢谢!

最佳答案

当 setInterval 调用 _updateCountdown 时,范围是 window,而不是倒计时插件的实例。为了让 _updateCountdown 能够访问插件的其余部分,您需要像这样代理调用:

setInterval($.proxy(this._updateCountdown, this), 88);

关于javascript - 带有 setInterval 的 jQuery 插件作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14608994/

相关文章:

javascript - 使用 $or 在 mongoose 中复杂化多个查询

JavaScript 替换 url

javascript - Rally.environment.getContext().getWorkspace() 为空

javascript - 附加的 anchor 链接在 Safari/iPhone 上无效

javascript - 如何获取图片点击Froala Editor

javascript - 使用 AJAX Rails 从 View 中删除评论

javascript - 在不移动网格的其他行的情况下替换行中的所有 div

Jquery 如果 div 有 value1-10 添加类

jquery - selected.js::有人有实际的工作示例吗?

javascript - 缩放图像灯箱