小记一下Hexo开懒加载后首次打开新页面无法显示问题

我一开始以为是自己配网站配的有问题,比如说插件装多了或者配置文件配错了,后来发现解决不了(

Hexo版本:7.3.0

主题为:hexo-theme-anzhiyu-1.6.14

问题效果描述

第一次打开网站后点击的第一个页面,图片加载不出来(实际上是加载了的,大图模式可以看见)

必须刷新页面才能好起来

image-20251002223901718

使用大图模式可以正常打开

image-20251002223939941

关掉懒加载后就能正常显示,推测应该是某个插件和懒加载冲突了

image-20251002225025946

问题真实原因

在参考了部分教程后发现,应该是懒加载和pjax冲突了,我关闭了pjax后页面也加载正常了。

就是这两个功能互相冲突打架了:

  • 懒加载:等用户划到对应位置才开始加载图片
  • PJAX:切换页面的时候不需要刷新整个页面,实现平滑切换

PJAX换完内容后,懒加载以为自己在老页面,根本没去管新来的图片。结果就是图片虽然存在,但懒加载不让它显示出来。

尝试去解决问题

起初我去配置了pjax对应的配置文件

效果确实好了,但是无缝切换页面功能没了(而且网站主题依赖pjax过多很多功能没了 失败

1
2
3
4
5
6
7
pjax:
enable: true
exclude:
- 'a[target="_blank"]' # 排除在新窗口打开的链接
- 'a.no-pjax' # 排除带有"no-pjax"类的链接
- 'a[data-no-pjax]' # 排除含有"data-no-pjax"属性的链接
- 'a[href^="https://external.com"]' # 排除指向特定外部域名的链接

然后又尝试加入这个参数到懒加载

因为懒加载插件不一样失败(这个主题的是vanilla-lazyload而不是hexo-lazyload-image

1
isSPA: true

只能动代码了 - 问题解决

我找了很多教程和问了很多AI也没有效果 最后只能动主题文件了

Hexo毕竟是静态博客(要有动代码前的备份的好习惯 主题报错就老实了

打开博客根路径 \themes\hexo-theme-anzhiyu-1.6.14\source\js\main.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
const unRefreshFn = function () {
window.addEventListener("resize", () => {
adjustMenu(false);
mobileSidebarOpen && anzhiyu.isHidden(document.getElementById("toggle-menu")) && sidebarFn.close();
});

document.getElementById("menu-mask").addEventListener("click", e => {
sidebarFn.close();
});

// 处理右键
$rightMenu = document.getElementById("rightMenu");
addDarkModeEventListener("menu-darkmode");
addDarkModeEventListener("sidebar", ".darkmode_switchbutton");

clickFnOfSubMenu();
GLOBAL_CONFIG.islazyload && lazyloadImg();
GLOBAL_CONFIG.copyright !== undefined && addCopyright();
GLOBAL_CONFIG.navMusic && listenNavMusicPause();
if (GLOBAL_CONFIG.shortcutKey && document.getElementById("consoleKeyboard")) {
localStorage.setItem("keyboardToggle", "true");
document.getElementById("consoleKeyboard").classList.add("on");
anzhiyu_keyboard = true;
executeShortcutKeyFunction();
}
if (GLOBAL_CONFIG.autoDarkmode) {
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", e => {
if (saveToLocal.get("theme") !== undefined) return;
e.matches ? handleThemeChange("dark") : handleThemeChange("light");
});
}
// 欢迎语
GLOBAL_CONFIG.greetingBox && greetingInit();
// 51la统计&灵雀统计
GLOBAL_CONFIG.LA51 && statistics51aInit();

document.addEventListener('pjax:complete', function() {
setTimeout(() => {
if (window.lazyLoadInstance) {
window.lazyLoadInstance.update();
}
}, 100);
});

};

框起来的是新增部分

image-20251002234113027

为了保险,我问一下AI来个代码解释。

第1行:document.addEventListener('pjax:complete', function() {

  • document.addEventListener:为文档添加事件监听器
  • 'pjax:complete':监听的事件名称,表示 PJAX 页面切换完成
  • function() {:事件触发时执行的回调函数

第2行:setTimeout(() => {

  • setTimeout:设置一个延迟执行的定时器
  • () => {:箭头函数,100ms后执行

第3行:if (window.lazyLoadInstance) {

  • 条件判断:检查全局变量 window.lazyLoadInstance 是否存在
  • 作用:确保懒加载实例已经初始化,避免在实例不存在时报错

第4行:window.lazyLoadInstance.update();

  • window.lazyLoadInstance:vanilla-lazyload 创建的全局实例
  • .update():懒加载实例的方法,重新扫描DOM查找新的懒加载图片

第5-8行:闭合括号

  • 结束条件判断、箭头函数和回调函数

整体功能:

这段代码的作用是:当 PJAX 完成页面切换后,延迟100毫秒,然后更新懒加载实例,让它重新扫描新页面中的图片元素。

为什么要这样设计:

  1. 事件监听pjax:complete 事件确保在页面内容已经替换完成后执行
  2. 延迟执行setTimeout 给浏览器一点时间完成DOM渲染,确保所有新图片都已插入到DOM中
  3. 安全检查if (window.lazyLoadInstance) 防止实例未初始化时出现错误
  4. 更新实例update() 方法让懒加载库知道有新内容需要处理

这样就解决了 PJAX 和懒加载冲突的问题:新页面加载后,懒加载库能正确识别并处理新图片。

再次验证

使用无痕(清除缓存也行)重新打开页面(测试功能 发现功能完善啦

image-20251002234513264

最后想说的话:我只是目前测试发现这样没问题,一定要备份备份备份!!!之后万一出什么bug也不好说(((((