使用 Tab 键将焦点从数据网格移动到下一个页面元素

Using tab key to move focus from data grid to next page element

使用 AG-Grid,我需要能够按下 tab 键并将焦点元素从当前选择的 grid/cell 更改为页面上网格外的下一个元素。问题是 Tab 键似乎被锁定在网格内,不会移动到数据 table 之外的下一个元素。

我在存储最后一个聚焦单元格的单元格上有一个均匀的监听器(用于存储最后一个位置以便能够切换回网格到先前聚焦的单元格),但需要有下一个聚焦单元格在数据网格之外:

const cells = document.getElementsByClassName('ag-cell');
[...cells].map(cell => {
  cell.addEventListener("keydown", function(e) {
    if(e.key === "Tab") {
      let lastCell = cell.attributes[2].value;
      console.log("Last Cell Focused: ", lastCell)
    }
  })
})

如何将焦点选择从按键时的网格移至下一个可聚焦页面元素?

这是当前网格的 link plnkr:Link

============================================= ========

更新

我已经更新了我的代码,而不是将事件侦听器附加到每个单元格,它现在正在寻找在文档上触发的事件。但是,我仍然 运行 无法获得 last_cell 值并在 hasFocusVisible.

上看到 focus-visible class
//on arrow right if last_call === header that has 'focus-visible', set focus to first cell in body
const headerCells = document.getElementsByClassName('ag-header-cell-label');
const last_cell = headerCells[headerCells.length-1].attributes[2];
const hasFocusVisible = document.querySelector('.ag-header-cell-label').classList.contains('focus-visible');
document.addEventListener("keydown", function(e) {
  if(e.key === "ArrowRight") {
    // if(hasFocusVisible && last_cell) {
      console.log("EVENT TRIGGERED FROM: ", event.target, "Last Cell Value: ", last_cell, hasFocusVisible);
      //if last_call and 'ag-header-cell-label' has 'focus-visible', set focus to first cell in body
      const bodyCell = document.getElementsByClassName('ag-cell')[0];
    // }
  }
});

更新的 Plnkr:Link

============================================= =======

更新 2

我已将元素选择器更新为以下内容:

const last_cell = document.querySelector('.ag-header-cell:last-child');
const hasFocusVisible = document.querySelector('.ag-header-cell-label').classList.contains('.focus-visible');
document.addEventListener("keydown", function(e) {
  console.log('document.activeElement', document.activeElement)
  const activeElement = document.activeElement;
  if(e.key === "ArrowRight" && activeElement) {
    if(last_cell) {
      console.log("EVENT TRIGGERED FROM: ", event.target, "Last Cell Value: ", last_cell, hasFocusVisible);
      //if last_call and 'ag-header-cell-label' has 'focus-visible', set focus to first cell in body
      const bodyCell = document.getElementsByClassName('ag-cell')[0];
    }
  }
  else if(e.key === "ArrowDown"){
    //look for first child in first row with same id as header and set focus
    document.querySelector('.ag-cell').focus();
  }
});

然而,hasFocusVisible 变量总是在注销 div 时出现 false ,该 div 具有焦点可见 class。我不确定我的逻辑是否不正确,或者当事件侦听器被触发时它无法在 ag-header-cell-label 上获得 focus-visible class。

如果选项卡在单元格内有效,请不要向每个单元格添加侦听器,只需将一个侦听器添加到文档中,然后手动将焦点移至您知道的页面上的下一个内容。例如:

var b = document.querySelector('button');
b.passThrough = true;
b.update = pass => {
  b.passThrough = pass;
  b.textContent = "click me to " + (b.passThrough ? "block" : "allow") + " tabbing";
}
b.addEventListener('click', e => b.update(!b.passThrough));
b.update(b.passThrough);

var focussable = Array.from(
  document.querySelectorAll([
    'button',
    '[href]',
    'input',
    'select',
    'textarea',
    '[tabindex]:not([tabindex="-1"])'
  ].join(','))
);

// let's pretend this is your last cell.
var p = document.querySelector('p');

// make it kill off keydown events, BUT, also have it redirect focus
// to "the next focussable element", so you can see what that code looks like.
p.addEventListener('keydown', e => e.preventDefault());

document.addEventListener('keydown', e => {
  if (b.passThrough && e.target === p) {
    var next = focussable.indexOf(p) + 1;
    focussable[next % focussable.length].focus();
  }
});
<button>toggle</button>
<p tabindex=0>first</p>
<a href="#top">second</a>
<a href="#top">third</a>

运行 这段代码,单击按钮,点击选项卡,注意选项卡事件现在被捕获(就像在您的单元格中一样)。现在,再次单击该按钮,点击 tab,再次点击 tab:注意它 似乎 事件不再被困,而事实是:元素本身的事件正在被杀死关闭,但是 document 的事件侦听器现在明确地为我们移动了焦点。