React SPA 中的锚点或按钮? [英] Anchor or Button in React SPA?

查看:35
本文介绍了React SPA 中的锚点或按钮?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设页面上有一段文本(无论它的样式是否为传统"链接或按钮),当点击该文本时,该文本会指向带有新页面/URL 的新页面.但是导航以编程方式发生(例如,通过 react-router 使用 History Web API)而不是硬 HTTP 刷新.

Say there is piece of text (regardless of whether it is styled as a "traditional" link or button) on a page that when clicked leads to a new page with a new page/URL. But the navigation happens programmatically (e.g. via react-router using the History web API) instead of a hard HTTP refresh.

在这种情况下,它应该是带有href属性的传统锚链接,例如#还是按钮?

In this case, should it be a traditional anchor link with href attribute such as # or a button?

选项 1:

<a href="#" onClick={navigateToNextPage}>Link</a>

缺点是你有一个垃圾 href 属性.您可以删除它,但它不在 Tab 键顺序中,并且不会获得默认链接样式(尽管可以通过一次性样式克服这些问题).此外,如果您复制链接,它会复制为 #,这是不正确的,并且会被屏幕阅读器错误地解释.

The downside is that you have a junk href attribute. You could remove that but then it is not in the tab order and doesn't get default link styling (though these could be overcome with one-off styling). Also if you copy the link it will copy as # which is incorrect and be interpreted incorrectly by screen readers.

选项 2:

<button onClick={navigateToNextPage}>Link</a>

这里的缺点是,如果您希望它看起来像传统链接,则需要应用自定义样式.此外,在我看来,它在某些方面确实像一个传统的链接.但这对屏幕阅读器来说会更好.

The downside here is that if you want it to look like a traditional link you need to apply custom styling. Also in some ways it is really acting like a traditional link in my view. But this would be better for screen readers.

推荐答案

我不能评论 React,但这里是 SPA 的正确方法,在 React 中实现它应该是微不足道的.

I can't comment on React but here is the correct method for SPAs, implementing it should be trivial in React.

如果没有其他选项可用,请使用超链接 () 在页面之间导航以及加载其他内容时.

Use a hyperlink (<a>) to navigate between pages and when loading additional content if no other option is available.

更简单:如果 URL 更改或您向页面添加了大量信息,请使用超链接.

More simply: if the URL changes or you add large amounts of information to the page, use a hyperlink.

在您的问题中,您提到了 History API 和 react-router.

In your question you mentioned the History API and react-router.

出于这个原因,我假设函数 navigateToNextPage 更改了 URL.

For this reason I assume that the function navigateToNextPage changes the URL.

我还假设我可以通过在浏览器中输入该 URL 来直接访问该页面.

I also assume that I could access that page directly if I desired by entering that URL into my browser.

考虑到这些假设,您应该使用:-

With those assumptions in mind you should use:-

<a href="new-page-url" onClick={navigateToNextPage}>Link</a>

显然你会停止默认操作(e.preventDefault() 或 React 等价物).

Obviously you would stop the default action (e.preventDefault() or React equivalent).

关于为什么使用上述格式的几点:-

A couple of points on why to use the format described above:-

  1. 可访问性 - 当我遇到带有屏幕阅读器的超链接时,我可以询问我的屏幕阅读器该链接会将我带到哪里,这令人放心,我不能用按钮做同样的事情.这就是为什么我没有使用 # 作为超链接,而是添加了实际目的地.如果您看到 href=#",这几乎总是表明使用了错误的元素或使用不当.在阅读您关于在导航之前执行操作的评论后,这仍然是完全有效的,执行您的操作然后重定向,它仍然是一天结束时的导航.
  2. 可访问性 - 当我通过屏幕阅读器浏览网站时,我可能决定循环浏览页面上的所有超链接以了解页面结构.(例如,NVDA 修饰符 + K 以获得下一个链接).我不太可能遍历页面上的所有按钮来查找导航.
  3. 可访问性 - 如果我遇到一个链接,我期望页面会发生变化(甚至通过 AJAX).如果我遇到一个按钮,我希望它在当前页面上执行一个操作.预期行为是可访问性的关键部分.
  4. 可访问性 - 超链接有一些重要的状态.已访问"是包含大量链接的页面的关键,因为我可能想查看我之前阅读的内容并能够通过访问过的链接进行导航(例如 NVDA 修饰符 + K 所有未访问的链接).按钮不公开此信息.重要的一点是,您也不能在 CSS 中使用 button:visited 设置按钮样式,因此您会错过那里每个人的视觉线索.
  5. 辅助功能 - Space 键与 Enter 键.如果我登陆一个链接,我希望按 space 进行导航,
  6. 健壮性 - 如果您的网站功能有限 JavaScript 失败时,超链接远比按钮好. JavaScript 失败时它仍然可以工作,这在 JavaScript 失败可能只是一个页面的临时加载问题时特别有用,允许用户访问另一个正常运行的页面.
  7. SEO - 我敢在 Stack Overflow 上谈论 SEO?耻辱!耻辱!耻辱!:-P - 但说真的,虽然谷歌在 JS 驱动的网站上可以做的事情非常聪明,但它仍然很难弄清楚 JavaScript 链接将把它带到哪里.如果 SEO 对您很重要,那么请使用带有有效目的地的超链接,以便 Google 可以正确映射信息.
  1. Accessibility - when I encounter a hyperlink with a screen reader I am able to ask my screen reader where that link will take me, this is reassuring, I can't do the same with a button. This is why I didn't use # for the hyperlink but instead added the actual destination. If you see href="#" it is nearly always a sign that the wrong element is being used or it is being used incorrectly. After reading your comments about performing an action before navigating this is still perfectly valid, perform your action and then redirect, it is still navigation at the end of the day.
  2. Accessibility - when I am navigating a site via a screen reader I may decide to cycle through all the hyperlinks on the page to get a feeling for the page structure. (NVDA modifier + K to get next link for example). I am very unlikely to loop through all the buttons on a page to look for navigation.
  3. Accessibility - If I encounter a link I expect the page to change (even via AJAX). If I encounter a button I expect it to perform an action on the current page. Expected behaviour is a key part of accessibility.
  4. Accessibility - hyperlinks have some important states. 'visited' is a key one on pages with lots of links as I may want to review something I read earlier and being able to navigate via visited links (e.g. NVDA modifier + K for all unvisited links). Buttons do not expose this information. An important point here is that you also can't style a button with button:visited in your CSS so you miss out on the visual clue for everybody there.
  5. Accessibility - Space key vs the Enter key. If I land on a link I am expecting to press space to navigate, a <button> only works with the Enter key and so I may be confused as to why the page isn't changing. (I am assuming at this point you have used a load of aria to convince me this button is a hyperlink).
  6. Robustness - If your site has limited functionality when JavaScript fails a hyperlink is far better than a button. It will still work when JavaScript fails and this is especially useful when a JavaScript failure may only be a temporary load problem with one page, allowing a user to get to another functioning page.
  7. SEO - I dare to speak of SEO on Stack Overflow? Shame! Shame! Shame! :-P - but seriously although Google is pretty darned smart in what it can do on JS powered sites it does still struggle to work out where a JavaScript only link will take it. If SEO matters for you then use a hyperlink with a valid destination so Google can map information correctly.

可能是我忘记提及的其他原因,但我想我已经说明了这一点.

Probably other reasons I have forgotten to mention but I think I have made the point.

虽然不是您问题的一部分,但我想我会快速补充几点以确保完整性.

Although not part of your question I thought I would quickly add a couple of points for completeness.

如果您使用 SPA 模式(因此会中断正常导航),则需要向用户发出正在加载页面的信号.例如我单击您的链接,您需要让我知道正在执行操作(加载.....),因为您使用 e.preventDefault() 或等效工具拦截了正常的浏览器行为.

You need to signal to a user that a page is loading if you are using a SPA pattern (and therefore interrupting normal navigation). e.g. I click your link you need to let me know that an action is being performed (loading.....) as you intercept the normal browser behaviour with e.preventDefault() or equivalent.

最简单的方法是使用 aria-live=assertive 在解释页面正在加载的区域上.你可以谷歌如何正确实施.

The simplest way is to use aria-live=assertive on a region that explains the page is loading. You can Google how to implement that correctly.

此外,当新页面加载时,您需要管理焦点.

Additionally when the new page loads you need to manage focus.

执行此操作的最佳方法是为每个具有 tabindex=-1" 的页面添加一个 1 级标题 (

).

The best way to do this is to add a level 1 heading (<h1>) to each page that has tabindex="-1".

页面加载后,您在 JavaScript 导航功能中执行的最后一个操作就是将焦点放在此标题上.

Once the page loads the last action you perform in your JavaScript navigation function is to place the focus onto this heading.

这有两个好处:

  1. 它让用户知道他们现在在哪里
  2. 它还让他们知道页面加载何时完成(因为 AJAX 导航不会在大多数屏幕阅读器中通知页面何时加载).

使用 tabindex=-1" 意味着标题不会被 JavaScript 以外的任何东西聚焦,因此不会干扰正常的文档流.

By using tabindex="-1" it means that the heading won't be focusable by anything other than your JavaScript so won't interfere with the normal document flow.

这篇关于React SPA 中的锚点或按钮?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆