简体   繁体   English

可访问性 - Javascript 仅链接带有 href=“#” 的反模式?

[英]Accessibility - Javascript only links with href=“#” an antipattern?

I have a react SPA where I have some links which require javascript to change the page url.我有一个反应 SPA,其中有一些链接需要 javascript 来更改页面 url。 Semantically these should be links, but the link destination is computed at runtime on click, or it requires javascript to move to that location (history api)从语义上讲,这些应该是链接,但是链接目标是在运行时单击时计算的,或者它需要 javascript 移动到该位置(历史 api)

I have seen it mentioned at a few places that href="#" is an antipattern or something that should be avoided.我在一些地方看到过,href="#" 是一种反模式或应该避免的东西。 For example this article from webaim https://webaim.org/techniques/hypertext/ mentions that:例如,来自 webaim https://webaim.org/techniques/hypertext/的这篇文章提到:

One of the most serious barriers is to create links that go nowhere.最严重的障碍之一是创建 go 无处的链接。 Developers sometimes use JavaScript to create dynamic menus that drop down when the user hovers over certain links with the mouse.开发人员有时会使用 JavaScript 创建动态菜单,当用户将鼠标悬停在某些链接上时会下拉。 In some cases, the link itself goes nowhere at all, and its only purpose is to expose the links in the drop-down menu, which do have real destinations.在某些情况下,链接本身根本无处可去,其唯一目的是在下拉菜单中公开链接,这些链接确实具有真实的目的地。 Links like this often have a pound sign as the link destination, which means that the link destination is the same page;像这样的链接通常有一个井号作为链接目的地,这意味着链接目的地是同一个页面; clicking on the link accomplishes nothing.点击链接什么也没做。 Both keyboard users and mouse users will experience nothing at all when attempting to activate the link.尝试激活链接时,键盘用户和鼠标用户都不会有任何体验。

and it gives an example of href="#"它给出了一个 href="#" 的例子

Now i get that using href="#" for links which do nothing or do not take the user anywhere might semantically be incorrect.现在我明白了,对于不执行任何操作或不将用户带到任何地方的链接使用 href="#" 可能在语义上是不正确的。 In my usage though, the link does have a destination, just that the destination can't be specified in href and may not be decided unless the link is clicked.不过,在我的使用中,链接确实有一个目的地,只是目的地不能在 href 中指定,除非单击链接,否则可能无法确定。 So my usage is to have href="#" and e.preventDefault() onClick, so that it does not go to top of the page and create another history entry.所以我的用法是让href="#"e.preventDefault() onClick,这样它不会 go 到页面顶部并创建另一个历史记录条目。

I have seen other working solutions/workarounds for this:我已经看到了其他可行的解决方案/解决方法:

But i would like to understand, if using href="#" for links that do have a destination (which is figured out after clicking on the link, or applied using javascript) is an antipattern.但我想了解,如果将href="#"用于确实有目的地的链接(在单击链接后发现,或使用 javascript 应用)是一种反模式。

This is a follow up to this question related to javascript only links accessibility Accessibility: Using javascript only links with href="#"这是与 javascript 相关的问题的后续行动,仅链接可访问性可访问性:使用 javascript 仅链接带有 href="#"

If you are using a screen reader software, eg, NVDA on Windows (Browser mode, specifically), it could intercept certain keys (eg, Space or Enter key) to a <a> tag and bind certain behavior to that, meaning that it bypasses the Javascript code that generates dynamic URLs).如果您使用的是屏幕阅读器软件,例如 Windows 上的 NVDA(特别是浏览器模式),它可能会拦截某些键(例如, SpaceEnter键)到<a>标签并将某些行为绑定到该标签,这意味着它绕过生成动态 URL 的 Javascript 代码)。 So your app could be broken for NVDA users.所以你的应用程序可能会被 NVDA 用户破坏。

You can actually try testing your app on NVDA / JAWS on Windows, and see if <a href="#" /> + Javascript works.您实际上可以尝试在 Windows 上的 NVDA / JAWS 上测试您的应用程序,看看<a href="#" /> + Javascript 是否有效。

If you are building a dropdown menus, generally, it's hard to implement make it 100% accessible for hover-and-expand menus.如果您正在构建下拉菜单,通常很难实现使其 100% 可用于悬停和展开菜单。 We should avoid using this pattern if possible.如果可能,我们应该避免使用这种模式。 You are better off using other designs, eg, table of content.您最好使用其他设计,例如目录。

If it navigates to a new URL, the href property should be set to that new URL.如果它导航到新的 URL,则href属性应设置为新的 URL。 You can then use event.preventDefault() to prevent the page from reloading at the new location.然后,您可以使用event.preventDefault()来防止页面在新位置重新加载。

 // mock out history for demo purposes const history = { pushState: (_data, _title, newUrl) => { alert(`navigated to ${newUrl}.`) } } document.querySelector('#spa-link'),addEventListener('click'. e => { e.preventDefault() history,pushState({}, '', '/new/path') })
 <a id="spa-link" href="/new/path">Go to new path</a>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM