模糊事件流和 DOM 更新同步

问题描述 投票:0回答:1

当我专注于输入然后单击删除按钮时,以下代码具有此行为:

  1. Mousedown回调函数被触发,但输入并没有立即模糊,原因是

    ev.preventDefault()

  2. 容器被(至少应该是)mousedown 函数删除。

  3. 然后触发模糊回调函数,因为容器的移除导致输入失去焦点

  4. 它在控制台中打印容器元素,即使我期待的是 null。不是被mousedown回调函数去掉了吗?

  5. 然后(以我的理解)删除由于某种原因未被 mousedown 函数删除的容器元素。

  6. mousedown 函数找不到要删除的元素,因此抛出 DOMException。

我不确定这个过程是否完全像我描述的那样发生。如果我注释掉模糊函数中的

container.remove
行,首先该元素将由模糊函数打印在控制台中,然后“null”将由 mousedown 函数打印。

我无法理解在 mousedown 之前如何调用模糊函数。为了调用模糊函数,必须删除容器。那么,blur 函数如何在 DOM 中再次找到它,如果它已经被删除了,又如何将其删除呢?

const inp = document.querySelector("input");
const container = document.querySelector("#container");
const btn = document.querySelector("button");

btn.addEventListener("mousedown", (ev) => {
  ev.preventDefault();
  console.log('Before remove',document.querySelector("#container"));  
  container.remove();
  console.log('After remove',document.querySelector("#container"));
});

inp.addEventListener("blur", () => {
  console.log('In blur',document.querySelector("#container"));
  container.remove();
});
<div id="container">
  <input />
  <button>Delete</button>
</div>

javascript html dom
1个回答
0
投票

我添加了一些

try-catch
语句,以便您更容易理解发生的情况。该错误显然是在
mousedown
处理程序中引发的,因为
blur
处理程序是在
container.remove()
处理程序内的
mousedown
行之前执行的。

因此,“流程”是:

  1. mousedown
    在按钮上触发
  2. ev.preventDefault()
    在 mousedown 处理程序中调用
  3. console.log('Before remove', /* elided */)
    在 mousedown 处理程序中执行
  4. blur
    输入时触发
  5. console.log('In blur', /* elided */)
    在模糊处理程序中执行
  6. container.remove()
    在模糊处理程序中执行
  7. container.remove()
    在 mousedown 处理程序中执行(由于容器已被删除而失败)

为了完整起见,我向按钮添加了一个

focus
侦听器,只是为了确保捕获所有相关步骤。然而,
focus
永远不会被执行。

我只在 Chrome Stable 127.0 中检查过这一点,所以也许其他浏览器 表现不同(尽管我对此表示怀疑)。

const inp = document.querySelector("input");
const container = document.querySelector("#container");
const btn = document.querySelector("button");

btn.addEventListener("mousedown", (ev) => {
  ev.preventDefault();
  console.log('Before remove',document.querySelector("#container"));
  try {
    container.remove();
  } catch (exc) {
    console.log('Error in mousedown', exc);
  }
  console.log('After remove',document.querySelector("#container"));
});

btn.addEventListener('focus', () => {
  console.log('Button has focus now');
});

inp.addEventListener("blur", () => {
  console.log('In blur',document.querySelector("#container"));
  try {
    container.remove();
  } catch (exc) {
    console.log('Error in blur', exc);
  }
});
<div id="container">
  <input />
  <button>Delete</button>
</div>

© www.soinside.com 2019 - 2024. All rights reserved.