javascript - "Skip Navigation"没有 anchor 的链接

标签 javascript jquery html accessibility

我正在尝试创建一个“跳过导航”链接,但无法使用 anchor 。该站点以一种特殊的方式构建,其中 anchor 链接格式已重新设计。所以,我试图让人们通过使用焦点来跳过导航。但是,它不起作用。

跳过导航链接本身的 HTML 代码:

<!-- Start Top Left in Nav Bar -->
<aside>
<a href="" onClick="javascript:skipNav()" tabindex="1" id="skipNav" role="link">Skip Navigation</a>
</aside>
<!-- End Top Left in Nav Bar -->

改变焦点的代码

var nav = document.getElementById('#skipNav');
nav.onclick=skipNav();

function skipNav(){
     document.activeElement.blur();

    if ($('#linkHome').hasClass('current')==true)
    {
        $('#homeFocus').focus();
    }
    if ($('#linkTeam').hasClass('current')==true)
    {
        $('#teamFocus').focus();
    }
    if ($('#linkTraining').hasClass('current')==true)
    {
        $('#trainingFocus').focus();
    }
    if ($('#linkTesting').hasClass('current')==true)
    {
        $('#testingFocus').focus();
    }
    if ($('#linkRemediation').hasClass('current')==true)
    {
        $('#remediationFocus').focus();
    }
    if ($('#linkContact').hasClass('current')==true)
    {
        $('#contactFocus').focus();
    }

};

更改页面和标记当前页面的脚本

var FluidNav = {
init: function() {
    $('a[href*="#"]').click(function(e) {
        e.preventDefault();
        if($(this).attr("href").split("#")[1]) {
            FluidNav.goTo($(this).attr("href").split("#")[1]);
        }
    });
    this.goTo("home");
},
goTo: function(page) {
    var next_page = $("#"+page);
    var nav_item = $('nav ul li a[href=#'+page+']');
    $("nav ul li").removeClass("current");
    nav_item.parent().addClass("current");
    FluidNav.resizePage((next_page.height() + 40), true, function() {
         $(".page").removeClass("current"); next_page.addClass("current"); 
    });
    $(".page").fadeOut(500);
    next_page.fadeIn(500);
    document.activeElement.blur();
    $('#'+page+'Focus').focus();

    FluidNav.centerArrow(nav_item);

},
centerArrow: function(nav_item, animate) {
    var left_margin = (nav_item.parent().position().left + nav_item.parent().width()) + 24 - (nav_item.parent().width() / 2);
    if(animate != false) {
        $("nav .arrow").animate({
            left: left_margin - 8
        }, 500, function() { $(this).show(); });
    } else {
        $("nav .arrow").css({ left: left_margin - 8 });
    }
},
resizePage: function(size, animate, callback) {
    if(size) { var new_size = size; } else { var new_size = $(".page.current").height() + 40; }
    if(!callback) { callback = function(){}; }
    if(animate) {
        $("#pages").animate({ height: new_size }, 400, function() { callback.call(); }); 
    } else {
        $("#pages").css({ height: new_size }); 
    }
}
};

 $("nav select").change(function() {
    if(this.options[this.selectedIndex].value != "#") {
        var page = this.options[this.selectedIndex].value.split("#")[1];
        FluidNav.goTo(page);
        $("html,body").animate({ scrollTop:$('#'+page).offset().top }, 700);
    }
});

有什么想法吗?

最佳答案

听起来您正在尝试做一个“动态跳过链接”,您在其中确定运行时的目标?

<a href="" onClick="javascript:skipNav()" tabindex="1" id="skipNav" role="link">Skip Navigation</a>

问题是,当您单击链接时,会发生导航。 href="" 不会阻止导航,它只是意味着您最终导航到当前页面 - 这将重置焦点。这发生在您的点击事件处理程序之后。因此,即使您可以正确地将焦点设置在您想要的位置,它最终也会在页面重新加载时“丢失”。

有几种方法可以防止这种情况发生:一种是使用 href="javascript:void(0)" - href 指定要导航的位置,如果它计算结果为 void,浏览器根本不会导航。

一种更简洁的方法是告诉浏览器不要执行事件处理程序中的默认操作:

function skipNav(e)
{
    e.preventDefault(); // prevent default action - link navigation - from taking place
    ...

--

代码的其他几个问题:

不要为 A 上的 role="link" 而烦恼 - 保存这些属性以备不时之需。要知道的关键是屏幕阅读器已经知道如何处理所有以标准方式使用的标准 HTML 元素。因此,如果您使用 as 链接或 as 按钮,则无需添加 Angular 色。

但是,如果您正在创建普通 DIV 的新控件,或者如果您正在将 HTML 元素重新用于不同的用途,那么您需要一个 Angular 色属性来告诉屏幕阅读器您实际上使用元素。

例如,有一个 onclick 处理程序并且表现得像一个按钮的 DIV 需要 role="button",否则屏幕阅读器可能会忽略它或者只是说一些通用的东西,比如“元素”。或者,如果您从 A 标签创建一个按钮,并且从用户的 Angular 来看它最终表现得像一个按钮,那么您需要 role="button"以便屏幕阅读器将其宣布为一个按钮而不是链接。

--

注意混合普通 DOM 和 jQuery 约定——只有 jQuery 使用 # 通过 ID 查找元素,所以使用其中之一:

var nav = document.getElementById('skipNav'); // plain DOM way, no #

var nav = $('#skipnav'); // jQuery way using selector

--

观察作为值的函数与调用:

nav.onclick=skipNav();

这实际上将调用 skipNav(),并分配返回值 - null! - 点击。设置回调时不要使用 ()。无论如何您都不需要此代码,因为无论如何您都在标记中使用 onClick 设置处理程序。

另外,请注意,就您的代码而言,当调用 skipNav() 时,它会尝试调用 document.activeElement.blur() - 但在那个时间点 - 文档仍在加载 - 没有 activeElement,因此调用 blur () 在 null 上生成异常 - 您应该在浏览器的控制台/调试窗口中看到。

--

不要使用 .blur() - 没有必要这样做:

 document.activeElement.blur();

相反,只需聚焦您想要聚焦的元素。执行 .blur() 的危险在于,如果它之后的代码无法将焦点设置在合理的位置,焦点将最终“丢失”,这对键盘用户来说非常不方便,因为他们必须从一开始就使用 Tab 键页面。

--

Javascript 编码实践:不要为 if() 表达式中的 == true 而烦恼;并且除非您期望不止一个元素具有“当前”类,否则请使用 else if 而不是普通的 if:这在代码中清楚地表明您期望只使用一个分支。

--

最后,与浏览器的调试器(大多数情况下为 F12)交 friend :您将通过在事件处理程序和初始化代码中放置断点来学习上述一些内容,并单步执行它以确保它的行为符合您的预期。

关于javascript - "Skip Navigation"没有 anchor 的链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10987575/

相关文章:

javascript - html2canvas() 中的屏幕截图是在哪里制作的?

JQuery css() 选择器从类中设置背景颜色

javascript - 为什么附加元素而不是可拖动的?

javascript - Console.log = null 对于我手动设置的值

javascript - jQuery 将数据从 map 函数传递到输入和跨度

javascript - 动画循环 - css

javascript - 如何在 Angular4 中设置 iframe?

jquery - z-index 问题,Mask 结束视频?

javascript - 如何阻止页面内容流入SideNav Semantic-ui

jquery - 如何以编程方式覆盖表单提交上的 select2 css?