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 プラグインに、欠落している、または非常に基本的なものを見落としているパターンはありますか? また、パフォーマンスを向上させるための提案をいただければ幸いです。ありがとう!