今天下午又开始直播了,内容是手写一个 Pjax 实现。Pjax 即 PushState + Ajax,主要是发现目前首页在用的 Pjax 库没有生命周期的概念,按照 React 的规则,如果想要彻底卸载一个页面,除了移除 DOM,还需要清空页面的所有对象事件,手动清理内存总会更合理吧。
整体过程还算流畅,主要是发现 popstate
这个事件的触发时机其实是按下返回或前进按钮之后才执行,因此需要将触发前的状态进行一次记录,方便在 onmount
和 unmount
两个回调里面判断页面路径,执行载入和卸载操作。
第一次进入页面,通过 history.state
获取状态是空的,会导致回退时无法正确刷新页面。可以通过手动记录首次页面的状态或者使用 history.replace
实现首个 State 的初始化。
整个 Pjax 的实现,主要就是这几个对象/函数,并不是很困难,唯独麻烦的就是请求页面失败或者超时,应该卸载当前页面还是不卸载呢?不卸载的话,页面 State 已经发生变化。卸载的话,页面上的东西全部无法交互了,真蛋疼。
// 创建一个文档实例,用于实际 DOM 的内容替换
document.implementation.createDocument
// 监听状态
window.onpopstate = function () {}
// 初始化页面的时候用一次,使 State 默认有数据
history.replaceState()
// 创建一个 State
history.pushState()
// 获取 State
history.state
我想了一招,能不能在 popstate
事件里面检测我是前进还是后退,如果后退我就重新前进一次,反之后退。可这事件并没有提供类似的属性,那就是没有办法在点击按钮重新加载页面且失败的情况下,回到之前的状态啊!
这个问题暂且有点难搞,先放着吧。虽说这个现象和现在的首页情况一样,但确实是没想出没有什么良好的解决办法。继续整 Preact + TypeScript 版小窝后台了。
后台部分,主要是让 @Innei 出马整了一下自己写的库里面的 TS 类型定义,解决爆红问题。但还是感觉到 Preact 在这块的短板,onChange 事件处理那里还是有很多爆红,感觉还是得换回 React 了!