【问题标题】:How to check if any form element inside a fieldset has focus如何检查字段集中的任何表单元素是否具有焦点
【发布时间】:2018-08-29 14:19:05
【问题描述】:

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

作为该验证的触发器,我正在监听 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') 总是有lengthof 0

我如何可靠地检查 fieldset 是否具有具有 :focus 的子元素?

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

【问题讨论】:

    标签: javascript validation dom focus focusout


    【解决方案1】:

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

    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>

    【讨论】:

    • 那么这是否意味着focusin 仅在focusout 的所有处理程序都已解析后才会发生?
    • 我不确定是否有保证。但据我了解,focusin 和 focusout 事件已排队,因此 timeout 事件将在它们之后排队等待服务,因此在 timeout 事件处理程序发生时,focusin 处理程序将已运行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    相关资源
    最近更新 更多