From f47f03c33c1a66a5f409ee76ef0a3b136b4f7da2 Mon Sep 17 00:00:00 2001 From: Vaica <94612053+zqlit@users.noreply.github.com> Date: Thu, 25 Jun 2026 19:07:58 +0800 Subject: [PATCH] 1907 --- themes/Ying/assets/js/modules/artalk.js | 166 +++++++++++++---------- themes/Ying/layouts/partials/footer.html | 6 +- themes/Ying/layouts/partials/head.html | 2 +- 3 files changed, 102 insertions(+), 72 deletions(-) diff --git a/themes/Ying/assets/js/modules/artalk.js b/themes/Ying/assets/js/modules/artalk.js index 36b73ff1..806b0654 100644 --- a/themes/Ying/assets/js/modules/artalk.js +++ b/themes/Ying/assets/js/modules/artalk.js @@ -20,123 +20,153 @@ var saveInitCount = function() { // ── 增强评论框字段 (PJAX 适配版本) ── // 在 Artalk 完全加载前就开始监控,确保油猴脚本能识别到字段 window.__artalkEnhancer = window.__artalkEnhancer || { - observers: [], - doneEditors: new WeakSet(), + observer: null, + running: false, enhance: function() { - var editors = document.querySelectorAll('.atk-editor'); var self = this; + var count = 0; - editors.forEach(function(editor) { - if (self.doneEditors.has(editor)) return; - self.doneEditors.add(editor); - - // 昵称输入框 - var nickInput = editor.querySelector('input[name="nick"]'); - if (nickInput && !nickInput.getAttribute('data-autofill-done')) { - nickInput.setAttribute('autocomplete', 'name'); - nickInput.setAttribute('aria-label', '昵称 author nick name user'); - nickInput.classList.add('comment-author', 'user-nick', 'user-name', 'user-displayname'); - nickInput.setAttribute('data-autofill-done', '1'); - } - - // 邮箱输入框 - var emailInput = editor.querySelector('input[name="email"]'); - if (emailInput && !emailInput.getAttribute('data-autofill-done')) { - emailInput.setAttribute('autocomplete', 'email'); - emailInput.setAttribute('aria-label', '邮箱 email mail'); - emailInput.classList.add('comment-email', 'user-email', 'user-mail'); - emailInput.setAttribute('data-autofill-done', '1'); - } - - // 网址输入框 - var linkInput = editor.querySelector('input[name="link"]'); - if (linkInput && !linkInput.getAttribute('data-autofill-done')) { - linkInput.setAttribute('autocomplete', 'url'); - linkInput.setAttribute('aria-label', '网址 website url link homepage site web'); - linkInput.classList.add('comment-url', 'user-link', 'user-website', 'user-site', 'user-web'); - linkInput.setAttribute('data-autofill-done', '1'); - } - - // 内容输入框(避免被误识别为昵称) - var contentInput = editor.querySelector('textarea[name="content"]'); - if (contentInput && !contentInput.getAttribute('data-autofill-done')) { - contentInput.setAttribute('autocomplete', 'off'); - contentInput.setAttribute('aria-label', '评论内容 content comment message'); - contentInput.setAttribute('data-autofill-done', '1'); - } + // 昵称输入框 + var nickInputs = document.querySelectorAll('input[name="nick"]:not([data-autofill-done])'); + nickInputs.forEach(function(input) { + input.setAttribute('autocomplete', 'name'); + input.setAttribute('aria-label', '昵称 author nick name user'); + input.classList.add('comment-author', 'user-nick', 'user-name', 'user-displayname', '昵称'); + input.setAttribute('data-autofill-done', '1'); + count++; }); + + // 邮箱输入框 + var emailInputs = document.querySelectorAll('input[name="email"]:not([data-autofill-done])'); + emailInputs.forEach(function(input) { + input.setAttribute('autocomplete', 'email'); + input.setAttribute('aria-label', '邮箱 email mail'); + input.classList.add('comment-email', 'user-email', 'user-mail', '邮箱'); + input.setAttribute('data-autofill-done', '1'); + count++; + }); + + // 网址输入框 + var linkInputs = document.querySelectorAll('input[name="link"]:not([data-autofill-done])'); + linkInputs.forEach(function(input) { + input.setAttribute('autocomplete', 'url'); + input.setAttribute('aria-label', '网址 website url link homepage site web'); + input.classList.add('comment-url', 'user-link', 'user-website', 'user-site', 'user-web', '网址'); + input.setAttribute('data-autofill-done', '1'); + count++; + }); + + // 内容输入框(避免被误识别为昵称) + var contentInputs = document.querySelectorAll('textarea[name="content"]:not([data-autofill-done])'); + contentInputs.forEach(function(input) { + input.setAttribute('autocomplete', 'off'); + input.setAttribute('aria-label', '评论内容 content comment message'); + input.setAttribute('data-autofill-done', '1'); + count++; + }); + + if (count > 0 && window.console && console.log) { + console.log('[ArtalkEnhancer] 增强了 ' + count + ' 个评论输入框'); + } + + return count; }, // 监控 DOM 变化(PJAX 切换、动态加载) observe: function() { var self = this; if (typeof MutationObserver === 'undefined') return; + if (this.observer) return; - // 清理旧 observer - this.observers.forEach(function(o) { o.disconnect(); }); - this.observers = []; - - var observer = new MutationObserver(function(mutations) { + this.observer = new MutationObserver(function(mutations) { + var shouldEnhance = false; for (var i = 0; i < mutations.length; i++) { var added = mutations[i].addedNodes; for (var j = 0; j < added.length; j++) { var node = added[j]; if (node.nodeType === 1) { - if (node.classList && node.classList.contains('atk-editor')) { - self.enhance(); + // 检查是否是 input 或 textarea 元素 + if (node.tagName === 'INPUT' || node.tagName === 'TEXTAREA') { + shouldEnhance = true; + break; } + // 检查子节点 if (node.querySelectorAll) { - var nestedEditors = node.querySelectorAll('.atk-editor'); - if (nestedEditors.length > 0) { - self.enhance(); + var inputs = node.querySelectorAll('input, textarea'); + if (inputs.length > 0) { + shouldEnhance = true; + break; } } } } + if (shouldEnhance) break; + } + if (shouldEnhance) { + // 稍微延迟,确保 DOM 完全插入 + setTimeout(function() { self.enhance(); }, 10); } }); - observer.observe(document.body, { childList: true, subtree: true }); - this.observers.push(observer); + this.observer.observe(document.body, { childList: true, subtree: true }); }, - // 启动全局监控(在脚本加载时执行一次) + // 启动全局监控 start: function() { + if (this.running) return; + this.running = true; + + if (window.console && console.log) { + console.log('[ArtalkEnhancer] 启动评论框字段增强'); + } + + // 立即尝试增强一次 this.enhance(); + + // 启动 DOM 监控 this.observe(); + + // 兜底:定时检查(Artalk 加载慢时) + var checkCount = 0; + var maxChecks = 20; // 最多检查 20 次(10 秒) + var interval = setInterval(function() { + checkCount++; + var enhanced = window.__artalkEnhancer.enhance(); + if (enhanced > 0 || checkCount >= maxChecks) { + clearInterval(interval); + } + }, 500); } }; -// 页面加载时启动全局监控 -if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', function() { - window.__artalkEnhancer.start(); - }); -} else { +// 立即启动(不等待 DOMContentLoaded,尽早开始监控) +if (typeof window.__artalkEnhancer !== 'undefined') { window.__artalkEnhancer.start(); } -// 监听 PJAX 切换:立即增强(Artalk 实例被销毁后,新实例加载前的过渡期) +// 监听 PJAX 切换:重置并重新增强 document.addEventListener('pjax:send', function() { - // 重置已处理记录(让新页面的评论框能重新增强) - if (window.__artalkEnhancer) { - window.__artalkEnhancer.doneEditors = new WeakSet(); + if (window.__artalkEnhancer && window.console && console.log) { + console.log('[ArtalkEnhancer] PJAX 切换,准备重新增强'); } }); document.addEventListener('pjax:success', function() { - // 立即增强新页面的评论框 if (window.__artalkEnhancer) { + // 立即尝试 window.__artalkEnhancer.enhance(); + // 延迟再试(Artalk 重新初始化需要时间) + setTimeout(function() { window.__artalkEnhancer.enhance(); }, 200); + setTimeout(function() { window.__artalkEnhancer.enhance(); }, 500); + setTimeout(function() { window.__artalkEnhancer.enhance(); }, 1000); } }); document.addEventListener('pjax:complete', function() { - // 完整加载后再增强一次 if (window.__artalkEnhancer) { - setTimeout(function() { window.__artalkEnhancer.enhance(); }, 100); - setTimeout(function() { window.__artalkEnhancer.enhance(); }, 500); + setTimeout(function() { window.__artalkEnhancer.enhance(); }, 300); + setTimeout(function() { window.__artalkEnhancer.enhance(); }, 800); } }); window.loadScriptOnce = window.loadScriptOnce || function(src, globalName, callback) { diff --git a/themes/Ying/layouts/partials/footer.html b/themes/Ying/layouts/partials/footer.html index f77a14ef..cc82ffa4 100644 --- a/themes/Ying/layouts/partials/footer.html +++ b/themes/Ying/layouts/partials/footer.html @@ -64,9 +64,10 @@ {{ $pangu := resources.Get "js/modules/pangu.js" }} {{ $linkify := resources.Get "js/modules/linkify.js" }} {{ $shortcodesJs := resources.Get "js/shortcodes.js" }} +{{ $lazyload := resources.Get "js/modules/lazyload.js" }} {{ $main := resources.Get "js/main.js" }} -{{ $coreScripts := slice $iconfont $uikit $viewimage $utils $loader $cache $search $floatingTools $nprogress $pjaxLib $mypjax $pangu $linkify $shortcodesJs $main | resources.Concat "js/core.js" | resources.Minify | resources.Fingerprint }} +{{ $coreScripts := slice $iconfont $uikit $viewimage $utils $loader $cache $search $floatingTools $nprogress $pjaxLib $mypjax $pangu $linkify $shortcodesJs $lazyload $main | resources.Concat "js/core.js" | resources.Minify | resources.Fingerprint }} @@ -170,9 +171,8 @@ {{/* ====== 5. 延迟加载的非关键JS ====== */}} {{ $toast := resources.Get "js/modules/toast.js" }} -{{ $easylazyload := resources.Get "js/modules/lazyload.js" }} -{{ $deferredScripts := slice $toast $easylazyload | resources.Concat "js/deferred.js" | resources.Minify | resources.Fingerprint }} +{{ $deferredScripts := slice $toast | resources.Concat "js/deferred.js" | resources.Minify | resources.Fingerprint }} - + {{ $echartsHead := resources.Get "js/libs/echarts.min.js" | resources.Fingerprint }} {{ $artalkHead := resources.Get "js/libs/Artalk.js" | resources.Fingerprint }}