【问题标题】:How do I make links with no href attribute accessible?使没有 href 的链接可访问
【发布时间】:2012-08-16 14:11:48
【问题描述】:

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

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

添加role="link" 会有帮助吗?

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

更新:我无法将原始的 href 或类似 href="#" 的内容添加回链接,因为第三方代码将不再执行它的功能。我希望他们改进他们的代码,以便我可以,但现在我需要使链接可以在没有“href”的情况下访问。

【问题讨论】:

  • 认为您需要提供链接如何以任何方式工作的示例......您将不想从他们为 js-action 存储它的位置获取原始 href .
  • 如果我将 href 属性重新添加到链接中,第 3 方用于自定义内容和跟踪链接的代码将不起作用。我无法控制这段代码,但为了满足任何想看它的人的好奇心:jsfiddle.net/eNjnu
  • 不知道你能不能说出这里涉及的第三者的名字?或者透露更多关于它如何处理链接点击的信息——它还有其他假设吗?

标签: javascript html accessibility wai-aria wai


【解决方案1】:

要使非href <a> 表现得像<a>(并且可以访问),您必须添加role=linktabindex=0,将其设置为看起来像一个真正的链接,添加键盘处理程序代码以将 Return 视为单击。

role="link" 还不够;屏幕阅读器可能会将其报告为链接,但如果没有 tabindex="0" 和适当的视觉样式,有视力的用户将无法首先使用标签,并且如果没有键盘事件处理程序,则只有鼠标用户能够点击它。 (从技术上讲,屏幕阅读器用户通常有热键来模拟鼠标点击,但只有键盘视力的用户通常没有这个选项,所以不要依赖它。)

或者,如果(大如果!)您使用的疯狂脚本允许它,您可以尝试在原始脚本内填充“键盘点击源”(我的术语)<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>")

它的工作原理是内部新添加的&lt;a ...&gt; 有一个href,因此它作为链接公开并且是可标签的。更重要的是,如果用户选择它并按下回车键,默认的 A 行为会将键盘输入转换为 click 事件。这个特定的 A 有一个 href 返回 undefined/void(0),因此不会发生实际的导航,但点击事件仍会冒泡到原始 A,它会对其进行操作。

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

这里最大的警告是它假定您的原始脚本不关心事件的target。如果该脚本确实检查了这一点,那么当它看到来自 shim 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)
});

【讨论】:

  • 看起来很有希望。我明天试试看它是否与第 3 方脚本冲突。
  • 似乎有效。我需要将它包装在一个计时器中,因为第 3 方脚本使它更改为页面以响应它启动的 ajax 调用,但除此之外它工作得很好。非常感谢。
  • 酷;很高兴它似乎有效。您是否需要做任何事件的事情,或者“事件源”A 链接是否足够?请务必让第 3 方知道他们的可访问性问题;请记住,虽然您知道这是一个问题并已修复,但使用其代码的其他人可能没有意识到这一点,因此最终会出现在没有意识到的情况下不必要地无法访问的页面。上面的代码是一种解决方法,而不是修复。
【解决方案2】:

虽然它不是很漂亮,但您可以使用 jQuery 获得所有没有 href 属性的锚点;

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

然后您可以将这些链接上的href 属性设置为“#”,这样它们就可以再次作为常规链接工作。

Here's a working JSFiddle

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

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

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

【讨论】:

  • 杰克,添加 href="#" 会破坏链接。如果代码拦截了对链接的标准点击,那么就不会有问题。但事实并非如此,它依赖于没有 href 来做它的事情这一事实。我讨厌写得很糟糕的 3rd 方 JavaScript。 :-(
  • 抱歉,我没有意识到。是否有替代脚本,或者您可以编辑原始脚本吗?这个脚本听起来很痛苦!
猜你喜欢
  • 2020-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-18
  • 1970-01-01
  • 2016-04-03
  • 1970-01-01
  • 2018-09-19
相关资源
最近更新 更多