单页应用(SPA)已经成为现代 Web 开发的一种趋势。它能够极大地提高用户体验,提高页面加载速度,我们可以使用 Vue、Angular、React 等前端框架/库快速建立 SPA 应用。在本文中,我们将介绍如何使用原生 JavaScript 实现 SPA 路由切换,不使用 Vue 或其他前端库,只使用 AJAX 实现页面无刷新切换。
SPA 简介
SPA优点:
- 用户体验好,页面切换无刷新感知
- 加载速度快,只需加载一次html,局部刷新数据
- 可维护性好,结构清晰,易于模块化开发
缺点:
- SEO不友好,搜索引擎检索难度大
- 对浏览器的运行性能要求较大
- 初次加载时间相对较长,对网络要求高
原生JS实现SPA基础
- history API控制地址栏和历史记录
- XMLHttpRequest实现Ajax异步数据获取
- DOM操作实现数据变化和页面重绘
// javascriptcn.com 代码示例 // 代码09.01 SPA路由部分 (router.js) class Router{ constructor(){ this.routes = {} this.currentUrl = '' this.history = [] this.currentIndex = this.history.length-1 this.backFlag = true this.forwardFlag = true this.init() } init(){ window.addEventListener('load', this.refresh.bind(this), false) window.addEventListener('popstate', e => { if(!this.backFlag && !this.forwardFlag){ this.backOrForward(e) }else{ this.backFlag = false this.forwardFlag = false } }, false) window.addEventListener('hashchange', this.refresh.bind(this), false) } route(path, callback){ this.routes[path] = callback || function(){} } refresh(){ if(location.pathname !== this.currentUrl || location.hash){ this.backFlag = true this.forwardFlag = true this.currentIndex = this.history.length this.history.push(location.pathname) this.currentUrl = location.pathname this.routes[this.currentUrl]() } } backOrForward(e){ this.currentIndex += e.state this.currentUrl = this.history[this.currentIndex] this.routes[this.currentUrl]() } back(){ this.backFlag = true this.forwardFlag = true this.currentIndex--; this.currentIndex = this.currentIndex < 0 ? 0 : this.currentIndex this.currentUrl = this.history[this.currentIndex] this.routes[this.currentUrl](); history.go(-1) } forward(){ this.backFlag = true this.forwardFlag = true this.currentIndex++ this.currentIndex = this.currentIndex >= this.history.length ? this.history.length - 1 : this.currentIndex this.currentUrl = this.history[this.currentIndex] this.routes[this.currentUrl]() history.go(1) } } // 代码09.02 index.html <body> <div class="container"> <ul> <li><a href="#/home">首页</a></li> <li><a href="#/about">关于我们</a></li> <li><a href="#/contact">联系我们</a></li> </ul> <div id="ajax_container"></div> </div> </body> // 代码09.03 spa.js class View{ constructor(container){ this.container = container this.template = null this.init() } async init(){ await this.beforeRender() this.render() await this.afterRender() } async render(){ let html = await this.getHTML() this.container.innerHTML = html } async getHTML(){ try{ let html = this.template let response = await this.fetchFragment() let document = new DOMParser().parseFromString(response, "text/html") let fragment = document.createDocumentFragment() fragment.appendChild(document.body) let fragmentContainer = document.createElement("div") let contentHTML = fragment.querySelector("#ajax_container").innerHTML fragmentContainer.innerHTML = contentHTML html = html.replace("{{content}}", contentHTML) return html }catch(e){ throw e } } async fetchFragment(){ try{ let url = this.contentURL() let response = await fetch(url) let text = await response.text() return text }catch(e){ throw e } } contentURL(){ return null } beforeRender(){ } afterRender(){ } }
总结
本文介绍了如何使用原生 JavaScript 实现 SPA 路由切换,不使用 Vue 或其他前端库,只使用 AJAX 实现页面无刷新切换。我们通过对 history API 和 XMLHttpRequest 实现 AJAX 异步获取数据,再通过 DOM 操作来完成数据变化和页面重绘,实现了 SPA 的核心功能。这个项目的实现方法可以帮助初学者掌握 SPA 的基础知识,更好地理解前端框架/库所基于的理念和思路,提高自身的编程水平。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/654f56827d4982a6eb84bb10