触发 input 的 blur 回调函数并动态添加DOM元素,可能会导致 button 的 click 函数不触发。
ezgif-3-fda2e047c9.gif操作步骤:
- 1、input 聚焦
- 2、点击按钮
代码展示
<div id="targetDiv"></div>
<input type="text" id="myInput">
<button id="myButton">按钮</button>
DOM结构很简单, 我们看一下 js 代码
var input = document.getElementById("myInput");
var targetDiv = document.getElementById("targetDiv");
var button = document.getElementById("myButton");
// 绑定blur事件处理函数
input.addEventListener("blur", function() {
// 创建新的复杂DOM结构
var container = document.createElement("div");
container.classList.add("container");
var wrapper = document.createElement("div");
wrapper.classList.add("wrapper");
var section = document.createElement("section");
section.classList.add("section");
var header = document.createElement("h2");
header.textContent = "New Content";
var paragraph = document.createElement("p");
paragraph.textContent = input.value;
section.appendChild(header);
section.appendChild(paragraph);
wrapper.appendChild(section);
container.appendChild(wrapper);
// 将新的复杂DOM结构追加到目标div中
targetDiv.appendChild(container);
});
// 添加点击事件处理函数
button.addEventListener("click", function() {
console.log("Button clicked!");
});
1、结论分析:blur 事件优先级高于 click 函数触发,当 blur 回调函数内做了DOM的更新,引起了重绘,从而导致 ‘按钮’ 的位置发生改变,鼠标点上去的时候 点的那个位置已经没有按钮DOM存在了,所以 click 事件失效了
看到很多文章中提到类似的问题,单一的解释js是单线程, blur事件触发导致click事件未触发。这类的结论描述可能会给人产生误导。所以这里有必要给大家演示一下,并非js事件顺序执行导致的该现象。当我在代码中把 targetDiv 这个DOM节点放到Button下边,那一切的表现都是正常的 blur可以触发, 按钮的click事件也可以触发。从而证明了 ‘js是单线程, blur事件触发导致click事件未触发’ 该观点的错误性
2、论证:论证该结论的正确性
ezgif-5-1f64438be1.gif在代码中添加已click的监听事件, 看一下当我们点击按钮的时候 实际点击的target是什么?
通过结果表现来看,当 blur 触发后,实际点击的位置并非 ‘按钮’ 而是body。从而论证 当点击的时候 按钮DOM的位置依然发生变化
3、解决方案:
- 将 blur 回调函数延迟触发 包一层setTimeout
- 将按钮的 click 事件替换成 onMouseDown
网友评论