我使用 moment.js 和 moment-duration-format plugin 制作了一个 jQuery 倒计时器。 .
请注意,$('div#countdown')
是硬编码在函数内部的。该函数的工作方式如此处所示。但如果我更改对 $(this) 的硬编码引用,它就不起作用。 console.log($this)
返回一个空对象。
我尝试在函数开始时将 $(this) 设置为变量,以防间隔造成范围问题,但这没有什么区别。
令人困惑的部分是,我之前已经在自定义 jQuery 函数中使用过这种精确的 $.fn.xxx = function
语法,并且 $(this) 在这些函数中工作得很好。这个特定函数的一些问题导致了它的失败。
<script>
$.fn.countdown = function ( seconds, tFormat, stopAtZero ) {
tFormat = (typeof tFormat !== 'undefined') ? tFormat : 'hh:mm:ss';
stopAtZero = (typeof stopAtZero !== 'undefined') ? stopAtZero : true;
var eventTime = Date.now() + ( seconds * 1000 );
var diffTime = eventTime - Date.now();
var duration = moment.duration( diffTime, 'milliseconds' );
var interval = 0;
var counter = setInterval(function () {
$('div#countdown').text( moment.duration( duration.asSeconds() - ++interval, 'seconds' ).format( tFormat, { trim: false }) );
if( stopAtZero && interval >= seconds ) clearInterval( counter );
}, 1000);
};
$('div#countdown').countdown( 30*60, 'mm:ss' );
</script>
<div id="countdown"></div>
编辑:已解决。功能很好。它只需要位于 Div 之后(或文档加载之后)::headdesk::
最佳答案
问题是因为 setTimeout()
中的函数在与外部函数不同的范围内运行。因此 this
并不是您所期望的那样。您需要缓存 this
引用。
另请注意,您可以通过向包含选项的函数提供一个对象来稍微改进逻辑。然后您可以使用 $.extend
提供默认值。您还应该循环 this
以使用户能够提供对象集合来初始化插件。试试这个:
$.fn.countdown = function(options) {
var defaults = {
seconds: 0,
tFormat: 'hh:mm:ss',
stopAtZero: true,
complete: function() {}
};
var settings = $.extend(defaults, options);
$(this).each(function() {
var $el = $(this);
var eventTime = Date.now() + (settings.seconds * 1000);
var diffTime = eventTime - Date.now();
var duration = moment.duration(diffTime, 'milliseconds');
var interval = 0;
var counter = setInterval(function() {
$el.text(moment.duration(duration.asSeconds() - ++interval, 'seconds').format(settings.tFormat, {
trim: false
}));
if (settings.stopAtZero && interval >= settings.seconds) {
clearInterval(counter);
settings.complete();
}
}, 1000);
});
}
$('div').countdown({
seconds: 10,
complete: function() {
console.log('finished!');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/1.3.0/moment-duration-format.min.js"></script>
<div></div>
关于jquery - $(this) 在自定义 jQuery 函数中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43683505/