【问题标题】:Setting an element's focus only if user has tabbed to it仅当用户使用选项卡时才设置元素的焦点
【发布时间】:2020-06-02 16:36:52
【问题描述】:

我正在尝试使我的网站上的一些可折叠手风琴容器可访问,但我遇到了问题。

手风琴由页面上的链接元素控制 - 这样,只有键盘的用户可以通过 Tab 键访问它们并访问它们。我遇到的第一个问题是,如果用户切换到其中一个链接,页面不会总是向上滚动以显示他们切换到哪个链接。我使用以下代码修复了设置焦点的问题,该代码将链接滚动到视口顶部:

$(".accordion .accordion-item .accordion-heading a").focus(
    function()
    {
        $('html:not(:animated), body:not(:animated)').animate({
            scrollTop: $(this).offset().top
        }, 250);
    }
    );

我现在遇到的问题是,当鼠标用户单击链接时,它会跳转到页面顶部并且不会打开容器,除非鼠标用户再次单击该链接。

有没有办法可以将上面的焦点代码设置为仅在链接已被选项卡到时触发?或者,是否有更好的方法来处理焦点问题,使其适用于仅键盘用户和鼠标用户?

谢谢!

【问题讨论】:

  • 尚不完全清楚您的问题到底是什么。你能添加一个显示问题的sn-p吗? “我遇到的第一个问题是,如果用户选择了其中一个链接,页面不会总是向上滚动以显示他们选择了哪个链接。” > 滚动到焦点元素(是否使用 tab 键)是 AFAIK 浏览器的默认功能。
  • 正如 Laurent 所说,不清楚是什么导致了您的问题或您试图描述的确切行为,您能否提供一个演示问题的小提琴或指向有问题的页面的链接.听起来您在手风琴上使用的任何功能都无法正常工作。此外,手风琴不应该是链接,它们应该是正确语义的按钮(除非您在单独的页面上仅提供指向手风琴内文本的链接)。
  • 另外,如果您正在拦截滚动,请不要对其进行动画处理,这会影响患有焦虑症/运动障碍的人(或确保它可以被禁用,或者您使用prefers-reduce-motion 媒体查询)
  • @LaurentS。 - 这是页面测试版本的链接:williamwoods.edu/test/gallery-index.html 如果您向下滚动到以前举办的活动并单击“2019-2020”,您会注意到页面向上滚动,将该链接设置在顶部页。然后,您必须再次单击它才能打开它。谢谢!
  • 请不要链接到页面,请在您的问题中添加minimal, reproducable example。链接变得过时了,尤其是当您解决了问题时,链接将不再与您的问题相关,并且 SO 的目标是您的问题将来可以帮助其他人,过时不是一件好事。

标签: javascript jquery html accessibility keyboard-events


【解决方案1】:

首先快速道歉,现在已经看到您的手风琴已正确构建,如果手风琴是在页面加载时使用 javascript 构建并回退到页面内锚链接和内容的列表,则实际上更可取的是带有页面内锚的链接他们之间。

我习惯于在手风琴开瓶器上看到<a href="#"> 和奇怪的手风琴实现我草草下结论,把它从<buttons> 改回来!

解决您的问题

可能不是您正在寻找的答案,但请完全删除 .focus() 函数。

它会产生奇怪的行为,如果我打开了一个手风琴项目并且我使用 Alt + Tab 快速滚动可能会非常混乱,因为如果你使用 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.
        }
    }
);

这解决了您的问题,因为鼠标用户将永远无法单击页面外的项目,因此他们将永远不会触发导致焦点问题的滚动事件。

【讨论】:

    【解决方案2】:

    您可以更改事件设置:取而代之的是 focus() 事件,您将执行 click() 事件:当您单击链接时,您将向上滚动。这将解决键盘导航和鼠标点击的问题;在可访问性方面也更是如此。

    $(".accordion .accordion-item .accordion-heading a").click(
    function(e)
    {
        e.preventDefault();
        $('html:not(:animated), body:not(:animated)').animate({
            scrollTop: $(this).offset().top
        }, 250);
    }
    );
    

    不要忘记通过添加 role=button 属性将链接设置更改为按钮。 并添加 aria-expanded 属性。

    【讨论】:

    • 他正在使用 focus 事件来让一个项目滚动到屏幕外的视图中,当它获得焦点时,他不能为此使用 click 事件 -> “The我遇到的第一个问题是,如果用户切换到其中一个链接,页面不会总是向上滚动以向他们显示他们切换到哪个链接。我使用以下代码修复了这个问题,它会滚动链接到视口顶部”
    • 访问键盘导航的正确方法是让用户通过点击而不是焦点来打开手风琴,否则会混淆用户
    • 重新阅读问题、我的回答和我的评论,你误会了。 .focus 不用于打开手风琴,它是将页面外的内容滚动到视图中。他的问题是当你click focus 事件在他不想要的时候被触发。
    • @GrahamRitchie 是正确的 - 我不希望它在用户点击它时滚动,我希望它在键盘用户点击它时滚动到焦点。 :) 但是,问题是 .focus 位在鼠标用户悬停在按钮上时使按钮“跳”到页面顶部,迫使他们将光标移回按钮上并再次单击以打开手风琴。我现在的计划只是将滚动功能全部删除——如果它在没有该代码的情况下所做的是预期行为。稍后我可能会尝试使用 isInViewport 功能。谢谢各位的帮助! :)
    • 我已将@GrahamRitchie 的答案标记为答案,因为这是我最终选择的答案。 isInViewport 函数工作得很好,但我无法让它触发其中的滚动函数。不过,当我测试它时,它会发出警报,所以我的设置一定有一些奇怪的地方。无论如何,我只是决定暂时禁用它,因为这是预期的行为。再次感谢大家的帮助! :D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-22
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-27
    相关资源
    最近更新 更多