mirror of https://github.com/Mabbs/mabbs.github.io
parent
111dc1e25f
commit
d6274791a8
|
|
@ -17,6 +17,7 @@
|
||||||
// ========== 工具函数 ==========
|
// ========== 工具函数 ==========
|
||||||
|
|
||||||
var _loadedScripts = {};
|
var _loadedScripts = {};
|
||||||
|
var _pendingScripts = [];
|
||||||
|
|
||||||
/** 动态加载外部 CSS(避免重复加载) */
|
/** 动态加载外部 CSS(避免重复加载) */
|
||||||
function loadCSS(href) {
|
function loadCSS(href) {
|
||||||
|
|
@ -24,7 +25,11 @@
|
||||||
$('<link rel="stylesheet" href="' + href + '" />').appendTo('head');
|
$('<link rel="stylesheet" href="' + href + '" />').appendTo('head');
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 动态加载外部 JS(去重) */
|
/**
|
||||||
|
* 动态加载外部 JS(避免重复)
|
||||||
|
* 用对象跟踪已加载的 URL,而不是检查 DOM 中的 <script> 标签
|
||||||
|
* (pjax 替换容器内容后,惰性 <script> 标签存在但不代表已执行)
|
||||||
|
*/
|
||||||
function loadScript(src, callback) {
|
function loadScript(src, callback) {
|
||||||
if (_loadedScripts[src]) {
|
if (_loadedScripts[src]) {
|
||||||
if (typeof callback === 'function') callback();
|
if (typeof callback === 'function') callback();
|
||||||
|
|
@ -37,6 +42,32 @@
|
||||||
document.body.appendChild(s);
|
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() {
|
function reinitAISummary() {
|
||||||
if (typeof ai_gen === 'function' && $('#ai-output').length) {
|
if (typeof ai_gen === 'function' && $('#ai-output').length) {
|
||||||
try { ai_gen(); } catch (e) { /* ignore */ }
|
try { ai_gen(); } catch (e) { /* ignore */ }
|
||||||
|
|
@ -231,16 +262,17 @@
|
||||||
$('body').removeClass('pjax-loading');
|
$('body').removeClass('pjax-loading');
|
||||||
// 清理可能残留的浮层(如推荐文章 tooltip,hover 后点击跳转时 mouseleave 来不及触发)
|
// 清理可能残留的浮层(如推荐文章 tooltip,hover 后点击跳转时 mouseleave 来不及触发)
|
||||||
$('.content-tooltip').hide();
|
$('.content-tooltip').hide();
|
||||||
|
// go() 路径:脚本在 DOM 替换前提取到了 _pendingScripts,需在此执行
|
||||||
|
// pjax 库路径:_pendingScripts 为空,pjax 库自行处理了脚本执行
|
||||||
|
if (_pendingScripts.length > 0) {
|
||||||
|
executeScripts(_pendingScripts);
|
||||||
|
_pendingScripts = [];
|
||||||
|
}
|
||||||
onPjaxComplete();
|
onPjaxComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 暴露给模板内 onclick/onchange 调用的导航函数 */
|
/** 暴露给模板内 onclick/onchange 调用的导航函数 */
|
||||||
window.go = function (url) {
|
window.go = function (url) {
|
||||||
if (!url || url === '#') return;
|
|
||||||
if (/^(https?:)?\/\//.test(url) || url.startsWith('mailto:')) {
|
|
||||||
window.location.href = url;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$('body').addClass('pjax-loading');
|
$('body').addClass('pjax-loading');
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: url,
|
url: url,
|
||||||
|
|
@ -253,13 +285,16 @@
|
||||||
var doc = (new DOMParser()).parseFromString(html, 'text/html');
|
var doc = (new DOMParser()).parseFromString(html, 'text/html');
|
||||||
var fragment = doc.querySelector(CONTAINER);
|
var fragment = doc.querySelector(CONTAINER);
|
||||||
if (fragment) {
|
if (fragment) {
|
||||||
// 用 adoptNode 搬运所有子节点(包括 script 元素),让浏览器自行处理脚本执行
|
// 先提取脚本(jQuery html() 会移除并可能异步处理脚本)
|
||||||
// 这能正确支持 type="module"、顶层 await 等,避免手动提取重建的坑
|
_pendingScripts = [];
|
||||||
$(CONTAINER).empty(); // jQuery 清理旧元素的事件和数据,避免内存泄漏
|
fragment.querySelectorAll('script').forEach(function (s) {
|
||||||
var container = document.querySelector(CONTAINER);
|
_pendingScripts.push({
|
||||||
while (fragment.firstChild) {
|
src: s.src || null,
|
||||||
container.appendChild(document.adoptNode(fragment.firstChild));
|
text: s.textContent
|
||||||
}
|
});
|
||||||
|
s.remove();
|
||||||
|
});
|
||||||
|
$(CONTAINER).html(fragment.innerHTML);
|
||||||
document.title = doc.title;
|
document.title = doc.title;
|
||||||
history.pushState({ url: url }, document.title, url);
|
history.pushState({ url: url }, document.title, url);
|
||||||
doPjaxComplete();
|
doPjaxComplete();
|
||||||
|
|
@ -313,4 +348,4 @@
|
||||||
reinitCopyButtons();
|
reinitCopyButtons();
|
||||||
});
|
});
|
||||||
|
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
|
@ -12,7 +12,7 @@ image: https://screenshot.mayx.eu.org/
|
||||||
<!-- 遍历分页后的文章 -->
|
<!-- 遍历分页后的文章 -->
|
||||||
<table class="entry-content h-feed">
|
<table class="entry-content h-feed">
|
||||||
{% for post in paginator.posts %}
|
{% 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>
|
<h2 class="p-name"><a class="post-link u-url" href="{{ post.url }}">{{ post.title }}{% if post.layout == "encrypt" %} [加密] {% endif %}</a></h2>
|
||||||
<p>
|
<p>
|
||||||
<time class="date dt-published" datetime="{{ post.date | date_to_xmlschema }}">{{ post.date | date: "%-d %B %Y" }}</time>
|
<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 %}
|
{% if post.tags %}
|
||||||
<span>
|
<span>
|
||||||
{% for tag in post.tags %}
|
{% 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 %}
|
{% endfor %}
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue