首页 > 解决方案 > 如何验证元素的祖先是否包含某种类型?

问题描述

在我的应用程序中,我想知道我单击的元素(或元素的父级,或祖父母,或祖父母)是否具有某种类型(例如button),以便触发副作用没有我要找的类型。

例如,如果我单击嵌入在 a 中的元素svg,该元素嵌入span在 a 中button,则检查器函数将返回“true”,因为该svg元素的祖先类型为button

到目前为止,我在isParentFocusable函数中进行了以下检查:

private isFocusable(el: HTMLElement) {
  if (!el) {
    return false;
  }
  if (el.getAttribute('focusable')) {
    return true;
  }

  let types = ['input', 'textarea', 'button', 'select', 'a', 'menuitem'];
  return (
    this.verifyRoleOrTagName(el, types) ||
    this.isParentFocusable(el, types)
  );
}

private verifyRoleOrTagName = (element: HTMLElement, types: string[]) => {
  return (
    types.includes(element.tagName.toLocaleLowerCase()) ||
    types.includes(element.getAttribute('role') || '')
  );
};

private isParentFocusable(el: HTMLElement, types: string[]) {
  let currentElement: HTMLElement | null | undefined = el;
  // The upmost level to check for the parent is set to 3;
  // we don't want to check all the parents up to the body tag
  const MAX_PARENT_LEVEL = 3;
  for (let i = 0; i < MAX_PARENT_LEVEL && currentElement; i++) {
    currentElement = currentElement.parentElement;
    if (currentElement && this.verifyRoleOrTagName(currentElement, types)) {
      return true;
    }
  }

  return false;
}

是否有一种优雅的方式或已知的方法来检查单击的元素是否嵌入到某种类型的标签中?types(这里,类型在数组中列出)。

标签: javascripthtmlreactjstypescript

解决方案


您可以使用该closest方法来做到这一点。它找到与 CSS 选择器匹配的最接近的元素,从调用它的元素开始,然后到父元素,等等。

const button = theElement.closest("button");

这是一个例子:

function clickHandler(event) {
    const button = event.target.closest("button");
    console.log(`Found button? ${button ? "Yes" : "No"}`);
}

for (const span of document.querySelectorAll("span")) {
    span.addEventListener("click", clickHandler);
}
<button type="button">
    <span>Click me</span>
</button>
<div>
    <span>And click me</span>
</div>


推荐阅读