使用支持 Shadow DOM 的纯 JavaScript 模拟 Tab 键按下

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

注意: here 和其他地方都存在现有问题,但它们都是特定于 jQuery 的,并且没有涵盖纯 JavaScript 的规范答案,包括对 Web 组件的支持。

我想模拟按 Tab 键,以便焦点转移到 Tab 键顺序中的下一个元素。下一个元素可以是任何可聚焦的 HTML 元素或带有

tabindex="0"
的元素。这也需要在某些后代 HTML 元素可能是带有影子 DOM 的自定义 Web 组件的情况下工作。

潜在的解决方案可能是触发按键事件或迭代后代节点以寻找可聚焦的节点。

javascript web-component shadow-dom tabindex focusable
1个回答
3
投票

我尝试让键盘事件正常工作,但遗憾的是我无法让它正常工作。根据文档,我相信正确的方法是:

document.activeElement.dispatchEvent(new KeyboardEvent("keypress", { 
    key: "Tab" 
}));
// -----------------------------------------------------
// Find all the elements that have a tabindex set, 
// I would keep this file scoped for performance sake
// ------------------------------------------------------
const tabElements = Array.from(document
    // Get all elements that can be focusable
  .querySelectorAll('a, button, input, textarea, select, details, [tabindex]'))
  
  // remove any that have a tabIndex of -1
  .filter(element => element.tabIndex > -1)
  
  // split elements into two arrays, explicit tabIndexs and implicit ones
  .reduce((prev, next) => {  
      return next.tabIndex > 0
        ? [[...prev[0], next].sort((a, b) => a.tabIndex > b.tabIndex ? -1 : 1), prev[1]]
        : [prev[0], [...prev[1], next]];
      }, [[], []])
      
  // flatten the two-dimensional array
    .flatMap(element => element);

然后选择下一个元素:

// ------------------------------------------------------------------------------
// Method to find the next element to focus and change the focus to that element
// ------------------------------------------------------------------------------
const DispatchTab = () => {

    // If the current focused element is a -1 then we wont find the index in the elements list, got to the start
    if (document.activeElement.tabIndex === -1) {
    tabElements[0].focus();
    return;
  }

    // find the current index in the tab list of the currently focused element
    const currentIndex = tabElements.findIndex(e => e === document.activeElement);

  // get the next element in the list ("%" will loop the index around to 0)
  const nextIndex = (currentIndex + 1) % tabElements.length;
  tabElements[nextIndex].focus();
}

我创建了一个 JS 小提琴,其方法根本不使用 KeyboardEvent。它可能需要根据您的喜好进行调整,但应该可以完成工作。我觉得选项卡示例

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