html - 带有溢出自动的 Div 在 Chrome 中不能以选项卡为焦点
问题描述
我有两个具有最大高度和溢出自动的 div。一个 div 不会溢出,而另一个会溢出。可滚动的 div 可以用键盘滚动,但 Firefox 和 Chrome 的行为不同:
- Firefox:即使我没有在其上指定选项卡索引,可滚动 div 也是选项卡可聚焦的。不可滚动的 div 无法聚焦。这是我想要的一个很好的默认行为。
- Chrome:除非我添加
tabindex="0"
强制它,否则可滚动的 div 不能以标签为中心。在我的用例中,每个 div 的内容都是用户生成的,我不知道它是否会溢出,所以我不能只应用tabindex="0"
到所有 div,因为它会使不可滚动的 div 成为我不想要的焦点。
请注意,如果您先单击 div 然后按向上/向下箭头,Chrome 允许滚动可滚动的 div,但这实际上并没有聚焦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>
推荐阅读
- react-native - 是否有可能知道在 react-native 中按下了哪个元素?
- google-chrome - Chrome 相当于 MozillaWindowClass
- c++ - 查找向量中元素的索引并将其删除
- r - 使用 igraph 在 R 中绘制具有坐标的节点
- python - pybind11 和 blitz 阵列
- chainlink - setPublicChainlinkToken 是如何工作的,如果这个函数没有感知当前链环境怎么办?
- arrays - 如何创建一个数组来存储多个不同的 malloc 指针?
- mongodb - 一次多次更新MongoDB
- css - 我如何使所有下一个 tr 舍入并在 vuetify 中设置它们之间的边距?
- c# - ASP.NET:除了 Web 应用程序二进制文件之外,如何发布 ocx 文件