如何为包含输入框的div实现blur事件委托?
如何实现blur事件委托完成输入框校验
要实现你需要的功能,核心问题在于blur事件本身不支持冒泡,所以直接在父div上监听blur事件不会触发子元素input的blur行为。给div加tabindex="0"后触发的是div自身的blur,自然拿不到对应的input。这里有两种可靠的解决方法:
方法1:使用focusout事件(推荐)
focusout是blur的冒泡版事件,它会随着DOM树向上传播,父元素可以监听到子元素的焦点丢失行为。直接给div绑定这个事件就能拿到对应的input目标:
<div class="number-inputs"> <input type="number" min="0" max="100" placeholder="0-100"> <input type="number" min="10" max="50" placeholder="10-50"> <!-- 更多数值输入框 --> </div>
const container = document.querySelector('.number-inputs'); container.addEventListener('focusout', function(e) { const target = e.target; // 只处理数值类型的input if (target.tagName !== 'INPUT' || target.type !== 'number') return; const min = Number(target.min); const max = Number(target.max); let inputValue = Number(target.value); // 校验并修正值 if (inputValue < min) { target.value = min; showError(target, `值不能小于${min}`); } else if (inputValue > max) { target.value = max; showError(target, `值不能大于${max}`); } else { clearError(target); } }); // 显示错误提示的辅助函数 function showError(input, msg) { let errorEl = input.nextElementSibling; if (!errorEl || !errorEl.classList.contains('input-error')) { errorEl = document.createElement('span'); errorEl.classList.add('input-error'); input.parentNode.appendChild(errorEl); } errorEl.textContent = msg; } // 清除错误提示的辅助函数 function clearError(input) { const errorEl = input.nextElementSibling; if (errorEl?.classList.contains('input-error')) { errorEl.remove(); } }
方法2:在捕获阶段监听blur事件
虽然blur不冒泡,但它会在事件捕获阶段向上传播。给addEventListener的第三个参数设为true,就能在捕获阶段监听到子元素的blur事件:
const container = document.querySelector('.number-inputs'); // 第三个参数true表示开启捕获阶段监听 container.addEventListener('blur', function(e) { const target = e.target; if (target.tagName !== 'INPUT' || target.type !== 'number') return; // 以下校验逻辑和方法1完全一致 const min = Number(target.min); const max = Number(target.max); let inputValue = Number(target.value); if (inputValue < min) { target.value = min; showError(target, `值不能小于${min}`); } else if (inputValue > max) { target.value = max; showError(target, `值不能大于${max}`); } else { clearError(target); } }, true);
为什么之前的方法无效?
- 直接给div绑blur:blur事件不冒泡,子元素的blur不会触发父元素的事件回调。
- 给div加
tabindex="0":此时div获得了焦点能力,触发的是div自身的blur事件,而非input的,所以e.target始终是div。
内容的提问来源于stack exchange,提问作者EzioMercer
相关产品推荐
相关产品推荐

