我正在用 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 插件中是否存在我遗漏的模式或者只是忽略了一些非常基本的东西?此外,任何有关提高性能的建议将不胜感激。谢谢!