[英]Anchor or Button in React SPA?
假设页面上有一段文本(无论它是否被设置为“传统”链接或按钮),当单击该文本时,该文本会导致带有新页面/URL 的新页面。 但导航以编程方式发生(例如,通过react-router
使用 History web API)而不是硬 HTTP 刷新。
在这种情况下,它应该是带有#
等href
属性的传统锚链接还是按钮?
选项 1 :
<a href="#" onClick={navigateToNextPage}>Link</a>
缺点是你有一个垃圾href
属性。 您可以删除它,但它不在选项卡顺序中并且没有获得默认链接样式(尽管这些可以通过一次性样式来克服)。 此外,如果您复制链接,它将复制为#
这是不正确的,并被屏幕阅读器错误地解释。
选项 2 :
<button onClick={navigateToNextPage}>Link</a>
这里的缺点是,如果您希望它看起来像传统链接,则需要应用自定义样式。 在我看来,在某些方面它确实像一个传统的链接。 但这对于屏幕阅读器来说会更好。
我无法评论 React,但这是 SPA 的正确方法,在 React 中实现它应该是微不足道的。
如果没有其他选项可用,请使用超链接 ( <a>
) 在页面之间以及在加载其他内容时导航。
更简单地说:如果 URL 发生变化,或者您向页面添加大量信息,请使用超链接。
在您的问题中,您提到了 History API 和react-router
。
出于这个原因,我假设 function navigateToNextPage
更改了 URL。
我还假设我可以通过在浏览器中输入 URL 来直接访问该页面。
考虑到这些假设,您应该使用:-
<a href="new-page-url" onClick={navigateToNextPage}>Link</a>
显然,您将停止默认操作( e.preventDefault()
或 React 等效项)。
关于为什么使用上述格式的几点:-
#
作为超链接,而是添加了实际目的地。 如果您看到href="#"
几乎总是表明使用了错误的元素或使用不正确。 在阅读您关于在导航之前执行操作的评论之后仍然完全有效,执行您的操作然后重定向,它仍然是一天结束时的导航。button:visited
在您的 CSS 中设置按钮样式,因此您错过了那里每个人的视觉线索。space
键进行导航的链接,则<button>
仅适用于Enter键,因此我可能会对页面没有更改的原因感到困惑。 (我假设此时您已经使用了大量的aria
来说服我这个按钮是一个超链接)。可能还有其他我忘记提及的原因,但我想我已经说明了这一点。
虽然不是你问题的一部分,但我想我会很快补充几点以确保完整性。
如果您使用 SPA 模式(因此会中断正常导航),您需要向用户发出页面正在加载的信号。 例如,我单击您的链接,当您使用e.preventDefault()
或等效项拦截正常浏览器行为时,您需要让我知道正在执行某个操作(正在加载.....)。
最简单的方法是在解释页面正在加载的区域上使用aria-live=assertive
。 您可以谷歌如何正确实施。
此外,当新页面加载时,您需要管理焦点。
最好的方法是为每个具有tabindex="-1"
的页面添加一个级别 1 标题 ( <h1>
)。
一旦页面加载您在 JavaScript 导航 function 中执行的最后一个操作,将焦点放在此标题上。
这有两个好处:
通过使用tabindex="-1"
这意味着标题不会被 JavaScript 以外的任何东西聚焦,因此不会干扰正常的文档流。
单击<NavLink>
时,您只需执行e.preventDefault()
即可。 然后导航。 NavLink
在 HTML 中生成<a>
标签,并在路由处于活动状态时默认提供active
class。 这允许您设置活动 state 链接的样式。
import React from "react";
import { NavLink, withRouter } from "react-router-dom";
function Header(props) {
const handleClick = e => {
e.preventDefault();
console.log("DO SOMETHING");
props.history.push(e.target.pathname);
};
return (
<ul>
<li>
<NavLink exact to="/" onClick={handleClick}>
Home
</NavLink>
</li>
<li>
<NavLink to="/about" onClick={handleClick}>
About
</NavLink>
</li>
<li>
<NavLink to="/topics" onClick={handleClick}>
NavLink
</NavLink>
</li>
</ul>
);
}
export const HeaderNav = withRouter(Header);
我建议您使用语义 HTML。 这意味着尽可能将正确的 HTML 元件用于其预期目的。
- 更容易开发——你可以免费获得一些功能,而且可以说它更容易理解。
- 在移动设备上更好——语义 HTML 在文件大小上可以说比非语义意大利面条代码更轻,并且更容易做出响应。
- 对 SEO 有好处——搜索引擎更重视标题、链接等中的关键字,而不是非语义等中包含的关键字,因此您的文档将更容易被客户找到。
还有更多细节
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.