jQuery键盘事件异常:回车触发按钮点击两次问题排查
问题分析:回车触发两次按钮点击的根源
你遇到的问题核心在于事件绑定的上下文错误,导致同一个keypress事件被重复监听了两次,最终触发两次按钮点击。
让我拆解一下你的代码问题:
在你的noEnter扩展中,_init函数里的$(this)并没有指向你调用扩展的输入框元素,而是指向了全局的window对象!
看这段代码:
this.each(function(){_init();});
当你在each循环里直接调用_init()时,没有给_init绑定任何上下文,所以_init函数内部的this默认指向window。这意味着:
- 当你调用
$("#email").noEnter(...)时,实际上给window绑定了一次keypress事件 - 当你再调用
$("#pass").noEnter(...)时,又给window绑定了第二次keypress事件
当你在输入框按下回车时,window上的两个keypress事件都会被触发,自然就会调用两次按钮的click事件。
修正方案
方案1:修复扩展中的上下文绑定
只需要修改each循环中调用_init的方式,用call把当前元素作为上下文传入:
(function($){ $.fn.noEnter=function(options){ let settings=$.extend({btn:""},options); function _init(){ $(this).on("keypress",function(event){ if(event.keyCode === 13) { event.preventDefault(); $("#"+settings.btn).click(); return false; } }); } this.each(function(){ _init.call(this); // 绑定当前元素作为_init的上下文 }); return this; // 保持jQuery链式调用习惯,不要返回空对象 }; }(jQuery));
方案2:简化扩展逻辑(更推荐)
直接去掉单独的_init函数,把逻辑写在each循环内部,避免上下文混乱:
(function($){ $.fn.noEnter=function(options){ let settings=$.extend({btn:""},options); return this.each(function(){ $(this).on("keypress",function(event){ if(event.keyCode === 13) { event.preventDefault(); $("#"+settings.btn).click(); return false; } }); }); }; }(jQuery));
额外优化建议
其实你不需要给每个输入框单独调用noEnter,可以直接给父级form绑定事件,利用事件委托来处理所有输入框的回车事件,这样更高效,也避免重复绑定:
// 去掉所有输入框的noEnter调用,换成这一行 $("#testForm").on("keypress", "input", function(event) { if (event.keyCode === 13) { event.preventDefault(); $("#btnLogin").click(); return false; } });
这样不管表单里有多少输入框,只需要绑定一次事件即可达到相同效果。
内容的提问来源于stack exchange,提问作者Војин Петровић
相关产品推荐
相关产品推荐

