问题 建立无href可访问的链接


正在我工作的网站上使用的第三方脚本取代了一些实例 <a href=""> 简单 <a>。由于脚本的另一部分,链接仍然有效。但是它们不再被用户代理视为链接。

我可以通过添加将它们恢复到选项卡式导航顺序 tabindex="0" 但我怎样才能让辅助技术宣布它们为链接或将它们包含在页面上所有链接的列表中?

会补充 role="link" 有帮助吗?

我正在推动第三方改进他们的脚本,以便href保持不变。但与此同时,我如何才能最好地修复正在进行的损害?

更新: 我不能添加原件 href 或类似的东西 href="#" 回到链接,因为第三方代码将不再执行它所做的事情。我希望他们能够改进他们的代码,但是现在我需要在不使用'href'的情况下访问链接。


12289
2017-08-21 08:54


起源

认为你需要提供链接如何以任何方式工作的例子....你将不会从他们为js-action存储它的地方获得原始的href。 - Steen
哪个代码不起作用? - starbeamrainbowlabs
如果我将href属性添加回链接,则第三方用于自定义内容和跟踪链接的代码将不起作用。我无法控制这段代码,但为了满足任何想要看到它的人的好奇心: jsfiddle.net/eNjnu - Steve Pugh
我想知道你是否可以为这里涉及的第三方命名?或者透露更多关于它如何处理链接点击的信息 - 是否还有其他假设? - BrendanMcK


答案:


要使非href A的行为类似于A(并且可以访问),您必须添加 role=linktabindex=0,把它看起来像一个真正的链接,  添加键盘处理程序代码以将Return视为单击。 role =“link”是不够的;屏幕阅读器可以将其报告为链接,但没有 tabindex="0" 和适当的视觉样式,有视觉的用户将无法首先选中它,并且没有键盘事件处理程序,只有鼠标用户才能单击它。 (技术上屏幕阅读器用户通常使用热键来模拟鼠标点击;但只有键盘的用户通常没有该选项,所以不要依赖它。)

或者,如果(如果!)您正在使用的疯狂脚本允许它,您可以尝试填充“键盘点击源”(我的术语)A在原始A中:所以你在哪里:

<a>foo</a>

你替换它:

<a><a class='shim' href="javascript:void(0)">foo</a></a>

(该 class='shim' 仅在您需要执行稍后描述的事件时才需要...) 您可以使用以下内容在jQuery中执行此操作:(借用Jack的答案)

$("a:not([href])").wrapInner("<a class='shim' href='javascript:void(0)'></a>")

这是如何工作的内部新增 <a ...> 有一个 href,因此被暴露为链接并且是可能的。更重要的是,如果用户选中它并按回车,则默认的A行为会将该键盘输入转换为 click 事件。这个特定的A有一个 href 返回undefined / void(0),因此不会发生实际的导航,但click事件仍然会冒泡到原来的A,它会对它起作用。

(这是一个简洁的模式,允许一些父元素 - 通常是DIV或类似的 - 来处理点击事件,添加一个子列表可以从键盘中获取点击事件,为您提供鼠标和键盘都可用的UI。)

这里最大的警告是它假设你的原始剧本并不关心 target 这件事。如果该脚本确实检查了这一点,当它看到来自垫片A而不是原始As的点击事件时,它会感到困惑。解决此问题的一种方法是捕获并重新引发事件,这可能很繁琐,并且可能仅适用于最近的浏览器 - 例如使用以下内容:

// 'shim' class used so we can do this:
$("a.shim").click(function(e) {
    e.preventDefault();
    e.stopPropagation();

    // the following works if listener using jQuery or is setting onclick directly, otherwise...
    // $(e.target).parent().click();.

    // More general way to raise events; may need alternate for IE<9
    var e2 = document.createEvent("UIEvents");
    e2.initUIEvent("click", true, true, window, 1);
    e.target.parentNode.dispatchEvent(e2)
});

8
2017-08-22 10:56



看起来很有希我明天就试一试,看看它是否与第三方脚本冲突。 - Steve Pugh
似乎工作。我需要将它包装在一个计时器中,因为第三方脚本会更改页面以响应它启动的ajax调用,但除此之外它工作得很好。非常感谢你。 - Steve Pugh
凉;很高兴它似乎工作。您是否需要执行任何事件,或者是“事件源”A链接是否足够?请让第三方了解他们的可访问性问题;请记住,虽然你知道这是一个问题并且有一个修复,但是其他使用他们代码的人可能没有意识到这一点,因此最终会得到一些在不知不觉中无法访问的页面。上面的代码是一种解决方法,而不是修复。 - BrendanMcK


虽然它不是很漂亮,但你可以在没有它的情况下获得所有锚点 href 像这样的属性,使用jQuery;

$("a:not([href])")

然后你可以设置 href 将这些链接归属于“#”,这应该使它们再次作为常规链接工作。

这是一个有效的JSFiddle

很抱歉回复jQuery解决方案......但是在常规JavaScript中执行此操作会更加冗长。

另一种方法是给锚点一个角色,然后以这种方式选择它们:

$("a[role='link']")

2
2017-08-21 09:19



杰克,添加href =“#”打破链接。如果代码拦截标准点击链接,那么就不会有问题。但事实并非如此,它依赖的事实是没有href来做它的事情。我讨厌写得不好的第三方JavaScript。 :-( - Steve Pugh
啊,我的道歉,我没有意识到。是否有替代脚本,或者您可以编辑原始脚本吗?这个脚本听起来很痛苦! - Jack Franklin