如何检查字段集中的任何表单元素是否具有焦点

How to check if any form element inside a fieldset has focus

我想通过验证字段集中的所有元素来部分验证表单。

作为该验证的触发器,我正在收听 focusout 事件,这些事件会冒泡到每个字段集。

如果该字段集中没有表单元素具有 :focus

,我想执行验证

我试过这样做:

const fieldsets = [...document.querySelectorAll('fieldset')]

for (const fieldset of fieldsets) {
  fieldset.addEventListener('focusout', (e) => {
    let focussedElements = e.currentTarget.querySelectorAll(':focus');
    if (focussedElements.length === 0) {
      console.log(`no element inside fieldset #${e.currentTarget.id} has focus`)
    } else if (focussedElements.length > 0) {
      console.log(`element ${focussedElements[0]} inside fieldset #${e.currentTarget.id} has focus`)
    }
  })
}
<fieldset id="fs1">
  <legend>Fieldset 1</legend>
  <input type="text">
  <input type="text">
</fieldset>

<fieldset id="fs2">
  <legend>Fieldset 2</legend>
  <input type="text">
  <select>
    <option>1</option>
    <option>2</option>
  </select>
</fieldset>

但是 e.currentTarget.querySelectorAll(':focus') 总是有 length0

如何可靠地检查 fieldset 是否有一个包含 :focus 的子元素?

注意:我不想使用 jQuery 或任何其他库来完成任务。

难道你只需要等待对新元素的关注发生吗?像这样:

const fieldsets = [...document.querySelectorAll('fieldset')]

for (const fieldset of fieldsets) {
  fieldset.addEventListener('focusout', (e) => {
    let ct = e.currentTarget;
    setTimeout(() => {
      let focussedElements = ct.querySelectorAll(':focus');
      if (focussedElements.length === 0) {
        console.log(`no element inside fieldset #${ct.id} has focus`)
      } else if (focussedElements.length > 0) {
        console.log(`element ${focussedElements[0]} inside fieldset #${ct.id} has focus`)
      }
    }, 10)
  })
}
<fieldset id="fs1">
  <legend>Fieldset 1</legend>
  <input type="text">
  <input type="text">
</fieldset>

<fieldset id="fs2">
  <legend>Fieldset 2</legend>
  <input type="text">
  <select>
    <option>1</option>
    <option>2</option>
  </select>
</fieldset>