在change事件监听器中判断触发源?点击密码图标时避免校验
解决密码框切换显示时触发不必要校验的问题
方案1:通过relatedTarget判断触发源
在input的change事件处理中,检查事件的relatedTarget是否为密码显示/隐藏图标,若是则跳过校验。修改事件委托代码:
const delegate = (selector) => (cb) => (e) => e.target.matches(selector) && cb(e); const inputDelegate = delegate('input'); forminputs.addEventListener('change', inputDelegate((e) => { // 判断是否为点击眼睛图标触发的change事件 const isEyeIconTrigger = e.relatedTarget?.id === 'eye'; if (!isEyeIconTrigger) { checkEntry(e.target); } }));
原理:点击眼睛图标时,input失去焦点触发change事件,此时e.relatedTarget会指向被点击的图标元素,通过ID判断即可跳过不必要的校验。
方案2:阻止图标点击时input失去焦点
利用mousedown事件的默认行为控制,mousedown触发时机早于change,阻止其默认行为可让input保持焦点,从根源上避免change事件触发。修改图标事件绑定:
<i class="fa-solid fa-eye" id="eye"></i>
document.getElementById('eye').addEventListener('mousedown', (e) => { e.preventDefault(); // 阻止默认行为,避免input失去焦点 showHide.call(e.target); // 手动调用显示/隐藏逻辑 });
保留原有showHide函数即可。
方案3:添加校验标记跳过检查
在切换密码显示状态时给input加临时标记,change事件中检测到标记则跳过校验,之后移除标记:
修改showHide函数:
function showHide(){ this.classList.toggle("fa-eye-slash"); const passwordField = document.getElementById('password'); passwordField.dataset.skipValidation = 'true'; // 添加校验跳过标记 const type = passwordField.getAttribute("type") === "password" ? "text" : "password"; passwordField.setAttribute("type", type); // 异步移除标记,不影响后续正常校验 setTimeout(() => delete passwordField.dataset.skipValidation, 0); }
修改change事件处理:
forminputs.addEventListener('change', inputDelegate((e) => { if (!e.target.dataset.skipValidation) { checkEntry(e.target); } }));
内容的提问来源于stack exchange,提问作者John Pankowicz
相关产品推荐
相关产品推荐

