使用Tab键将焦点从数据网格移至下一页元素

时间:2018-07-27 15:49:35

标签: javascript reactjs accessibility ag-grid wcag2.0

使用AG-Grid,我需要能够按下Tab键并使焦点元素从当前选定的网格/单元更改为网格外部页面上的下一个元素。问题在于,Tab键似乎已锁定在网格内,并且不会移到数据表之外到下一个元素。

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

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)
    }
  })
})

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

以下是指向当前网格的plnkr链接:Link

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

更新

我已经更新了代码,现在不是在每个单元格上附加事件侦听器,而是在寻找文档中触发的事件。但是,我仍然遇到一个问题,即它没有获得last_cell的值,而没有看到focus-visible上的hasFocusVisible类。

//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();
  }
});

但是,注销具有焦点可见类的div时,hasFocusVisible变量总是出现false。我不确定自己的逻辑是否不正确,或者在触发事件侦听器时无法在focus-visible上获取ag-header-cell-label类。

1 个答案:

答案 0 :(得分:0)

如果选项卡在单元格中起作用,则不要在每个单元格中添加一个侦听器,只需在文档中添加一个,然后手动将焦点移到页面上的下一个即可。例如:

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>

运行此代码段,单击按钮,单击选项卡,请注意,现在已捕获了选项卡事件(就像在单元格中一样)。现在,再次单击该按钮,依次单击选项卡,再次单击选项卡:似乎注意它,就像事件不再被捕获一样,而实际上它是:元素本身的事件被杀死了,但是现在,文档的事件监听器为我们明确转移了焦点。