背景
SPA(Single Page Application),即单页应用程序,将整个网站的内容都放在同一个页面中,通过异步加载数据来实现页面的更新,用户只需在单个页面中进行操作,无需跳转页面,大大提高了用户体验。但是,在实现 SPA 过程中,2B 问题也相应出现了,这里所说的 2B 问题主要有两方面:
- Back Button(后退按钮)问题:在 SPA 中,访问 URL 变化时只会切换页面的主体内容,而 URL 并未发生改变,一旦用户点击浏览器后退按钮,就会返回到上一个没有刷新的页面,用户体验大打折扣。
- Bookmark(书签)问题:在上述情况下,如果用户想要将当前的页面收藏起来,保存在书签栏中,重复打开该书签时也会返回到上一个没有刷新的页面。
这些问题显然对于页面的可用性和用户体验影响非常明显,本文将会介绍如何通过实现历史记录功能来解决这些问题,摆脱 2B 问题的困扰。
解决方案
在解决这个问题之前,需要先了解一下 history
对象。这个对象虽然浏览器支持它已经有很长时间了,但是知道的人并不多,这也是我们考虑使用的方法。
history
相当于保存了浏览器上一步和下一步之间的页面状态,包括当前页面的 URL,以及之前访问过的所有 URL,我们可以用其来模拟前进和后退功能、更改浏览器地址栏的 URL、跳转到某个指定的 URL 等。
因此,在 SPA 中我们可以使用 history.pushState()
方法来添加新的状态,history.replaceState()
方法来替换当前状态,以及 window.onpopstate
事件来监听当用户点击了前进或后退按钮时,浏览器向历史记录栈中添加或删除记录时,例如:
-- -------------------- ---- ------- -- --------- -- ------------------- ----- --------- -- ----- ------------ -- ------------ -- --------------------------- ------------------ ----- ------------------- -- ---------- ---- ----------------- - --------------- - ---------------------- - - ----------------- - -- ------ - - ----------------------------- --
有了以上基础,我们就可以着手解决具体的 2B 问题了。
解决 Back Button 问题
在 SPA 应用中,当用户按下后退按钮时,我们需要通过 history.pushState()
或 history.replaceState()
方法向历史记录栈中添加一条记录,以便在用户点击前进按钮时,能够通过 window.onpopstate
事件监听到历史记录栈的变化,并重新加载当前页面的状态。我们可以使用类似以下的方式:
// 添加路由记录 history.pushState({ page: "page1" }, null, "/page1"); // 监听路由变化 window.onpopstate = function(event) { console.log("location: " + document.location + ", state: " + JSON.stringify(event.state)); // TODO: 根据路由状态渲染页面(例如重新请求服务器) };
解决 Bookmark 问题
在解决 Bookmark 问题时,我们需要保证用户能够在点击书签链接时重现当时的页面状态,我们可以在路由变化时使用 URL 标识当前页面的状态,例如:
-- -------------------- ---- ------- -- ------ ------------------- ----- ------- -- ----- ---------- -- ------ ----------------- - --------------- - ---------------------- - - ----------------- - -- ------ - - ----------------------------- ------------------- --- -------- - -- ----- --------------------- - ---- - -- ----- ------ - --
这样当用户点击书签链接时,通过浏览器地址栏中的 URL,我们就能够判断出目标页面的状态,执行对应的渲染操作,避免了 Bookmark 问题的出现。
总结
以上就是解决 SPA 应用中的 2B 问题所需的核心知识点和代码实现方式。综合应用以上内容,加上一些业务逻辑,我们就可以完美地解决 SPA 应用中的 2B 问题,提升用户体验,增强网站的可用性。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64545d8b968c7c53b084b3cc