让你的Hexo变成单页面应用
在开始之前,不妨先打开这个页面,播放一首音乐,再点击我的头像返回来。
你是不是会好奇,明明是由Hexo生成的静态页面,为什么没有触发浏览器刷新?
静态页面虽然对SEO友好,但是却让访客的浏览体验不佳——现如今几乎没有不需要进行交互的网页。而只需要使用Fetch API,将页面作为一种资源异步取得,再由Javascript进行解析和局部替换,就让整个网站看起来像是单页应用了
<!-- html -->
<a href="/audio/" onclick="onEvent(event);return false">声 音</a>
// typescript
async function _appendScript(element: HTMLScriptElement) {
return new Promise((resolve) => {
if (!element.src) {
// e.innerText = element.innerText
return
}
const e = document.createElement('script')
document.body.appendChild(e)
e.src = element.src
e.onload = () => {
resolve({})
}
})
}
/**
* 模拟单页面应用
* @param event
*/
async function onEvent(event: MouseEvent): Promise<void> {
const el = event.target as HTMLLinkElement
if (!el.href) {
return onEvent({ target: el.parentElement } as any)
}
const res = await fetch(el.href)
const data = await res.text()
const domparser = new DOMParser()
const doc = domparser.parseFromString(data, 'text/html')
window.history.pushState(null, doc.title, el.href)
document.title = doc.title
document.body = doc.body
let scripts: HTMLScriptElement[] = doc.body.querySelectorAll('script') as any
if (!scripts) scripts = []
else scripts = Array.from(scripts)
for (let i = 0; ; i++) {
if (i >= scripts.length) {
break
}
const s = scripts[i]
await _appendScript(s)
}
}