jQuery实现Enter键导航表单遇display:none输入框冻结的解决方法
问题根源
你写的代码出现导航冻结,核心是两个逻辑漏洞:
allInputs是页面初始化时一次性获取的静态集合,后续输入框被动态设置为display:none后,这个缓存的集合不会自动更新,仍然保留已隐藏的元素- 跳转下一个输入框时没有做可见性校验,直接尝试给隐藏元素设置焦点,操作失效后就会卡在当前位置,无法继续导航。
你提到不能替换visibility:hidden/opacity:0的隐藏方案完全不影响修复,jQuery的:visible选择器原生就会过滤所有display:none的元素(包括自身或父级设置display:none的情况),不需要手动写判断display属性的逻辑。
最简修复方案
把获取可见输入框集合的逻辑移到Enter键的事件回调里,每次触发导航时实时查询当前页面所有可见的文本输入框,同时修复原代码未传入事件对象的兼容问题即可,改动量最小。
修正后的核心JS代码
$(document).ready(function() { $(":text").on("keyup", function(e) { if (e.key !== "Enter") return; e.preventDefault(); // 每次导航前实时获取当前所有可见的文本输入框,自动过滤display:none的元素 const allVisibleInputs = $(':text:visible'); const currentIdx = allVisibleInputs.index(this); const nextInput = allVisibleInputs.get(currentIdx + 1); if (nextInput) { nextInput.focus(); } }); });
你原有的CSS和HTML逻辑不需要做任何修改,可以直接兼容:
.input:not(:focus):not(:placeholder-shown):valid ~ .remove { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <input class="input" pattern="(1)" placeholder=" "> <input> <input> <input class="remove"> <br> <input> <input> <input> <input>
性能优化版方案
如果页面上输入框数量过百,担心每次按键查询DOM有性能损耗,可以保留初始化时的全量输入框缓存,跳转时向后遍历找到第一个可见的输入框即可,效果和上面的方案完全一致:
$(document).ready(function() { // 初始化时缓存所有文本输入框 const allInputs = $(":text"); allInputs.on("keyup", function(e) { if (e.key !== "Enter") return; e.preventDefault(); let currentIdx = allInputs.index(this); let nextInput = null; // 从当前位置向后遍历,找到第一个可见的输入框 while (currentIdx < allInputs.length - 1) { const target = allInputs.get(++currentIdx); if ($(target).is(':visible')) { nextInput = target; break; } } if (nextInput) { nextInput.focus(); } }); });
两种方案都会自动跳过所有被
display:none隐藏的输入框,不需要调整你现有的业务隐藏逻辑。
内容的提问来源于stack exchange,提问作者d50org
相关产品推荐
相关产品推荐

