pjax的js重载
由于通过 Pjax 切换的页面并没有完全刷新,浏览器不会将网页从头执行一遍,因此有些 JS 将不会生效。重载 JS 脚本大致分为三种:一种是重载 JS 函数,一种是重载整个 JS 文件,另一种是重载内联的 script 标签。
重载 JS 函数
这种重载一般适用于用户自己编写的一些 JS 函数。但是具体情况比较复杂,函数要不要重载还得具体分析。下面举一些例子:
页面不变部分对应的事件
比如,页面顶部栏有一个搜索按钮,点击之后会弹出搜索框:
1
2
3document.querySelector(".search-button").onclick = function () {
// ...
};由于页面顶部栏不变,所以其中的元素上绑定的事件仍然可以使用,这部分元素对应的 JS 事件不需要重载。
页面可变部分对应的事件
比如,页面主体部分是变化的,懒加载其中的图片:
1
2
3var imgs = document.querySelectorAll("#main img.lazyload");
lazyload(imgs);当通过 Pjax 切换页面后,由于主体部分改变,上述代码已经失效,因此需要进行重载。为了方便使用,我们使用函数封装一下:
1
2
3
4
5
6
7
8
9
10function pjax_reload() {
var imgs = document.querySelectorAll("#main img.lazyload");
lazyload(imgs);
}
// Pjax 完成后,重新加载上面的函数
document.addEventListener("pjax:complete", function () {
pjax_reload();
});
重载整个 JS 文件
这种情况多数用于第三方文件,比如,卜算子统计的脚本、谷歌/百度/腾讯分析的脚本等,这些脚本在每一次页面加载后都需要执行。
我的做法是,在引入这些文件的标签上添加 data-pjax 属性,然后将具有这个属性的标签重新添加在页面中。有时候不方便在这些标签上添加额外的属性,那么你可以在这些标签外套一层标签,如< div class=”.pjax-reload”></ div>,然后将 .pjax-reload 里的元素全部重新添加到页面中即可。代码示例如下:
1 | <script |
1 | // jQuery 写法 |
重载整个script标签
这种情况和前面类似,如果一些 JS 脚本写在 script 标签中,并且需要重载,可以选择直接重载整个 script 标签。具体做法和上一步相同,在标签上添加 data-pjax 属性,然后将具有这个属性的标签重新添加到页面中。
实际操作
初级方案
在一些主题中如果作者有在pjax.ejs或者pjax.pug等类似文件中有类似如下代码的适配:
1 | document.querySelectorAll('script[data-pjax]').forEach(item => { |
其中可以看到选择器中有包含data-pjax的script标签会被重新加载,可以在需要重载的script标签加data-pjax属性。
也可以自己加选择器在querySelectorAll()里,比如butterfly主题中加入了名为“js-pjax”的类选择器。
终极方案
对于集成在插件里的js或者一些使用初级方案后仍旧无法重载的部分,可以在new pjax()中选择相应的标签对应的选择器。
博主本人并不十分了解pjax,这里这是给出自己的一些解决办法。