javascript - 仅当用户使用选项卡时才设置元素的焦点
问题描述
我试图在我的网站上制作一些可折叠的手风琴容器,但我遇到了一个问题。
手风琴由页面上的链接元素控制——这样,只有键盘的用户可以通过 Tab 键访问它们并访问它们。我遇到的第一个问题是,如果用户切换到其中一个链接,页面不会总是向上滚动以显示他们切换到了哪个链接。我修复了使用以下代码设置焦点的问题,该代码将链接滚动到视口顶部:
$(".accordion .accordion-item .accordion-heading a").focus(
function()
{
$('html:not(:animated), body:not(:animated)').animate({
scrollTop: $(this).offset().top
}, 250);
}
);
我现在遇到的问题是,当鼠标用户单击链接时,它会跳转到页面顶部并且不会打开容器,除非鼠标用户再次单击链接。
有没有办法可以将上面的焦点代码设置为仅在链接已被选项卡到时触发?或者,有没有更好的方法来处理焦点问题,以便它适用于纯键盘和鼠标用户?
谢谢!
解决方案
首先快速道歉,现在已经看到您的手风琴已正确构建,如果手风琴是在页面加载时使用 javascript 构建并回退到页面内锚链接和它们之间的内容的列表,则实际上更可取的是带有页面内锚的链接。
我习惯于<a href="#">
在手风琴开瓶器和奇怪的手风琴实现上看到我得出的结论,把它改回来<buttons>
!
解决您的问题
可能不是您正在寻找的答案,而是.focus()
完全删除该功能。
它会产生奇怪的行为,如果我打开了一个手风琴项目并且我用Alt+Tab快速滚动返回标签可能会非常混乱,因为如果你的标签比滚动快,它会跳来跳去。
可访问性的黄金法则之一是仅在预期的情况下调整页面上的滚动位置(即return to top
按钮或使用页内锚点)。
在示例中和您的网站上,一旦我禁用了“焦点上滚动到顶部”,该网站实际上就按预期运行。
我理解你为什么这样做,因为偶尔会出现一个聚焦的链接出现在页面之外,但是当你再次点击或向下滚动时,这会自行补救(你的网站是合乎逻辑的,所以如果我点击并且我的焦点不可见,我知道它是离开页面。)
这往往会发生(项目没有滚动到视图中),当项目刚刚看不见时,一两个像素,这是很常见的,具有讽刺意味的是现在陷入“预期”行为(另一条规则,在设计组件时遵循公认和预期的行为和页面)。
如果你真的想修复它
在您的focus
函数中,当一个项目获得焦点时,不要只是滚动到页面顶部,而是检查它是否不在页面上。
下面是我发现(未测试)的一个示例函数,您可以使用它来检查项目是否在视口中,如果是则不执行任何操作,如果不是则执行滚动功能。
var isInViewport = function (elem) {
var bounding = elem.getBoundingClientRect();
return (
bounding.top >= 0 &&
bounding.left >= 0 &&
bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
bounding.right <= (window.innerWidth || document.documentElement.clientWidth)
);
};
如此粗略(再次没有测试是否传入了正确的项目,这只是为了给你一个想法)。
$(".accordion .accordion-item .accordion-heading a").focus(
function()
{
if(isInViewport(this) === false){
//item is not in the viewport so scroll it into view
$('html:not(:animated), body:not(:animated)').animate({
scrollTop: $(this).offset().top //I would perhaps add a couple of hundred pixels here to make the item appear in a more natural area.
}, 250); //remove the animation as a further accessibility improvement, animations can be off putting to people with motion or anxiety disorders.
}
}
);
这解决了您的问题,因为没有鼠标用户能够单击页面外的项目,因此他们将永远不会触发导致焦点问题的滚动事件。
推荐阅读
- c# - 将 microsoft.applicationinsights.tracelistener 用于 ASP.Net Core 3.1 应用程序
- javascript - JavaScript 错误未捕获 ReferenceError: setEven 未在 HTMLSpanElement.onclick 中定义
- ios - CAShapeLayer 已添加到视图中,但不在我的按钮周围
- android - 如何打开通知中发送的深层链接?- 反应原生
- xspec - 无法对生成具有嵌套元素的元素的 XSLT 模板规则进行单元测试
- java.util.concurrent - 从 FutureTask.run() 内部调用 get() 时出现死锁而不是异常
- javascript - 如果数组返回子级或子级映射时如何正确替换任何类型
- elasticsearch - 如何配置 Packetbeat 以防止发送预检 http 请求(选项请求)
- python - 如何在 sympy 中简化为求和符号?
- sql - 为 BCP 创建 SQL 查询的字符串格式问题