summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormayx <mayx@outlook.com>2026-05-21 10:11:01 +0000
committermayx <mayx@outlook.com>2026-05-21 10:11:01 +0000
commitd6274791a8f794d11e7e9acc58c3d45abe11a76c (patch)
treee416fe6f18460d6ba655b7f99e8db5b045cbd9cb
parent111dc1e25f43a1c783192d214a3697dee33bae82 (diff)
Update 2 files
- /assets/js/pjax.js - /index.html
-rw-r--r--assets/js/pjax.js65
-rw-r--r--index.html4
2 files changed, 52 insertions, 17 deletions
diff --git a/assets/js/pjax.js b/assets/js/pjax.js
index 3664392..e81b974 100644
--- a/assets/js/pjax.js
+++ b/assets/js/pjax.js
@@ -17,6 +17,7 @@
// ========== 工具函数 ==========
var _loadedScripts = {};
+ var _pendingScripts = [];
/** 动态加载外部 CSS(避免重复加载) */
function loadCSS(href) {
@@ -24,7 +25,11 @@
$('<link rel="stylesheet" href="' + href + '" />').appendTo('head');
}
- /** 动态加载外部 JS(去重) */
+ /**
+ * 动态加载外部 JS(避免重复)
+ * 用对象跟踪已加载的 URL,而不是检查 DOM 中的 <script> 标签
+ * (pjax 替换容器内容后,惰性 <script> 标签存在但不代表已执行)
+ */
function loadScript(src, callback) {
if (_loadedScripts[src]) {
if (typeof callback === 'function') callback();
@@ -37,6 +42,32 @@
document.body.appendChild(s);
}
+ /**
+ * 按顺序执行脚本数组(内联和外部混合)
+ * 外部脚本加载完成后再执行后续内联脚本,保持依赖顺序
+ */
+ function executeScripts(scripts) {
+ var idx = 0;
+ function runNext() {
+ while (idx < scripts.length) {
+ var s = scripts[idx];
+ idx++;
+ if (s.src) {
+ loadScript(s.src, runNext);
+ return; // 等待 onload 回调
+ }
+ try {
+ (window.execScript || function (code) {
+ window['eval'].call(window, code);
+ })(s.text);
+ } catch (e) {
+ console.warn('[pjax] inline script exec error:', e);
+ }
+ }
+ }
+ runNext();
+ }
+
// ========== 页面类型判断 ==========
/** 是否为文章页(非首页/分页) */
@@ -98,7 +129,7 @@
}
}
- /** AI 摘要(post.html 内联脚本,pjax 后触发) */
+ /** AI 摘要(post.html 内联脚本,pjax 后由 executeScripts 触发) */
function reinitAISummary() {
if (typeof ai_gen === 'function' && $('#ai-output').length) {
try { ai_gen(); } catch (e) { /* ignore */ }
@@ -231,16 +262,17 @@
$('body').removeClass('pjax-loading');
// 清理可能残留的浮层(如推荐文章 tooltip,hover 后点击跳转时 mouseleave 来不及触发)
$('.content-tooltip').hide();
+ // go() 路径:脚本在 DOM 替换前提取到了 _pendingScripts,需在此执行
+ // pjax 库路径:_pendingScripts 为空,pjax 库自行处理了脚本执行
+ if (_pendingScripts.length > 0) {
+ executeScripts(_pendingScripts);
+ _pendingScripts = [];
+ }
onPjaxComplete();
}
/** 暴露给模板内 onclick/onchange 调用的导航函数 */
window.go = function (url) {
- if (!url || url === '#') return;
- if (/^(https?:)?\/\//.test(url) || url.startsWith('mailto:')) {
- window.location.href = url;
- return;
- }
$('body').addClass('pjax-loading');
$.ajax({
url: url,
@@ -253,13 +285,16 @@
var doc = (new DOMParser()).parseFromString(html, 'text/html');
var fragment = doc.querySelector(CONTAINER);
if (fragment) {
- // 用 adoptNode 搬运所有子节点(包括 script 元素),让浏览器自行处理脚本执行
- // 这能正确支持 type="module"、顶层 await 等,避免手动提取重建的坑
- $(CONTAINER).empty(); // jQuery 清理旧元素的事件和数据,避免内存泄漏
- var container = document.querySelector(CONTAINER);
- while (fragment.firstChild) {
- container.appendChild(document.adoptNode(fragment.firstChild));
- }
+ // 先提取脚本(jQuery html() 会移除并可能异步处理脚本)
+ _pendingScripts = [];
+ fragment.querySelectorAll('script').forEach(function (s) {
+ _pendingScripts.push({
+ src: s.src || null,
+ text: s.textContent
+ });
+ s.remove();
+ });
+ $(CONTAINER).html(fragment.innerHTML);
document.title = doc.title;
history.pushState({ url: url }, document.title, url);
doPjaxComplete();
@@ -313,4 +348,4 @@
reinitCopyButtons();
});
-})(jQuery);
+})(jQuery); \ No newline at end of file
diff --git a/index.html b/index.html
index bd67f17..35e26be 100644
--- a/index.html
+++ b/index.html
@@ -12,7 +12,7 @@ image: https://screenshot.mayx.eu.org/
<!-- 遍历分页后的文章 -->
<table class="entry-content h-feed">
{% for post in paginator.posts %}
- <tr><td class="h-entry" onclick="go('{{ post.url }}')">
+ <tr><td class="h-entry" onclick="if (!event.target.closest('a.p-category')) go('{{ post.url }}')">
<h2 class="p-name"><a class="post-link u-url" href="{{ post.url }}">{{ post.title }}{% if post.layout == "encrypt" %} [加密] {% endif %}</a></h2>
<p>
<time class="date dt-published" datetime="{{ post.date | date_to_xmlschema }}">{{ post.date | date: "%-d %B %Y" }}</time>
@@ -24,7 +24,7 @@ image: https://screenshot.mayx.eu.org/
{% if post.tags %}
<span>
{% for tag in post.tags %}
- <a rel="category tag" class="p-category" href="/search.html?keyword={{ tag | uri_escape }}" onclick="event.stopPropagation()"><code style="white-space: nowrap">#{{ tag }}</code></a>
+ <a rel="category tag" class="p-category" href="/search.html?keyword={{ tag | uri_escape }}"><code style="white-space: nowrap">#{{ tag }}</code></a>
{% endfor %}
</span>
{% endif %}