我有两个带有最大高度和溢出自动的 div。一个 div 不会溢出,而另一个则溢出。可滚动 div 可以使用键盘滚动,但 Firefox 和 Chrome 之间的行为不同:
tabindex="0"
来强制它。在我的用例中,每个 div 的内容都是用户生成的,我不知道它是否会溢出,所以我不能只将 tabindex="0"
应用于所有 div,因为它会使不可滚动的 div 成为焦点,而我不这样做想要。请注意,如果您先单击 div 然后按向上/向下箭头,Chrome 允许滚动可滚动 div,但这实际上并不会 focus div (div 不会变成
document.activeElement
)。 Chrome 似乎会记住最后点击的是哪个元素。这不是我正在寻找的仅键盘解决方案。
基本上我希望 Chrome 在这种情况下能像 Firefox 一样工作。这可能吗?也许 Chrome 中有一个辅助功能设置可以实现此功能(我找不到)。仅使用键盘的用户在 Chrome 中如何处理这种情况?
div {
overflow: auto;
max-height: 50px;
border: 1px solid black;
margin: 10px 0;
}
div:focus {
outline: 2px solid blue;
}
<div>
Text does not overflow, not scrollable and should not receive tab focus.
</div>
<div>
Text overflows and should be tab focusable so that it can be scrolled with the keyboard.<br>
Text overflows and should be tab focusable so that it can be scrolled with the keyboard.<br>
Text overflows and should be tab focusable so that it can be scrolled with the keyboard.<br>
Text overflows and should be tab focusable so that it can be scrolled with the keyboard.
</div>
假设这些用户是仅使用键盘的用户,而不是屏幕阅读器用户(因为他们会使用不同的控件),最简单的方法是使用一点 JavaScript,如果元素有滚动条(垂直和水平),则添加
tabindex="0"
。
只需一行 JavaScript 即可确定元素是否具有垂直或水平滚动条
if(el.scrollWidth > el.clientWidth || el.scrollHeight > el.clientHeight){//scrollable}
我在下面提供了一个示例,如果容器有滚动条,我会在容器上设置
tabindex="0"
。
如果这些 div 的内容可能会发生变化,您可能需要使用突变观察器来监听变化。
我也为您将其包含在下面的示例中。
var els = document.querySelectorAll('.isItScrollable');
//observer setup
var observer = new MutationObserver(mutatedDiv);
var objConfig = {
childList: true,
subtree : true,
attributes: false,
characterData : false
};
//see if the scroll width or height is larger than the client width or height
function isScrollable(el){
if(el.scrollWidth > el.clientWidth || el.scrollHeight > el.clientHeight){
return true;
}
return false;
}
for(var x = 0; x < els.length; x++){
var el = els[x];
//check whether the element is scrollable initially.
if(isScrollable(el)){
el.setAttribute('tabindex', 0);
}
//use an observer to check for a change so we can check if the content updates
observer.observe(el, objConfig);
}
//observer callback function
function mutatedDiv (mutations) {
mutations.forEach(function(mutation) {
if(isScrollable(mutation.target)){
mutation.target.setAttribute('tabindex', 0);
}else{
mutation.target.removeAttribute('tabindex');
}
});
}
////////////not relevant, just for demo
var add1 = document.querySelector('.addone');
add1.addEventListener("click", function(e){
els[0].innerHTML = "Text overflows and should be tab focusable so that it can be scrolled with the keyboard.<br>Text overflows and should be tab focusable so that it can be scrolled with the keyboard.<br> Text overflows and should be tab focusable so that it can be scrolled with the keyboard.<br> Text overflows and should be tab focusable so that it can be scrolled with the keyboard.";
});
var remove1 = document.querySelector('.removeone');
remove1.addEventListener("click", function(e){
els[0].innerHTML = "Text does not overflow, not scrollable and should not receive tab focus."
});
var add2 = document.querySelector('.addtwo');
add2.addEventListener("click", function(e){
els[1].innerHTML = "Text overflows and should be tab focusable so that it can be scrolled with the keyboard.<br>Text overflows and should be tab focusable so that it can be scrolled with the keyboard.<br> Text overflows and should be tab focusable so that it can be scrolled with the keyboard.<br> Text overflows and should be tab focusable so that it can be scrolled with the keyboard.";
});
var remove2 = document.querySelector('.removetwo');
remove2.addEventListener("click", function(e){
els[1].innerHTML = "Text does not overflow, not scrollable and should not receive tab focus."
});
.isItScrollable {
overflow: auto;
max-height: 50px;
border: 1px solid black;
margin: 10px 0;
}
.isItScrollable:focus {
outline: 2px solid blue;
}
<div class="isItScrollable">
Text does not overflow, not scrollable and should not receive tab focus.
</div>
<div class="isItScrollable">
Text overflows and should be tab focusable so that it can be scrolled with the keyboard.<br>
Text overflows and should be tab focusable so that it can be scrolled with the keyboard.<br>
Text overflows and should be tab focusable so that it can be scrolled with the keyboard.<br>
Text overflows and should be tab focusable so that it can be scrolled with the keyboard.
</div>
<button class="addone">Add Text Div One</button>
<button class="removeone">Reset Text Div One</button>
<button class="addtwo">Add Text Div Two</button>
<button class="removetwo">Remove Text Div Two</button>
Chrome 中的
KeyboardFocusableScrollers
功能最近切换为 experimental
状态。这应该使某些可滚动容器可以根据需要进行选项卡聚焦。另请参阅其 chromestatus 页面。可能很快就可以通过功能标志打开此功能。