TimingField插件upHour方法在setInterval+$.proxy中无法触发的问题求助
解决TimingField时间选择器中setInterval无法触发upHour方法的问题
这个问题的核心在于**setInterval回调函数里的this指向错误,以及你没有正确执行绑定后的函数**,下面给你具体的解决思路和修改方案:
问题根源分析
this指向丢失:在setInterval的普通函数回调中,this默认指向全局对象(浏览器环境下是window),而不是TimingField插件的实例对象,所以直接调用this.upHour会找不到这个方法。- 未执行绑定后的函数:你在测试代码里写了
$.proxy(this.upHour, this),但这只是创建了一个绑定好上下文的函数,并没有实际调用它——相当于你定义了函数但没执行,自然不会触发upHour。
正确修改方案
这里提供几种可行的修改方式,你可以根据项目环境选择:
方案1:提前绑定函数上下文(兼容旧环境)
在mousedown回调里提前用$.proxy把upHour的上下文绑定到插件实例,再传给setInterval:
this.tpl.find('.timingfield_hours .timingfield_next') .on('mouseup', function() { clearInterval(timeoutId); return false; }) .on('mousedown', function(e) { // 提前绑定好插件实例的上下文 const boundUpHour = $.proxy(this.upHour, this); timeoutId = setInterval(boundUpHour, 100); return false; });
方案2:使用ES6箭头函数(支持现代浏览器)
箭头函数会继承外部作用域的this,不需要额外绑定:
this.tpl.find('.timingfield_hours .timingfield_next') .on('mouseup', function() { clearInterval(timeoutId); return false; }) .on('mousedown', (e) => { timeoutId = setInterval(() => { this.upHour(); }, 100); return false; });
方案3:保存this引用(传统写法)
在mousedown回调里先把插件实例的this保存到变量中,再在定时器回调里使用:
this.tpl.find('.timingfield_hours .timingfield_next') .on('mouseup', function() { clearInterval(timeoutId); return false; }) .on('mousedown', function(e) { const self = this; // 保存当前插件实例的引用 timeoutId = setInterval(function() { self.upHour(); // 通过self调用实例方法 }, 100); return false; });
验证效果
修改后,当你按住按钮时,setInterval会每隔100ms正确触发upHour方法;松开鼠标时,mouseup事件会清除定时器,停止触发方法,完全符合你的预期。
内容的提问来源于stack exchange,提问作者Federico Navarrete
相关产品推荐
相关产品推荐

