本文实现的单页应用很简单。
一段简单 HTML 结构:
<main>这是一个简单的单页应用示例</main>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
首先,我们将每个不同路线的网站标题和内容存储在一个名为 pages 的对象中:
const pages = {
'/': {
title: 'Home',
content: `<h1>欢迎来到我的网站!</h1>
<p>这是我的网站主页</p>
<h2>相关链接</h2>`
},
'/about': {
title: 'About',
content: `<h1>关于我</h1>
<p>我喜欢吃吃喝喝!</p>
<h2>相关链接</h2>`
},
'/contact': {
title: 'Contact',
content: `<h1>联系我</h1>
<p>我可以通过 email 联系到我</p>
<h2>相关链接</h2>`
}
}
然后,在页面加载时执行以下操作:
获取当前路径名(例如 /、/about、/contact)
根据路径名将 main 元素的 innerHTML 设置为正确的内容
根据路径名设置文档标题
我们使用 window.location.pathname 访问当前路径。接着,我们根据 pages 对象设置 main 元素的 innerHTML 属性和 document.title 属性。
const path = window.location.pathname
document.querySelector('main').innerHTML = pages[path].content
document.title = pages[path].title
每次我们点击一个链接,我们都会向服务器发送一个请求,并得到相同的响应。我们需要防止链接执行 GET 请求,而是直接在视图中操作 HTML:
const links = document.querySelectorAll('a')
links.forEach((link) => {
link.addEventListener('click', (e) => {
e.preventDefault()
const path = e.target.pathname
window.history.pushState({
}, pages[path].title, path)
document.querySelector('main').innerHTML = pages[path].content
document.title = pages[path].title
})
})
以上代码中,我们为文档中的每个链接添加了一个事件监听器。使用 preventDefault 阻止链接的默认操作。相反,它从目标锚点元素获取路径名,使用 window.history.pushState 来更改 URL,然后执行与加载时执行的代码相同的 innerHTML 和 title 更改内容。