设置type="button"的按钮为何会被回车键触发?
问题分析与解决方案
我懂你遇到的头疼问题:明明给按钮设了type="button",还在输入框的keyup事件里加了evt.preventDefault(),可在type="number"的输入框按回车时,还是会莫名其妙触发按钮的点击事件。
为啥会出现这种怪事?
这是浏览器的一个默认行为:当页面里只有一个可交互的输入框时,哪怕你没写<form>标签,浏览器也会自动把这些元素隐式包裹进表单里。按下回车键时,浏览器会触发这个隐式表单的提交动作,并且会把这个动作“绑定”到页面上的第一个按钮——哪怕这个按钮是type="button",也会被误触发。
给你几个靠谱的解决办法:
方案1:显式套表单,阻止表单提交
给输入框和按钮加个<form>标签,直接拦截表单的默认提交行为,从根源上解决问题:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <form class="number-input-form"> <input type="number" class="form-control numberToEnter"> <button type="button" class="btn btn-default buttonForNumber"> Button </button> </form>
$(".buttonForNumber").on('click', function (evt) { alert("I'm here, I don't know why"); }); // 阻止表单默认提交 $(".number-input-form").on('submit', function(evt) { evt.preventDefault(); }); $(".numberToEnter").on('keyup', function (evt) { if (evt.keyCode === 13) { // 这里写你要执行的自定义逻辑 console.log("回车触发了我的专属操作"); } });
方案2:在输入框事件里阻止冒泡
除了阻止默认行为,还要阻止事件向上冒泡,避免触发浏览器的隐式表单逻辑:
$(".buttonForNumber").on('click', function (evt) { alert("I'm here, I don't know why"); }); $(".numberToEnter").on('keyup', function (evt) { evt.preventDefault(); evt.stopPropagation(); // 阻止事件往上冒泡到隐式表单 if (evt.keyCode === 13) { //do something.... console.log("回车触发了我的专属操作"); } });
方案3:加个隐藏的输入框“骗”浏览器
浏览器的这个默认行为只在页面只有一个输入框时触发,所以我们可以加个隐藏的输入框,打破这个条件:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <input type="number" class="form-control numberToEnter"> <!-- 加个隐藏的输入框,让浏览器认为不止一个输入元素 --> <input type="text" style="display: none;"> <button type="button" class="btn btn-default buttonForNumber"> Button </button>
这样浏览器就不会把回车行为绑定到按钮上了,你的原有逻辑也能正常跑起来。
测试一下
随便选一个方案试试,应该都能解决回车键误触按钮的问题。核心就是打断浏览器那个“自作主张”的隐式表单提交逻辑。
内容的提问来源于stack exchange,提问作者Pedro Joaquín
相关产品推荐
相关产品推荐

