1
0
Fork 0
blog/content/posts/百草园/解决Swup导致的JavaScript加载失效问题.md

129 lines
5.6 KiB
Markdown
Raw Normal View History

---
slug: swup-modifying
summary: 解题方法:瞪眼法(确信)
tags:
- 博客
- 折腾
title: 解决Swup导致的JavaScript加载失效问题
date: 2024-07-26
description: 本文记录了作者修复 Swup 下 JavaScript 加载问题的过程。作者发现页面功能如评论和代码复制无法正常加载,经过排查发现 Swup 仅替换页面的 HTML 内容,而未加载新页面的 JavaScript。作者随后找到了解决方案使用 Swup 的 Script Plugin 来确保 JavaScript 被正确加载。最后,作者针对评论功能做了额外处理,确保 Twikoo 评论系统可以正常工作。虽然该方案还未完全完善,但已基本解决问题。
categories: ["百草园"]
featuredImage:
draft: false
---
各位老友们好,我是 Chlorine。本期又是前端小白的魔改历险记。
## 前言
我目前使用的主题 Efímero 是我基于 [Hugo Landscape](https://github.com/kkbt0/Hugo-Landscape) 的魔改版本。Landscape 使用 Swup 作为页面的过渡,平滑的效果深得我心。
但是在我的网站使用过程中遇到了一个很烦人的问题:有一些功能常常加载不出来,比方说说说页面、代码一键复制、评论等等。奇怪的是,刷新一次就好了。
之前我并没怎么在意这件事。但是由于今天太闲且强迫症作祟,我就想着修复一下。
## 踩坑
我的切入点是我的说说页面 `whisper.html`。我相当肯定问题在 JavaScript 部分(毕竟 HTML 和 CSS 能有什么坏心思捏然而凭借我有限的知识看了半天还是无果AI 也不行。
我打开了控制台,发现在初次加载的时候,报出了错误:
```bash
Hooks.ts:435 Error in hook 'page:view': ReferenceError: init is not defined
at VM35:6:36
at index.ts:37:2
at new Promise (<anonymous>)
at Hooks.ts:433:8
at index.ts:37:31
at Hooks.ts:435:26
at t (Hooks.ts:438:6)
whisper/:1385 Uncaught ReferenceError: init is not defined
at HTMLDocument.<anonymous> (whisper/:1385:101)
```
看起来有一个神秘的 `init` 没有定义。我相当肯定我的 `whisper` 中没有什么 `init`,但是问题都摆在眼前了,总不能摆烂(~~还真能~~)。
前往定义,在挖呀挖呀挖了半天后,终于发现了一个所谓的 `init`
```js
const swup = new Swup({
plugins: [new SwupPreloadPlugin()]
});
document.readyState === "complete" ? init() : document.addEventListener("DOMContentLoaded", ()=>init()),
swup.hooks.on("page:view", ()=>init())
```
嘶,好像有点熟,但是也就是有点熟,然后就没有然后了。
试着在项目里搜索这段代码,还真有,在 `baseof.html` 中。这看起来是创建了一个 JavaScript 的 `swup` 实例。把 `init` 去掉,发现不报错了,但是还是不行;随便写一个 `init`,发现还是没用。
中间经过了多少稀奇古怪的尝试我已经忘了。不过我是一点不慌,别问,问就是 Git 配享太庙。
## 福至心灵
一筹莫展之际,我又仔细翻了翻代码,发现了个正常到不能再正常的事情,就是 `document.addEventListener`。我不太了解 JavaScript但是前几天写 Java+XML 的经验让我大致能猜出其意思。二者的绑定方式还有点像。
嗯?既然 `document.addEventListener` 是在页面加载完的时候进行,**那如果页面没加载完呢?更进一步,如果根本没加载呢?**
听上去荒谬但是我瞬间来精神了。Swup 能做到切换这么丝滑,难道是根本没加载新的页面,只是做了点替换?
说干就干,我在我的 HTML 顶端加了条测试语句:
```html
<script>
console.log("whisper.html");
</script>
```
然后重启本地服务器,打开控制台……果然没打印!
破案了家人们,这个 Swup 根本没加载新的页面——至少是没加载新页面的 JavaScript。而刷新会强制加载这个页面所以就好使了而前面的 `baseof` 的代码,就是让 Swup 接管这些加载活动。
那下面就想办法解决好了。我翻了半天,在[这里](https://swup.js.org/getting-started/reloading-javascript/)找到了解决方法(准确来说是被 issue 引过去的)。琢磨了一会儿,我决定采取省事的 Script Plugin。至于内存泄漏算了先不管了。
```html
<script src="https://unpkg.com/@swup/scripts-plugin@2"></script>
{{/* ... */}}
<script data-swup-ignore-script>
document.addEventListener('DOMContentLoaded', function() {
const swup = new Swup({
plugins: [
new SwupPreloadPlugin(),
new SwupScriptsPlugin()
]
});
});
</script>
```
速度慢的话可以自己去找镜像。
## 评论
其他部分都好了,就是这个评论还是不行。找了半天,发现是按钮本身绑定的 JavaScript 的事情。
首先把 Twikoo 的 CDN JavaScript 单独拎出来加载,然后再加一个钩子:
```js
swup.hooks.on('page:view', () => {
const loadCommentsBtn = document.getElementById('load-comments-btn');
if (loadCommentsBtn) {
loadCommentsBtn.addEventListener('click', function () {
const container = document.getElementById('comments-container');
if (container) {
container.style.display = 'block'; // 显示评论容器
this.style.display = 'none'; // 隐藏按钮
}
});
}
});
```
目前这个方案虽然还不完善,但是已经可以用了。
## 结语
本来打算过几天在高铁上写的,但是太过激动,今天就写出来了。
马上要大作业验收啦……祝我好运!