拜托,用个链接吧!Please, use a link!
针对现代 Web 应用中滥用 JavaScript 拦截导航而导致浏览器原生功能失效的现象进行了强烈批评。作者在使用某内部工具时,点击浏览器后退按钮竟直接跳转到了默认标签页,而不是返回上一页。造成这种糟糕体验的根本原因在于开发者没有使用原生的 `<a>` 标签进行页面跳转。文章呼吁回归 Web 基础,尊重浏览器内置的导航历史栈机制。
Ibrahim Diallo
这是一篇吐槽。这并不是今天才开始的,但我想我已经忍无可忍了。可以说是压死骆驼的最后一根稻草。我第一次使用某个内部工具。我登录并在 Web 应用中进行了浏览,四处做了一些更新。一切都很顺利。但后来我犯了个错,想返回到最初的仪表盘。我点击了后退按钮,结果没有返回上一页,反而看到 Chrome 的默认标签页赫然映入眼帘。
这怎么可能?我明明浏览了至少十几个页面,结果只点了一下后退按钮,整个 Web 应用就不翼而飞了。如果你也遇到过类似的情况,那很可能是因为你正在使用单页应用。当然,单页应用本身并没有错,但多年来我得出了一个结论:那些只知道如何构建单页应用的人,根本不知道什么是链接。
那么,让我们先来看几个“不是链接”的例子。
<div onclick="navigate('home')">Home</div>这不是链接。这是一个带有 onclick 事件处理程序的 div。你可以随便给它加样式,但它不是链接。
<button onclick="navigate('home')">Home</button>这也许是个按钮,但它不是链接。随着 React 的出现,这种情况已经变得司空见惯。因为它被称为“按钮”(button),初学者自然会倾向于用它来链接不同的页面。但还有更糟的。
<a onclick="navigate('home')">Home</a>这几乎让人感觉是故意的。好像开发者在故意戏弄我。既然用了锚(anchor)标签,为什么又要省略它最重要的属性呢?一个真正的链接应该是这样的:
<a href="/home">Home</a>就是这样。很简单。你不需要添加任何配置就能让浏览器支持它。你甚至都不需要给它写样式。所有的用户代理(user agents)都为链接的不同状态(未访问、已访问、活动)提供了合理的默认样式。它与浏览器历史记录完美契合。在桌面端,当你将鼠标悬停在它上面时,会在屏幕左下角看到目标 URL 的预览。在移动端,你可以长按它来获取多种打开方式的选项。你甚至都不用操心无障碍访问的问题。它天生就能正常工作。
但是,当开发者沉浸在自己的 React 应用中思考功能逻辑时,他们可能会说:“点击这个按钮时,跳转到主页。”他们自然会想到把 onClick 当作一个事件。而且既然是单页应用,他们考虑的就是状态(state),而不是页面。他们可能会写出类似这样的代码:
import { navigate } from 'somewhere';
function Home() {
return (
<div style={{ padding: '20px' }}>
<h1>Home Page</h1>
<button onClick={() => navigate('/about')}>
Go to About Page
</button>
<div
onClick={() => navigate('/about')}
style={{ cursor: 'pointer', marginTop: '10px', color: 'blue' }}
>
Click this text to navigate
</div>
</div>
);
}
export default Home;这已经够糟糕了。但取决于 navigate 函数是如何实现的,它可能会拯救也可能彻底破坏整个浏览器历史记录。在我用的那个内部工具中,navigate 本质上就是使用 location.replace() 将当前的 URL 替换为新的 URL。
只需使用锚标签,你就可以避免所有这些问题。如果你需要让它与你的 React 应用很好地配合,React Router 提供了一个 Link 组件。
import { Link } from 'react-router-dom';
function Navbar() {
return (
<nav>
<Link to="/home">Home</Link>
</nav>
);
}拜托,直接使用原生链接吧,这样你就不用再为其他任何事情操心了。
需要完整排版与评论请前往来源站点阅读。