Files
argon-theme/argontheme.js
nanhaoluo 549fec6a53 fix: 移除向后兼容代码并修复黑幕样式
- 移除 showLoadingOverlay 和 hideLoadingOverlay 向后兼容函数
- 直接使用 PageLoader.show() 和 PageLoader.hide()
- 重构黑幕样式,添加文章内容选择器支持
- 优化夜间模式黑幕颜色(#1a1a1a)
- 添加 article .entry-content 和 .article-content 选择器
- 确保黑幕在所有文章容器中正常显示
- 改进代码结构和注释
2026-01-27 16:56:32 +08:00

5085 lines
162 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*!
* Argon 主题核心 JavaScript
*/
// ========== 兼容性修复 ==========
// 确保 Prism 和 autoloader 存在
if (typeof window.Prism === 'undefined') {
window.Prism = {
highlightAll: function() {},
highlightElement: function() {},
plugins: {}
};
}
if (typeof window.Prism.plugins === 'undefined') {
window.Prism.plugins = {};
}
if (typeof window.Prism.plugins.autoloader === 'undefined') {
window.Prism.plugins.autoloader = {
languages_path: '',
use_minified: true
};
}
// 确保 Zoomify 存在
if (typeof window.Zoomify === 'undefined') {
window.Zoomify = function() {};
window.Zoomify.DEFAULTS = {};
}
// 确保 jQuery 插件存在
if (typeof jQuery !== 'undefined') {
(function($) {
// 确保 easing 函数存在(防止其他插件覆盖 jQuery 后丢失)
if (typeof $.easing === 'undefined') {
$.easing = {};
}
if (typeof $.easing.easeOutCirc === 'undefined') {
$.easing.easeOutCirc = function(x) {
return Math.sqrt(1 - Math.pow(x - 1, 2));
};
}
if (typeof $.easing.easeOutExpo === 'undefined') {
$.easing.easeOutExpo = function(x) {
return x === 1 ? 1 : 1 - Math.pow(2, -10 * x);
};
}
if (!$.fn._argonInit) {
$.fn._argonInit = $.fn.init;
$.fn.init = function(selector, context, root) {
// 修复空选择器、特殊字符和中文标点导致的语法错误
if (typeof selector === 'string') {
let trimmed = selector.trim();
// 检查是否为空或只有 # 符号
if (trimmed === '' || trimmed === '#') {
return new $.fn._argonInit();
}
// 检查是否包含中文标点(可能导致语法错误)
if (/[;,。:!?]/.test(trimmed)) {
console.warn('[Argon] Invalid selector with Chinese punctuation:', selector);
return new $.fn._argonInit();
}
// 检查 ID 选择器是否有效(#后面必须有内容)
if (/^#\s*$/.test(trimmed)) {
return new $.fn._argonInit();
}
}
return $.fn._argonInit.call(this, selector, context, root);
};
$.fn.init.prototype = $.fn;
}
// 确保 zoomify 插件存在
if (typeof $.fn.zoomify === 'undefined') {
$.fn.zoomify = function() { return this; };
}
// 确保 fancybox 存在
if (typeof $.fancybox === 'undefined') {
$.fancybox = {
defaults: {
transitionEffect: 'slide',
buttons: [],
lang: 'zh_CN',
i18n: {}
},
open: function() {},
close: function() {}
};
}
if (typeof $.fancybox.defaults === 'undefined') {
$.fancybox.defaults = {
transitionEffect: 'slide',
buttons: [],
lang: 'zh_CN',
i18n: {}
};
}
// 确保 pjax 存在
if (typeof $.pjax === 'undefined') {
$.pjax = function() {};
$.pjax.defaults = {
timeout: 10000,
container: [],
fragment: []
};
}
if (typeof $.pjax.defaults === 'undefined') {
$.pjax.defaults = {
timeout: 10000,
container: [],
fragment: []
};
}
})(jQuery);
}
// ==========================================================================
// 性能优化模块引入
// ==========================================================================
// 注意argon-performance.js 需要在此文件之前加载
// 在 functions.php 中通过 wp_enqueue_script 确保加载顺序
//
// 提供的优化功能:
// - ArgonDOMCache: DOM 元素缓存系统
// - ArgonEventManager: 事件节流和防抖
// - ArgonResourceLoader: 资源按需加载
// - ArgonRenderOptimizer: 渲染优化和 GPU 加速
// - ArgonMemoryManager: 内存管理和清理
// - ArgonPerformanceMonitor: 性能监控和分析
// ==========================================================================
// ========== 原有代码 ==========
if (typeof(argonConfig) == "undefined"){
var argonConfig = {};
}
if (typeof(argonConfig.wp_path) == "undefined"){
argonConfig.wp_path = "/";
}
// ==========================================================================
// 性能优化模块实例(全局变量)
// ==========================================================================
var argonDOMCache = null; // DOM 缓存实例
var argonEventManager = null; // 事件管理实例
var argonResourceLoader = null; // 资源加载实例
var argonRenderOptimizer = null; // 渲染优化实例
var argonMemoryManager = null; // 内存管理实例
var argonPerformanceMonitor = null; // 性能监控实例
// ==========================================================================
// 调试控制台(由 argon-performance.js 引入)
// ==========================================================================
// 如果 ArgonDebug 未定义,创建一个简单的替代实现
if (typeof ArgonDebug === 'undefined') {
window.ArgonDebug = {
enabled: false,
init() {
if (typeof argonConfig !== 'undefined' && argonConfig.debug_mode) {
this.enabled = true;
}
},
log(...args) { if (this.enabled) console.log('[Argon]', ...args); },
warn(...args) { if (this.enabled) console.warn('[Argon]', ...args); },
error(...args) { if (this.enabled) console.error('[Argon]', ...args); },
info(...args) { if (this.enabled) console.info('[Argon]', ...args); }
};
ArgonDebug.init();
}
/*Cookies 操作*/
function setCookie(cname, cvalue, exdays) {
let d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
let expires = "expires=" + d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie(cname) {
let name = cname + "=";
let decodedCookie = decodeURIComponent(document.cookie);
let ca = decodedCookie.split(';');
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
/*多语言支持*/
var translation = {};
translation['en_US'] = {
"确定": "OK",
"清除": "Clear",
"恢复博客默认": "Set To Default",
"评论内容不能为空": "Comment content cannot be empty",
"昵称不能为空": "Name cannot be empty",
"邮箱或QQ号格式错误": "Incorrect email or QQ format",
"邮箱格式错误": "Incorrect email format",
"网站格式错误 (不是 http(s):// 开头)": "Website URL format error",
"验证码未输入": "CAPTCHA cannot be empty",
"验证码格式错误": "Incorrect CAPTCHA format",
"请完成验证码验证": "Please complete CAPTCHA verification",
"评论格式错误": "Comment format error",
"发送中": "Sending",
"正在发送": "Sending",
"评论正在发送中...": "Comment is sending...",
"发送": "Send",
"评论发送失败": "Comment failed",
"发送成功": "Success",
"您的评论已发送": "Your comment has been sent",
"评论": "Comments",
"未知原因": "Unknown Error",
"编辑中": "Editing",
"正在编辑": "Editing",
"评论正在编辑中...": "Comment is being edited...",
"编辑": "Edit",
"评论编辑失败": "Comment editing failed",
"已编辑": "Edited",
"编辑成功": "Success",
"您的评论已编辑": "Your comment has been edited",
"评论 #": "Comment #",
"的编辑记录": "- Edit History",
"加载失败": "Failed to load",
"展开": "Show",
"没有更多了": "No more comments",
"找不到该 Repo": "Can't find the repository",
"获取 Repo 信息失败": "Failed to get repository information",
"点赞失败": "Vote failed",
"Hitokoto 获取失败": "Failed to get Hitokoto",
"复制成功": "Copied",
"代码已复制到剪贴板": "Code has been copied to the clipboard",
"复制失败": "Failed",
"请手动复制代码": "Please copy the code manually",
"刚刚": "Now",
"分钟前": "minutes ago",
"小时前": "hours ago",
"昨天": "Yesterday",
"前天": "The day before yesterday",
"天前": "days ago",
"隐藏行号": "Hide Line Numbers",
"显示行号": "Show Line Numbers",
"开启折行": "Enable Break Line",
"关闭折行": "Disable Break Line",
"复制": "Copy",
"全屏": "Fullscreen",
"退出全屏": "Exit Fullscreen",
"置顶评论": "Pin Comment",
"取消置顶评论": "Unpin Comment",
"是否要取消置顶评论 #": "Do you want to unpin the comment #",
"是否要置顶评论 #": "Do you want to pin the comment #",
"确认": "Confirm",
"取消": "Cancel",
"置顶": "Pin",
"取消置顶": "Unpin",
"置顶成功": "Pinned",
"取消置顶成功": "Unpinned",
"该评论已置顶": "The comment has been pinned",
"该评论已取消置顶": "The comment has been unpinned",
"置顶失败": "Failed to pin",
"取消置顶失败": "Failed to unpin",
};
translation['ru_RU'] = {
"确定": "ОК",
"清除": "Очистить",
"恢复博客默认": "Восстановить по умолчанию",
"评论内容不能为空": "Содержимое комментария не может быть пустым",
"昵称不能为空": "Имя не может быть пустым",
"邮箱或QQ号格式错误": "Неверный формат электронной почты или QQ",
"邮箱格式错误": "Неправильный формат электронной почты",
"网站格式错误 (不是 http(s):// 开头)": "Сайт ошибка формата URL-адреса ",
"验证码未输入": "Вы не решили капчу",
"验证码格式错误": "Ошибка проверки капчи",
"评论格式错误": "Неправильный формат комментария",
"发送中": "Отправка",
"正在发送": "Отправка",
"评论正在发送中...": "Комментарий отправляется...",
"发送": "Отправить",
"评论发送失败": "Не удалось отправить комментарий",
"发送成功": "Комментарий отправлен",
"您的评论已发送": "Ваш комментарий был отправлен",
"评论": "Комментарии",
"未知原因": "Неизвестная ошибка",
"编辑中": "Редактируется",
"正在编辑": "Редактируется",
"评论正在编辑中...": "Комментарий редактируется",
"编辑": "Редактировать",
"评论编辑失败": "Не удалось отредактировать комментарий",
"已编辑": "Изменено",
"编辑成功": "Успешно",
"您的评论已编辑": "Ваш комментарий был изменен",
"评论 #": "Комментарий #",
"的编辑记录": "- История изменений",
"加载失败": "Ошибка загрузки",
"展开": "Показать",
"没有更多了": "Комментариев больше нет",
"找不到该 Repo": "Невозможно найти репозиторий",
"获取 Repo 信息失败": "Неудалось получить информацию репозитория",
"点赞失败": "Ошибка голосования",
"Hitokoto 获取失败": "Проблемы с вызовом Hitokoto",
"复制成功": "Скопировано",
"代码已复制到剪贴板": "Код скопирован в буфер обмена",
"复制失败": "Неудалось",
"请手动复制代码": "Скопируйте код вручную",
"刚刚": "Сейчас",
"分钟前": "минут назад",
"小时前": "часов назад",
"昨天": "Вчера",
"前天": "Позавчера",
"天前": "дней назад",
"隐藏行号": "Скрыть номера строк",
"显示行号": "Показать номера строк",
"开启折行": "Включить перенос строк",
"关闭折行": "Выключить перенос строк",
"复制": "Скопировать",
"全屏": "Полноэкранный режим",
"退出全屏": "Выход из полноэкранного режима",
};
translation['zh_TW'] = {
"确定": "確定",
"清除": "清除",
"恢复博客默认": "恢復博客默認",
"评论内容不能为空": "評論內容不能為空",
"昵称不能为空": "昵稱不能為空",
"邮箱或QQ号格式错误": "郵箱或QQ號格式錯誤",
"邮箱格式错误": "郵箱格式錯誤",
"网站格式错误 (不是 http(s):// 开头)": "網站格式錯誤 (不是 http(s):// 開頭)",
"验证码未输入": "驗證碼未輸入",
"验证码格式错误": "驗證碼格式錯誤",
"评论格式错误": "評論格式錯誤",
"发送中": "發送中",
"正在发送": "正在發送",
"评论正在发送中...": "評論正在發送中...",
"发送": "發送",
"评论发送失败": "評論發送失敗",
"发送成功": "發送成功",
"您的评论已发送": "您的評論已發送",
"评论": "評論",
"未知原因": "未知原因",
"编辑中": "編輯中",
"正在编辑": "正在編輯",
"评论正在编辑中...": "評論正在編輯中...",
"编辑": "編輯",
"评论编辑失败": "評論編輯失敗",
"已编辑": "已編輯",
"编辑成功": "編輯成功",
"您的评论已编辑": "您的評論已編輯",
"评论 #": "評論 #",
"的编辑记录": "的編輯記錄",
"加载失败": "加載失敗",
"展开": "展開",
"没有更多了": "沒有更多了",
"找不到该 Repo": "找不到該 Repo",
"获取 Repo 信息失败": "獲取 Repo 信息失敗",
"点赞失败": "點贊失敗",
"Hitokoto 获取失败": "Hitokoto 獲取失敗",
"复制成功": "復制成功",
"代码已复制到剪贴板": "代碼已復制到剪貼板",
"复制失败": "復制失敗",
"请手动复制代码": "請手動復制代碼",
"刚刚": "剛剛",
"分钟前": "分鐘前",
"小时前": "小時前",
"昨天": "昨天",
"前天": "前天",
"天前": "天前",
"隐藏行号": "隱藏行號",
"显示行号": "顯示行號",
"开启折行": "開啟折行",
"关闭折行": "關閉折行",
"复制": "復制",
"全屏": "全屏",
"退出全屏": "退出全屏",
};
function __(text){
let lang = argonConfig.language;
if (typeof(translation[lang]) == "undefined"){
return text;
}
if (typeof(translation[lang][text]) == "undefined"){
return text;
}
return translation[lang][text];
}
/*根据滚动高度改变顶栏透明度 */
!function(){
let toolbar = document.getElementById("navbar-main");
let $bannerContainer = $("#banner_container");
let $content = $("#content");
let startTransitionHeight;
let endTransitionHeight;
let maxOpacity = 0.85;
startTransitionHeight = $bannerContainer.offset().top - 75;
endTransitionHeight = $content.offset().top - 75;
$(window).resize(function(){
startTransitionHeight = $bannerContainer.offset().top - 75;
endTransitionHeight = $content.offset().top - 75;
});
function changeToolbarTransparency(){
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if (scrollTop < startTransitionHeight){
toolbar.style.setProperty('background-color', 'rgba(var(--toolbar-color), 0)', 'important');
toolbar.style.setProperty('box-shadow', 'none');
if (argonConfig.toolbar_blur){
toolbar.style.setProperty('backdrop-filter', 'blur(0px)');
}
toolbar.classList.add("navbar-ontop");
return;
}
if (scrollTop > endTransitionHeight){
toolbar.style.setProperty('background-color', 'rgba(var(--toolbar-color), ' + maxOpacity + ')', 'important');
toolbar.style.setProperty('box-shadow', '');
if (argonConfig.toolbar_blur){
toolbar.style.setProperty('backdrop-filter', 'blur(16px)');
}
toolbar.classList.remove("navbar-ontop");
return;
}
let transparency = (scrollTop - startTransitionHeight) / (endTransitionHeight - startTransitionHeight) * maxOpacity;
toolbar.style.setProperty('background-color', 'rgba(var(--toolbar-color), ' + transparency, 'important');
toolbar.style.setProperty('box-shadow', '');
if (argonConfig.toolbar_blur){
if ((scrollTop - startTransitionHeight) / (endTransitionHeight - startTransitionHeight) > 0.3){
toolbar.style.setProperty('backdrop-filter', 'blur(16px)');
}else{
toolbar.style.setProperty('backdrop-filter', 'blur(0px)');
}
}
toolbar.classList.remove("navbar-ontop");
}
function changeToolbarOnTopClass(){
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if (scrollTop < 30){
toolbar.classList.add("navbar-no-blur");
}else{
toolbar.classList.remove("navbar-no-blur");
}
}
if ($("html").hasClass("no-banner")) {
changeToolbarOnTopClass();
// 使用节流优化滚动事件性能
const throttledChangeToolbarOnTopClass = argonEventManager ?
argonEventManager.throttle(changeToolbarOnTopClass, 16) :
changeToolbarOnTopClass;
document.addEventListener("scroll", throttledChangeToolbarOnTopClass, {passive: true});
return;
}
if (argonConfig.headroom == "absolute") {
toolbar.classList.add("navbar-ontop");
return;
}
if ($("html").hasClass("toolbar-blur")) {
argonConfig.toolbar_blur = true;
maxOpacity = 0.65;
}else{
argonConfig.toolbar_blur = false;
}
changeToolbarTransparency();
// 使用节流优化滚动事件性能
const throttledChangeToolbarTransparency = argonEventManager ?
argonEventManager.throttle(changeToolbarTransparency, 16) :
changeToolbarTransparency;
document.addEventListener("scroll", throttledChangeToolbarTransparency, {passive: true});
}();
/*搜索*/
function searchPosts(word){
if ($(".search-result").length > 0){
let url = new URL(window.location.href);
url.searchParams.set("s", word);
$.pjax({
url: url.href
});
}else{
$.pjax({
url: argonConfig.wp_path + "?s=" + encodeURI(word)
});
}
}
/*顶栏搜索*/
$(document).on("click" , "#navbar_search_input_container" , function(){
$(this).addClass("open");
$("#navbar_search_input").focus();
});
$(document).on("blur" , "#navbar_search_input_container" , function(){
// 如果有文字则保持has-text类
if ($("#navbar_search_input").val().trim() !== "") {
$(this).addClass("has-text");
} else {
$(this).removeClass("has-text");
}
$(this).removeClass("open");
});
// 监听输入变化来切换has-text类
$(document).on("input" , "#navbar_search_input" , function(){
var container = $("#navbar_search_input_container");
if ($(this).val().trim() !== "") {
container.addClass("has-text");
} else {
container.removeClass("has-text");
}
});
$(document).on("keydown" , "#navbar_search_input_container #navbar_search_input" , function(e){
if (e.keyCode != 13){
return;
}
let word = $(this).val();
if (word == ""){
$("#navbar_search_input_container").blur();
return;
}
let scrolltop = $(document).scrollTop();
searchPosts(word);
});
/*顶栏搜索 (Mobile)*/
$(document).on("keydown" , "#navbar_search_input_mobile" , function(e){
if (e.keyCode != 13){
return;
}
let word = $(this).val();
$("#navbar_global .collapse-close button").click();
if (word == ""){
return;
}
let scrolltop = $(document).scrollTop();
searchPosts(word);
});
/*侧栏搜索*/
$(document).on("click" , "#leftbar_search_container" , function(){
$(".leftbar-search-button").addClass("open");
$("#leftbar_search_input").removeAttr("readonly").focus();
$("#leftbar_search_input").focus();
$("#leftbar_search_input").select();
return false;
});
$(document).on("blur" , "#leftbar_search_container" , function(){
$(".leftbar-search-button").removeClass("open");
$("#leftbar_search_input").attr("readonly", "readonly");
});
$(document).on("keydown" , "#leftbar_search_input" , function(e){
if (e.keyCode != 13){
return;
}
let word = $(this).val();
if (word == ""){
$("#leftbar_search_container").blur();
return;
}
$("html").removeClass("leftbar-opened");
searchPosts(word);
});
/*搜索过滤器*/
$(document).on("change" , ".search-filter" , function(e){
if (pjaxLoading){
$(this).prop("checked", !$(this).prop("checked"));
e.preventDefault();
return;
}
pjaxLoading = true;
let postTypes = [];
$(".search-filter:checked").each(function(){
postTypes.push($(this).attr("name"));
});
if (postTypes.length == 0){
postTypes = ["none"];
}
let url = new URL(document.location.href);
url.searchParams.set("post_type", postTypes.join(","));
url.pathname = url.pathname.replace(/\/page\/\d+$/, '');
$.pjax({
url: url.href
});
});
/*左侧栏随页面滚动浮动*/
!function(){
if ($("#leftbar").length == 0){
let contentOffsetTop = $('#content').offset().top;
function changeLeftbarStickyStatusWithoutSidebar(){
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if( contentOffsetTop - 10 - scrollTop <= 20 ){
document.body.classList.add('leftbar-can-headroom');
}else{
document.body.classList.remove('leftbar-can-headroom');
}
}
changeLeftbarStickyStatusWithoutSidebar();
// 使用节流优化滚动事件性能
const throttledChangeLeftbarStickyStatusWithoutSidebar = argonEventManager ?
argonEventManager.throttle(changeLeftbarStickyStatusWithoutSidebar, 16) :
changeLeftbarStickyStatusWithoutSidebar;
document.addEventListener("scroll", throttledChangeLeftbarStickyStatusWithoutSidebar, {passive: true});
$(window).resize(function(){
contentOffsetTop = $('#content').offset().top;
changeLeftbarStickyStatusWithoutSidebar();
});
return;
}
let $leftbarPart1 = $('#leftbar_part1');
let $leftbarPart2 = $('#leftbar_part2');
let leftbarPart1 = document.getElementById('leftbar_part1');
let leftbarPart2 = document.getElementById('leftbar_part2');
let leftbarPart3 = document.getElementById('leftbar_part3');
let part1OffsetTop = $('#leftbar_part1').offset().top;
let part1OuterHeight = $('#leftbar_part1').outerHeight();
function changeLeftbarStickyStatus(){
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if( part1OffsetTop + part1OuterHeight + 10 - scrollTop <= (argonConfig.headroom != "absolute" ? 90 : 18) ){
//滚动条在页面中间浮动状态
leftbarPart2.classList.add('sticky');
if (leftbarPart3) {
leftbarPart3.classList.add('sticky');
// 计算可用空间并分配给 part2 和 part3
let viewportHeight = window.innerHeight;
let topOffset = argonConfig.headroom !== 'absolute' ? 90 : 20;
let availableHeight = viewportHeight - topOffset - 20; // 20px 底部边距
// 获取 part3 的自然高度(不受限制时的高度)
leftbarPart3.style.maxHeight = 'none';
let part3NaturalHeight = leftbarPart3.scrollHeight;
leftbarPart3.style.maxHeight = '';
// 最小高度限制
let minPart2Height = 150;
let minPart3Height = 100;
// 计算分配
let part2Height, part3MaxHeight;
if (part3NaturalHeight + minPart2Height <= availableHeight) {
// part3 可以完全显示
part3MaxHeight = part3NaturalHeight;
part2Height = availableHeight - part3NaturalHeight - 10;
} else {
// 需要按比例分配part2 占 60%part3 占 40%
part2Height = Math.max(minPart2Height, availableHeight * 0.6);
part3MaxHeight = Math.max(minPart3Height, availableHeight - part2Height - 10);
}
document.documentElement.style.setProperty('--leftbar-part2-height', leftbarPart2.offsetHeight + 10 + 'px');
document.documentElement.style.setProperty('--leftbar-part3-height', part3MaxHeight + 'px');
document.documentElement.style.setProperty('--leftbar-part3-max-height', part3MaxHeight + 'px');
}
}else{
//滚动条在顶部 不浮动状态
leftbarPart2.classList.remove('sticky');
if (leftbarPart3) leftbarPart3.classList.remove('sticky');
}
if( part1OffsetTop + part1OuterHeight + 10 - scrollTop <= 20 ){//侧栏下部分是否可以随 Headroom 一起向上移动
document.body.classList.add('leftbar-can-headroom');
}else{
document.body.classList.remove('leftbar-can-headroom');
}
}
changeLeftbarStickyStatus();
// 使用节流优化滚动事件性能
const throttledChangeLeftbarStickyStatus = argonEventManager ?
argonEventManager.throttle(changeLeftbarStickyStatus, 16) :
changeLeftbarStickyStatus;
document.addEventListener("scroll", throttledChangeLeftbarStickyStatus, {passive: true});
$(window).resize(function(){
part1OffsetTop = $leftbarPart1.offset().top;
part1OuterHeight = $leftbarPart1.outerHeight();
changeLeftbarStickyStatus();
});
new MutationObserver(function(){
part1OffsetTop = $leftbarPart1.offset().top;
part1OuterHeight = $leftbarPart1.outerHeight();
changeLeftbarStickyStatus();
}).observe(leftbarPart1, {attributes: true, childList: true, subtree: true});
}();
/*Headroom*/
if (argonConfig.headroom == "true"){
var headroom = new Headroom(document.querySelector("body"),{
"tolerance" : {
up : 0,
down : 0
},
"offset": 0,
"classes": {
"initial": "with-headroom",
"pinned": "headroom---pinned",
"unpinned": "headroom---unpinned",
"top": "headroom---top",
"notTop": "headroom---not-top",
"bottom": "headroom---bottom",
"notBottom": "headroom---not-bottom",
"frozen": "headroom---frozen"
}
}).init();
}
/*瀑布流布局*/
function waterflowInit() {
if (argonConfig.waterflow_columns == "1") {
return;
}
$("#main.article-list img").each(function(index, ele){
ele.onload = function(){
waterflowInit();
}
});
let columns;
if (argonConfig.waterflow_columns == "2and3") {
if ($("#main").outerWidth() > 1000) {
columns = 3;
} else {
columns = 2;
}
}else{
columns = parseInt(argonConfig.waterflow_columns);
}
if ($("#main").outerWidth() < 650 && columns == 2) {
columns = 1;
}else if ($("#main").outerWidth() < 800 && columns == 3) {
columns = 1;
}
let heights = [0, 0, 0];
function getMinHeightPosition(){
let res = 0, minn = 2147483647;
for (var i = 0; i < columns; i++) {
if (heights[i] < minn) {
minn = heights[i];
res = i;
}
}
return res;
}
function getMaxHeight(){
let res = 0;
for (let i in heights) {
res = Math.max(res, heights[i]);
}
return res;
}
$("#primary").css("transition", "none")
.addClass("waterflow");
let $container = $("#main.article-list");
if (!$container.length){
return;
}
let $items = $container.find("article.post:not(.no-results), .shuoshuo-preview-container");
columns = Math.max(Math.min(columns, $items.length), 1);
if (columns == 1) {
$container.removeClass("waterflow");
$items.css("transition", "").css("position", "").css("width", "").css("top", "").css("left", "").css("margin", "");
$(".waterflow-placeholder").remove();
}else{
$container.addClass("waterflow");
$items.each(function(index, item) {
let $item = $(item);
$item.css("transition", "none")
.css("position", "absolute")
.css("width", "calc(" + (100 / columns) + "% - " + (10 * (columns - 1) / columns) + "px)").css("margin", 0);
let itemHeight = $item.outerHeight() + 10;
let pos = getMinHeightPosition();
$item.css("top", heights[getMinHeightPosition()] + "px")
.css("left", (pos * $item.outerWidth() + 10 * pos) + "px");
heights[pos] += itemHeight;
});
}
if ($(".waterflow-placeholder").length) {
$(".waterflow-placeholder").css("height", getMaxHeight() + "px");
}else{
$container.prepend("<div class='waterflow-placeholder' style='height: " + getMaxHeight() +"px;'></div>");
}
}
waterflowInit();
if (argonConfig.waterflow_columns != "1") {
$(window).resize(function(){
waterflowInit();
});
new MutationObserver(function(mutations, observer){
waterflowInit();
}).observe(document.querySelector("#primary"), {
'childList': true
});
}
/*移动端文章列表布局切换*/
!function(){
var mobileLayout = argonConfig.article_list_layout_mobile || "1";
var isMobile = window.innerWidth <= 900;
function applyMobileLayout() {
var nowMobile = window.innerWidth <= 900;
if (nowMobile) {
$("html").addClass("mobile-layout-" + mobileLayout);
} else {
$("html").removeClass("mobile-layout-1 mobile-layout-2 mobile-layout-3");
}
}
applyMobileLayout();
$(window).resize(function(){
applyMobileLayout();
});
}();
/*浮动按钮栏相关(回顶部)*/
!function(){
// 确保 DOM 和 jQuery 已加载
if (typeof jQuery === 'undefined') {
setTimeout(arguments.callee, 50);
return;
}
let $fabtns = $('#float_action_buttons');
if ($fabtns.length === 0) {
setTimeout(arguments.callee, 50);
return;
}
let $backToTopBtn = $('#fabtn_back_to_top');
let $toggleSidesBtn = $('#fabtn_toggle_sides');
let $toggleDarkmode = $('#fabtn_toggle_darkmode');
let $toggleAmoledMode = $('#blog_setting_toggle_darkmode_and_amoledarkmode');
let $toggleBlogSettings = $('#fabtn_toggle_blog_settings_popup');
let $goToComment = $('#fabtn_go_to_comment');
let $readingProgressBtn = $('#fabtn_reading_progress');
let $readingProgressBar = $('#fabtn_reading_progress_bar');
let $readingProgressDetails = $('#fabtn_reading_progress_details');
$backToTopBtn.on("click" , function(){
$("body,html").stop().animate({
scrollTop: 0
}, 600);
});
$toggleDarkmode.on("click" , function(){
toggleDarkmode();
});
$toggleAmoledMode.on("click" , function(){
toggleAmoledDarkMode();
})
if ($("#post_comment").length > 0){
$("#fabtn_go_to_comment").removeClass("fabtn-hidden");
}else{
$("#fabtn_go_to_comment").addClass("fabtn-hidden");
}
$goToComment.on("click" , function(){
var commentsArea = $("#comments");
var postCommentArea = $("#post_comment");
var wasCollapsed = commentsArea.hasClass("comments-collapsed");
var toggleBtn = $("#comments_toggle");
if (wasCollapsed && toggleBtn.length > 0) {
// 折叠状态:先滚动到评论切换按钮位置,再展开
$("body,html").stop().animate({
scrollTop: toggleBtn.offset().top - 80
}, 600);
toggleBtn.find("i").removeClass("fa-comments").addClass("fa-comment-o");
toggleBtn.find(".btn-inner--text").text("折叠评论");
toggleBtn.addClass("expanded");
commentsArea.removeClass("comments-collapsed");
setTimeout(function() {
postCommentArea.removeClass("comments-collapsed");
$("#post_comment_content").focus();
}, 150);
} else {
// 已展开或无切换按钮:直接滚动到评论区
$("body,html").stop().animate({
scrollTop: postCommentArea.offset().top - 80
}, 600);
$("#post_comment_content").focus();
}
});
if (localStorage['Argon_fabs_Floating_Status'] == "left"){
$fabtns.addClass("fabtns-float-left");
}
$toggleSidesBtn.on("click" , function(){
$fabtns.addClass("fabtns-unloaded");
setTimeout(function(){
$fabtns.toggleClass("fabtns-float-left");
if ($fabtns.hasClass("fabtns-float-left")){
localStorage['Argon_fabs_Floating_Status'] = "left";
}else{
localStorage['Argon_fabs_Floating_Status'] = "right";
}
$fabtns.removeClass("fabtns-unloaded");
} , 300);
});
//博客设置
$toggleBlogSettings.on("click" , function(){
$("#float_action_buttons").toggleClass("blog_settings_opened");
});
$("#close_blog_settings").on("click" , function(){
$("#float_action_buttons").removeClass("blog_settings_opened");
});
$("#blog_setting_darkmode_switch .custom-toggle-slider").on("click" , function(){
toggleDarkmode();
});
//字体
$("#blog_setting_font_sans_serif").on("click" , function(){
$("html").removeClass("use-serif");
localStorage['Argon_Use_Serif'] = "false";
});
$("#blog_setting_font_serif").on("click" , function(){
$("html").addClass("use-serif");
localStorage['Argon_Use_Serif'] = "true";
});
// 字体设置已在 header.php 中预加载,此处无需重复应用
//阴影
$("#blog_setting_shadow_small").on("click" , function(){
$("html").removeClass("use-big-shadow");
localStorage['Argon_Use_Big_Shadow'] = "false";
});
$("#blog_setting_shadow_big").on("click" , function(){
$("html").addClass("use-big-shadow");
localStorage['Argon_Use_Big_Shadow'] = "true";
});
// 阴影设置已在 header.php 中预加载,此处无需重复应用
//滤镜
function setBlogFilter(name){
if (name == undefined || name == ""){
name = "off";
}
if (!$("html").hasClass("filter-" + name)){
$("html").removeClass("filter-sunset filter-darkness filter-grayscale");
if (name != "off"){
$("html").addClass("filter-" + name);
}
}
$("#blog_setting_filters .blog-setting-filter-btn").removeClass("active");
$("#blog_setting_filters .blog-setting-filter-btn[filter-name='" + name + "']").addClass("active");
localStorage['Argon_Filter'] = name;
}
// 滤镜设置已在 header.php 中预加载,此处只需设置按钮状态
let currentFilter = localStorage['Argon_Filter'] || 'off';
$("#blog_setting_filters .blog-setting-filter-btn[filter-name='" + currentFilter + "']").addClass("active");
$(".blog-setting-filter-btn").on("click" , function(){
setBlogFilter(this.getAttribute("filter-name"));
});
//UI 样式切换 (玻璃拟态/新拟态)
function setUIStyle(style){
if (style == undefined || style == ""){
style = "default";
}
$("html").removeClass("style-glass style-neumorphism");
if (style != "default"){
$("html").addClass("style-" + style);
}
$(".blog-setting-style-btn").removeClass("active");
$(".blog-setting-style-btn[style-name='" + style + "']").addClass("active");
localStorage['Argon_UI_Style'] = style;
}
// UI 样式设置已在 header.php 中预加载,此处只需设置按钮状态
let currentUIStyle = localStorage['Argon_UI_Style'] || 'default';
$(".blog-setting-style-btn[style-name='" + currentUIStyle + "']").addClass("active");
$(".blog-setting-style-btn").on("click" , function(){
setUIStyle(this.getAttribute("style-name"));
});
let $window = $(window);
function changefabtnDisplayStatus(){
//阅读进度
function hideReadingProgress(){
$readingProgressBtn.addClass("fabtn-hidden");
}
function setReadingProgress(percent){
$readingProgressBtn.removeClass("fabtn-hidden");
$readingProgressDetails.html((percent * 100).toFixed(0) + "%");
$readingProgressBar.css("width" , (percent * 100).toFixed(0) + "%");
}
if ($("article.post.post-full").length == 0){
hideReadingProgress();
}else{
let a = $window.scrollTop() - ($("article.post.post-full").offset().top - 80);
let b = $("article.post.post-full").outerHeight() + 50 - $window.height();
if (b <= 0){
hideReadingProgress();
}else{
readingProgress = a / b;
if (isNaN(readingProgress) || readingProgress < 0 || readingProgress > 1){
hideReadingProgress();
}else{
setReadingProgress(readingProgress);
}
}
}
//是否显示回顶
if ($(window).scrollTop() >= 400){
$backToTopBtn.removeClass("fabtn-hidden");
}else{
$backToTopBtn.addClass("fabtn-hidden");
}
}
changefabtnDisplayStatus();
$(window).scroll(function(){
changefabtnDisplayStatus();
});
$(window).resize(function(){
changefabtnDisplayStatus();
});
$fabtns.removeClass("fabtns-unloaded");
}();
/*卡片圆角大小调整*/
!function(){
function setCardRadius(radius, setcookie){
document.documentElement.style.setProperty('--card-radius', radius + "px");
if (setcookie){
setCookie("argon_card_radius", radius, 365);
}
}
let slider = document.getElementById('blog_setting_card_radius');
noUiSlider.create(slider, {
start: [$("meta[name='theme-card-radius']").attr("content")],
step: 0.5,
connect: [true, false],
range: {
'min': [0],
'max': [30]
}
});
slider.noUiSlider.on('update', function (values){
let value = values[0];
setCardRadius(value, false);
});
slider.noUiSlider.on('set', function (values){
let value = values[0];
setCardRadius(value, true);
});
$(document).on("click" , "#blog_setting_card_radius_to_default" , function(){
slider.noUiSlider.set($("meta[name='theme-card-radius-origin']").attr("content"));
setCardRadius($("meta[name='theme-card-radius-origin']").attr("content"), false);
setCookie("argon_card_radius", $("meta[name='theme-card-radius-origin']").attr("content"), 0);
});
}();
/*评论区 & 发送评论*/
!function(){
//回复评论
let replying = false , replyID = 0;
/**
* 显示回复框
* @param {number} commentID - 评论ID
*/
function reply(commentID){
cancelEdit(false);
replying = true;
replyID = commentID;
let nameEl = $("#comment-" + commentID + " .comment-item-title > .comment-name")[0];
let textEl = $("#comment-" + commentID + " .comment-item-text")[0];
let sourceEl = $("#comment-" + commentID + " .comment-item-source")[0];
if (nameEl) {
$("#post_comment_reply_name").text(nameEl.textContent);
}
let preview = textEl ? textEl.textContent : '';
if (sourceEl && sourceEl.innerHTML !== '') {
preview = sourceEl.textContent;
}
$("#post_comment_reply_preview").text(preview);
if ($("#comment-" + commentID + " .comment-item-title .badge-private-comment").length > 0){
$("#post_comment").addClass("post-comment-force-privatemode-on");
}else{
$("#post_comment").addClass("post-comment-force-privatemode-off");
}
// 滚动到评论框(使用原生 scrollTo 避免 jQuery easing 依赖问题)
let postComment = $('#post_comment');
if (postComment.length > 0 && postComment.offset()) {
let targetTop = postComment.offset().top - 100;
window.scrollTo({
top: targetTop,
behavior: 'smooth'
});
}
// 使用 CSS 动画显示回复框
let replyInfo = $('#post_comment_reply_info');
if (replyInfo.length > 0) {
replyInfo.removeClass('reply-leaving').css('display', 'block');
// 触发重排以确保动画生效
replyInfo[0].offsetHeight;
replyInfo.addClass('reply-entering');
}
setTimeout(function(){
$("#post_comment_content").focus();
}, 300);
}
/**
* 取消回复
*/
function cancelReply(){
replying = false;
replyID = 0;
let replyInfo = $('#post_comment_reply_info');
replyInfo.removeClass('reply-entering').addClass('reply-leaving');
setTimeout(function(){
replyInfo.css('display', 'none').removeClass('reply-leaving');
}, 200);
$("#post_comment").removeClass("post-comment-force-privatemode-on post-comment-force-privatemode-off");
}
$(document).on("click" , ".comment-reply" , function(){
reply(this.getAttribute("data-id"));
});
$(document).on("click pjax:click" , "#post_comment_reply_cancel" , function(){
cancelReply();
});
$(document).on("pjax:click" , function(){
replying = false;
replyID = 0;
$('#post_comment_reply_info').css("display", "none").removeClass('reply-entering reply-leaving');
$("#post_comment").removeClass("post-comment-force-privatemode-on post-comment-force-privatemode-off");
});
//编辑评论
let editing = false , editID = 0;
function edit(commentID){
cancelReply();
editing = true;
editID = commentID;
$('#post_comment').addClass("editing");
$("#post_comment_content").val($("#comment-" + editID + " .comment-item-source").text());
$("#post_comment_content").trigger("change");
if ($("#comment-" + editID).data("use-markdown") == true && document.getElementById("comment_post_use_markdown") != null){
document.getElementById("comment_post_use_markdown").checked = true;
}else{
document.getElementById("comment_post_use_markdown").checked = false;
}
if ($("#comment-" + commentID + " .comment-item-title .badge-private-comment").length > 0){
$("#post_comment").addClass("post-comment-force-privatemode-on");
}else{
$("#post_comment").addClass("post-comment-force-privatemode-off");
}
// 使用原生 scrollTo 避免 jQuery easing 依赖问题
let postCommentEl = document.getElementById('post_comment');
if (postCommentEl) {
window.scrollTo({
top: postCommentEl.getBoundingClientRect().top + window.pageYOffset - 100,
behavior: 'smooth'
});
}
$("#post_comment_content").focus();
}
function cancelEdit(clear){
editing = false;
editID = 0;
$("#post_comment").removeClass("post-comment-force-privatemode-on post-comment-force-privatemode-off");
if (clear == true) $("#post_comment_content").val("");
$("#post_comment_content").trigger("change");
$('#post_comment').removeClass("editing");
}
$(document).on("click", ".comment-edit", function(){
edit(this.getAttribute("data-id"));
});
$(document).on("click", "#post_comment_edit_cancel", function(){
// 使用原生 scrollTo 避免 jQuery easing 依赖问题
let commentEl = document.getElementById("comment-" + editID);
if (commentEl) {
window.scrollTo({
top: commentEl.getBoundingClientRect().top + window.pageYOffset - 100,
behavior: 'smooth'
});
}
cancelEdit(true);
});
$(document).on("pjax:click", function(){
cancelEdit(true);
});
$(document).on("click", ".comment-pin, .comment-unpin", function(){
toogleCommentPin(this.getAttribute("data-id"), !this.classList.contains("comment-pin"));
});
$(document).on("click", ".comment-delete", function(){
deleteComment(this.getAttribute("data-id"));
});
$(document).on("mouseenter", ".comment-parent-info", function(){
$("#comment-" + this.getAttribute("data-parent-id")).addClass("highlight");
});
$(document).on("mouseleave", ".comment-parent-info", function(){
$("#comment-" + this.getAttribute("data-parent-id")).removeClass("highlight");
});
//切换评论置顶状态
function toogleCommentPin(commentID, pinned){
$("#comment_pin_comfirm_dialog .modal-title").html(pinned ? __("取消置顶评论") : __("置顶评论"));
$("#comment_pin_comfirm_dialog .modal-body").html(pinned ? __("是否要取消置顶评论 #") + commentID + "?" : __("是否要置顶评论 #") + commentID + "?");
$("#comment_pin_comfirm_dialog .btn-comfirm").html(__("确认")).attr("disabled", false);
$("#comment_pin_comfirm_dialog .btn-dismiss").html(__("取消")).attr("disabled", false);
$("#comment_pin_comfirm_dialog .btn-comfirm").off("click").on("click", function(){
$("#comment_pin_comfirm_dialog .btn-dismiss").attr("disabled", true)
$("#comment_pin_comfirm_dialog .btn-comfirm").attr("disabled", true).prepend(__(`<span class="btn-inner--icon" style="margin-right: 10px;"><i class="fa fa-spinner fa-spin"></i></span>`));
$.ajax({
type: 'POST',
url: argonConfig.wp_path + "wp-admin/admin-ajax.php",
dataType : "json",
data: {
action: "pin_comment",
id: commentID,
pinned: pinned ? "false" : "true"
},
success: function(result){
$("#comment_pin_comfirm_dialog").modal('hide');
if (result.status == "success"){
if (pinned){
$("#comment-" + commentID + " .comment-name .badge-pinned").remove();
$("#comment-" + commentID + " .comment-unpin").removeClass("comment-unpin").addClass("comment-pin").html(__("置顶"));
}else{
$("#comment-" + commentID + " .comment-name").append(`<span class="badge badge-danger badge-pinned">${__("置顶")}</span>`);
$("#comment-" + commentID + " .comment-pin").removeClass("comment-pin").addClass("comment-unpin").html(__("取消置顶"));
}
iziToast.show({
title: pinned ? __("取消置顶成功") : __("置顶成功"),
message: pinned ? __("该评论已取消置顶") : __("该评论已置顶"),
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#2dce89',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-check',
timeout: 5000
});
} else {
iziToast.show({
title: pinned ? __("取消置顶失败") : __("置顶失败"),
message: result.msg,
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#f5365c',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-close',
timeout: 5000
});
}
},
error: function(result){
$("#comment_pin_comfirm_dialog").modal('hide');
iziToast.show({
title: pinned ? __("取消置顶失败") : __("置顶失败"),
message: __("未知错误"),
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#f5365c',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-close',
timeout: 5000
});
}
});
});
$("#comment_pin_comfirm_dialog").modal(null);
}
//删除评论
function deleteComment(commentID) {
if (!confirm(__('确定要删除评论 #') + commentID + '?')) {
return;
}
$.ajax({
type: 'POST',
url: argonConfig.wp_path + 'wp-admin/admin-ajax.php',
dataType: 'json',
data: {
action: 'frontend_delete_comment',
id: commentID
},
success: function(result) {
if (result.status === 'success') {
// 移除评论元素
$('#comment-' + commentID).fadeOut(300, function() {
$(this).next('.comment-divider').remove();
$(this).remove();
});
iziToast.show({
title: __('删除成功'),
message: result.msg,
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#2dce89',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-check',
timeout: 5000
});
} else {
iziToast.show({
title: __('删除失败'),
message: result.msg,
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#f5365c',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-close',
timeout: 5000
});
}
},
error: function() {
iziToast.show({
title: __('删除失败'),
message: __('未知错误'),
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#f5365c',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-close',
timeout: 5000
});
}
});
}
//显示/隐藏额外输入框(评论者网址)
$(document).on("click" , "#post_comment_toggle_extra_input" , function(){
$("#post_comment").toggleClass("show-extra-input");
if ($("#post_comment").hasClass("show-extra-input")){
$("#post_comment_extra_input").slideDown(250, 'easeOutCirc');
}else{
$("#post_comment_extra_input").slideUp(200, 'easeOutCirc');
}
});
//输入框细节
$(document).on("change input keydown keyup propertychange" , "#post_comment_content" , function(){
$("#post_comment_content_hidden")[0].innerText = $("#post_comment_content").val() + "\n";
$("#post_comment_content").css("height" , $("#post_comment_content_hidden").outerHeight());
});
$(document).on("focus" , "#post_comment_link" , function(){
$(".post-comment-link-container").addClass("active");
});
$(document).on("blur" , "#post_comment_link" , function(){
$(".post-comment-link-container").removeClass("active");
});
$(document).on("focus" , "#post_comment_captcha" , function(){
$(".post-comment-captcha-container").addClass("active");
});
$(document).on("blur" , "#post_comment_captcha" , function(){
$(".post-comment-captcha-container").removeClass("active");
});
//发送评论
window.postComment = function postComment(){
let commentContent = $("#post_comment_content").val();
let commentName = $("#post_comment_name").val();
let commentEmail = $("#post_comment_email").val();
let commentLink = $("#post_comment_link").val();
let commentCaptcha = $("#post_comment_captcha").val();
let useMarkdown = false;
let privateMode = false;
let mailNotice = false;
if ($("#comment_post_use_markdown").length > 0){
useMarkdown = $("#comment_post_use_markdown")[0].checked;
}
if ($("#comment_post_privatemode").length > 0){
privateMode = $("#comment_post_privatemode")[0].checked;
}
if ($("#comment_post_mailnotice").length > 0){
mailNotice = $("#comment_post_mailnotice")[0].checked;
}
let postID = $("#post_comment_post_id").val();
let commentCaptchaSeed = $("#post_comment_captcha_seed").val();
let isError = false;
let errorMsg = "";
//检查表单合法性
if (commentContent.match(/^\s*$/)){
isError = true;
errorMsg += __("评论内容不能为空") + "</br>";
}
if (!$("#post_comment").hasClass("no-need-name-email")){
if (commentName.match(/^\s*$/)){
isError = true;
errorMsg += __("昵称不能为空") + "</br>";
}
if ($("#post_comment").hasClass("enable-qq-avatar")){
if (!(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/).test(commentEmail) && !(/^[1-9][0-9]{4,10}$/).test(commentEmail)){
isError = true;
errorMsg += __("邮箱或QQ 号格式错误") + "</br>";
}
}else{
if (!(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/).test(commentEmail)){
isError = true;
errorMsg += __("邮箱格式错误") + "</br>";
}
}
}else{
if (commentEmail.length || (document.getElementById("comment_post_mailnotice") != null && document.getElementById("comment_post_mailnotice").checked == true)){
if ($("#post_comment").hasClass("enable-qq-avatar")){
if (!(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/).test(commentEmail) && !(/^[1-9][0-9]{4,10}$/).test(commentEmail)){
isError = true;
errorMsg += __("邮箱或QQ 号格式错误") + "</br>";
}
}else{
if (!(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/).test(commentEmail)){
isError = true;
errorMsg += __("邮箱格式错误") + "</br>";
}
}
}
}
if (commentLink != "" && !(/https?:\/\//).test(commentLink)){
isError = true;
errorMsg += __("网站格式错误 (不是 http(s):// 开头)") + "</br>";
}
if (!$("#post_comment").hasClass("no-need-captcha")){
// 检查是否使用Geetest验证码
if ($("#geetest-captcha").length > 0) {
// 检查Geetest库是否加载成功
if (typeof window.geetestLoadFailed !== 'undefined' && window.geetestLoadFailed) {
isError = true;
errorMsg += __("验证码服务不可用,请刷新页面重试");
} else if (typeof window.geetestCaptcha === 'undefined' || !window.geetestCaptcha) {
isError = true;
errorMsg += __("验证码未初始化,请稍后重试");;
} else {
// Geetest验证码检查
let lotNumber = $("#geetest_lot_number").val();
let captchaOutput = $("#geetest_captcha_output").val();
let passToken = $("#geetest_pass_token").val();
let genTime = $("#geetest_gen_time").val();
if (!lotNumber || !captchaOutput || !passToken || !genTime) {
isError = true;
errorMsg += __("请完成验证码验证");
}
}
} else {
// 原有的数学验证码验证
if (commentCaptcha == ""){
isError = true;
errorMsg += __("验证码未输入");
}
if (commentCaptcha != "" && !(/^[0-9]+$/).test(commentCaptcha)){
isError = true;
errorMsg += __("验证码格式错误");
}
}
}
if (isError){
// 确保按钮和表单元素处于可用状态
$("#post_comment_send").removeAttr("disabled");
$("#post_comment_content").removeAttr("disabled");
$("#post_comment_name").removeAttr("disabled");
$("#post_comment_email").removeAttr("disabled");
$("#post_comment_link").removeAttr("disabled");
$("#post_comment_captcha").removeAttr("disabled");
$("#post_comment_reply_cancel").removeAttr("disabled");
$("#post_comment").removeClass("sending");
$("#post_comment_send .btn-inner--icon.hide-on-comment-editing").html("<i class='fa fa-send'></i>");
$("#post_comment_send .btn-inner--text.hide-on-comment-editing").html(__("发送"));
iziToast.show({
title: __("评论格式错误"),
message: errorMsg,
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#f5365c',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-close',
timeout: 5000
});
return;
}
//增加 disabled 属性和其他的表单提示
$("#post_comment").addClass("sending");
$("#post_comment_content").attr("disabled","disabled");
$("#post_comment_name").attr("disabled","disabled");
$("#post_comment_email").attr("disabled","disabled");
$("#post_comment_captcha").attr("disabled","disabled");
$("#post_comment_link").attr("disabled","disabled");
$("#post_comment_send").attr("disabled","disabled");
$("#post_comment_reply_cancel").attr("disabled","disabled");
$("#post_comment_send .btn-inner--icon.hide-on-comment-editing").html("<i class='fa fa-spinner fa-spin'></i>");
$("#post_comment_send .btn-inner--text.hide-on-comment-editing").html(__("发送中"));
iziToast.show({
title: __("正在发送"),
message: __("评论正在发送中..."),
class: 'shadow-sm iziToast-noprogressbar',
position: 'topRight',
backgroundColor: 'var(--themecolor)',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-spinner fa-spin',
close: false,
timeout: 999999999
});
// 准备数据
var ajaxData = {
action: "ajax_post_comment",
comment: commentContent,
author: commentName,
email: commentEmail,
url: commentLink,
comment_post_ID: postID,
comment_parent: replyID,
"wp-comment-cookies-consent": "yes",
use_markdown: useMarkdown,
private_mode: privateMode,
enable_mailnotice: mailNotice,
argon_nonce: $("#argon_comment_nonce").val()
};
// 根据验证码类型添加相应参数
if ($("#geetest-captcha").length > 0) {
// 检查Geetest库加载状态
if (typeof window.geetestLoadFailed !== 'undefined' && window.geetestLoadFailed) {
// 重新启用按钮和表单元素
$("#post_comment").removeClass("sending");
$("#post_comment_content").removeAttr("disabled");
$("#post_comment_name").removeAttr("disabled");
$("#post_comment_email").removeAttr("disabled");
$("#post_comment_captcha").removeAttr("disabled");
$("#post_comment_link").removeAttr("disabled");
$("#post_comment_send").removeAttr("disabled");
$("#post_comment_reply_cancel").removeAttr("disabled");
$("#post_comment_send .btn-inner--icon.hide-on-comment-editing").html("<i class='fa fa-send'></i>");
$("#post_comment_send .btn-inner--text.hide-on-comment-editing").html(__("发送"));
setTimeout(function() {
try {
iziToast.destroy();
iziToast.error({
title: __('评论发送失败'),
message: __('验证码服务不可用,请刷新页面重试'),
position: 'topRight'
});
} catch (e) {
ArgonDebug.warn('iziToast error:', e);
}
}, 0);
return false;
}
// Geetest验证码参数 - 使用后端期望的参数名
ajaxData.lot_number = $("#geetest_lot_number").val();
ajaxData.captcha_output = $("#geetest_captcha_output").val();
ajaxData.pass_token = $("#geetest_pass_token").val();
ajaxData.gen_time = $("#geetest_gen_time").val();
// 验证Geetest参数是否完整
if (!ajaxData.lot_number || !ajaxData.captcha_output || !ajaxData.pass_token || !ajaxData.gen_time) {
// 重新启用按钮和表单元素
$("#post_comment").removeClass("sending");
$("#post_comment_content").removeAttr("disabled");
$("#post_comment_name").removeAttr("disabled");
$("#post_comment_email").removeAttr("disabled");
$("#post_comment_captcha").removeAttr("disabled");
$("#post_comment_link").removeAttr("disabled");
$("#post_comment_send").removeAttr("disabled");
$("#post_comment_reply_cancel").removeAttr("disabled");
$("#post_comment_send .btn-inner--icon.hide-on-comment-editing").html("<i class='fa fa-send'></i>");
$("#post_comment_send .btn-inner--text.hide-on-comment-editing").html(__("发送"));
// 使用 setTimeout 确保 iziToast 操作在下一个事件循环中执行
setTimeout(function() {
try {
iziToast.destroy();
iziToast.error({
title: __('评论发送失败'),
message: __('请完成验证码验证'),
position: 'topRight'
});
} catch (e) {
ArgonDebug.warn('iziToast error:', e);
}
}, 0);
return false;
}
} else {
// 原有数学验证码参数
ajaxData.comment_captcha_seed = commentCaptchaSeed;
ajaxData.comment_captcha = commentCaptcha;
}
$.ajax({
type: 'POST',
url: argonConfig.wp_path + "wp-admin/admin-ajax.php",
dataType : "json",
data: ajaxData,
success: function(result){
$("#post_comment").removeClass("sending");
$("#post_comment_content").removeAttr("disabled");
$("#post_comment_name").removeAttr("disabled");
$("#post_comment_email").removeAttr("disabled");
$("#post_comment_link").removeAttr("disabled");
$("#post_comment_send").removeAttr("disabled");
$("#post_comment_reply_cancel").removeAttr("disabled");
$("#post_comment_send .btn-inner--icon.hide-on-comment-editing").html("<i class='fa fa-send'></i>");
$("#post_comment_send .btn-inner--text.hide-on-comment-editing").html(__("发送"));
$("#post_comment").removeClass("show-extra-input post-comment-force-privatemode-on post-comment-force-privatemode-off");
if (!result.isAdmin){
$("#post_comment_captcha").removeAttr("disabled");
}
//判断是否有错误
if (result.status == "failed"){
// 使用 setTimeout 确保 iziToast 操作在下一个事件循环中执行
setTimeout(function() {
try {
iziToast.destroy();
iziToast.show({
title: __("评论发送失败"),
message: result.msg,
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#f5365c',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-close',
timeout: 5000
});
} catch (e) {
ArgonDebug.warn('iziToast error:', e);
}
}, 0);
return;
}
//发送成功
// 先复位评论表单(确保无论后续操作是否成功都能重置表单)
cancelReply();
$("#post_comment_content").val("");
// 重置数学验证码
$("#post_comment_captcha_seed").val(result.newCaptchaSeed);
$("#post_comment_captcha + style").html(".post-comment-captcha-container:before{content: '" + result.newCaptcha + "';}");
$("#post_comment_captcha").val("");
// 清空Geetest验证码隐藏字段并重置验证码实例
if ($("#geetest-captcha").length > 0) {
$("#geetest_lot_number").val("");
$("#geetest_captcha_output").val("");
$("#geetest_pass_token").val("");
$("#geetest_gen_time").val("");
// 重置验证状态标志位
window.geetestVerified = false;
// 重置自动提交标记
window.geetestAutoSubmitting = false;
// 重置 Geetest 实例,确保下一次可以重新验证
if (window.geetestCaptcha) {
try {
window.geetestCaptcha.reset();
} catch (e) {
ArgonDebug.warn('Geetest reset error:', e);
}
}
}
// 显示成功提示
setTimeout(function() {
try {
iziToast.destroy();
iziToast.show({
title: __("发送成功"),
message: __("您的评论已发送"),
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#2dce89',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-check',
timeout: 5000
});
} catch (e) {
ArgonDebug.warn('iziToast error:', e);
}
}, 0);
// 插入新评论
try {
result.html = result.html.replace(/<(\/).noscript>/g, "");
let parentID = result.parentID;
if (parentID == "" || parentID == null){
parentID = 0;
}
parentID = parseInt(parentID);
if (parentID == 0){
if ($("#comments > .card-body > ol.comment-list").length == 0){
$("#comments > .card-body").html("<h2 class='comments-title'><i class='fa fa-comments'></i> " + __("评论") + "</h2><ol class='comment-list'></ol>");
}
if (result.commentOrder == "asc"){
$("#comments > .card-body > ol.comment-list").append(result.html);
}else{
$("#comments > .card-body > ol.comment-list").prepend(result.html);
}
}else{
if ($("#comment-" + parentID + " + .comment-divider + li > ul.children").length > 0){
$("#comment-" + parentID + " + .comment-divider + li > ul.children").append(result.html);
}else{
$("#comment-" + parentID + " + .comment-divider").after("<li><ul class='children'>" + result.html + "</ul></li>");
}
}
calcHumanTimesOnPage();
// 滚动到新评论
$("body,html").animate({
scrollTop: $("#comment-" + result.id).offset().top - 100
}, 500, 'easeOutExpo');
} catch (e) {
ArgonDebug.warn('Comment insertion error:', e);
}
},
error: function(result){
$("#post_comment").removeClass("sending");
$("#post_comment_content").removeAttr("disabled");
$("#post_comment_name").removeAttr("disabled");
$("#post_comment_email").removeAttr("disabled");
$("#post_comment_link").removeAttr("disabled");
$("#post_comment_send").removeAttr("disabled");
$("#post_comment_reply_cancel").removeAttr("disabled");
$("#post_comment_send .btn-inner--icon.hide-on-comment-editing").html("<i class='fa fa-send'></i>");
$("#post_comment_send .btn-inner--text.hide-on-comment-editing").html(__("发送"));
$("#post_comment").removeClass("show-extra-input post-comment-force-privatemode-on post-comment-force-privatemode-off");
if (!result.isAdmin){
$("#post_comment_captcha").removeAttr("disabled");
}
// 重置Geetest验证状态
window.geetestVerified = false;
// 重置自动提交标记
window.geetestAutoSubmitting = false;
$("#geetest_lot_number").val("");
$("#geetest_captcha_output").val("");
$("#geetest_pass_token").val("");
$("#geetest_gen_time").val("");
// 重置 Geetest 实例确保下一次生成新的pass_token
if (window.geetestCaptcha) {
try { window.geetestCaptcha.reset(); } catch (e) {}
}
// 安全地处理iziToast 操作防止time 属性错误
setTimeout(function() {
try {
iziToast.destroy();
iziToast.show({
title: __("评论发送失败"),
message: __("未知原因"),
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#f5365c',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-close',
timeout: 5000
});
} catch (e) {
ArgonDebug.warn('iziToast operation error:', e);
}
}, 10);
return;
}
});
}
//编辑评论
function editComment(){
let commentContent = $("#post_comment_content").val();
let isError = false;
let errorMsg = "";
if (commentContent.match(/^\s*$/)){
isError = true;
errorMsg += __("评论内容不能为空") + "</br>";
}
if (isError){
iziToast.show({
title: __("评论格式错误"),
message: errorMsg,
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#f5365c',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-close',
timeout: 5000
});
return;
}
//增加 disabled 属性和其他的表单提交
$("#post_comment_content").attr("disabled","disabled");
$("#post_comment_send").attr("disabled","disabled");
$("#post_comment_edit_cancel").attr("disabled","disabled");
$("#post_comment_send .btn-inner--icon.hide-on-comment-not-editing").html("<i class='fa fa-spinner fa-spin'></i>");
$("#post_comment_send .btn-inner--text.hide-on-comment-not-editing").html(__("编辑中"));
iziToast.show({
title: __("正在编辑"),
message: __("评论正在编辑中.."),
class: 'shadow-sm iziToast-noprogressbar',
position: 'topRight',
backgroundColor: 'var(--themecolor)',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-spinner fa-spin',
close: false,
timeout: 999999999
});
$.ajax({
type: 'POST',
url: argonConfig.wp_path + "wp-admin/admin-ajax.php",
dataType : "json",
data: {
action: "user_edit_comment",
comment: commentContent,
id: editID
},
success: function(result){
$("#post_comment_content").removeAttr("disabled");
$("#post_comment_send").removeAttr("disabled");
$("#post_comment_edit_cancel").removeAttr("disabled");
$("#post_comment_send .btn-inner--icon.hide-on-comment-not-editing").html("<i class='fa fa-pencil'></i>");
$("#post_comment_send .btn-inner--text.hide-on-comment-not-editing").html(__("编辑"));
//判断是否有错误
if (result.status == "failed"){
iziToast.destroy();
iziToast.show({
title: __("评论编辑失败"),
message: result.msg,
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#f5365c',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-close',
timeout: 5000
});
return;
}
//发送成功,替换原评论
result.new_comment = result.new_comment.replace(/<(\/).noscript>/g, "");
$("#comment-" + editID + " .comment-item-text").html(result.new_comment);
$("#comment-" + editID + " .comment-item-source").html(result.new_comment_source);
if ($("#comment-" + editID + " .comment-info .comment-edited").length == 0){
$("#comment-" + editID + " .comment-info").prepend("<div class='comment-edited'><i class='fa fa-pencil' aria-hidden='true'></i>" + __("已编辑") + "</div>")
}
if (result.can_visit_edit_history){
$("#comment-" + editID + " .comment-info .comment-edited").addClass("comment-edithistory-accessible");
}
iziToast.destroy();
iziToast.show({
title: __("编辑成功"),
message: __("您的评论已编辑"),
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#2dce89',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-check',
timeout: 5000
});
$("body,html").animate({
scrollTop: $("#comment-" + editID).offset().top - 100
}, 500, 'easeOutExpo');
editing = false;
editID = 0;
$("#post_comment_content").val("");
$('#post_comment').removeClass("editing post-comment-force-privatemode-on post-comment-force-privatemode-off");
$("#post_comment_content").trigger("change");
},
error: function(result){
$("#post_comment_content").removeAttr("disabled");
$("#post_comment_send").removeAttr("disabled");
$("#post_comment_edit_cancel").removeAttr("disabled");
$("#post_comment_send .btn-inner--icon.hide-on-comment-not-editing").html("<i class='fa fa-pencil'></i>");
$("#post_comment_send .btn-inner--text.hide-on-comment-not-editing").html(__("编辑"));
if (result.readyState != 4 || result.status == 0){
iziToast.destroy();
iziToast.show({
title: __("评论编辑失败"),
message: __("未知原因"),
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#f5365c',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-close',
timeout: 5000
});
return;
}
}
});
}
$(document).on("click" , "#post_comment_send" , function(){
if ($("#post_comment").hasClass("editing")){
editComment();
}else{
// 首先进行基本的表单验证
let commentContent = $("#post_comment_content").val();
let commentName = $("#post_comment_name").val();
let commentEmail = $("#post_comment_email").val();
let commentLink = $("#post_comment_link").val();
let isError = false;
let errorMsg = "";
// 检查表单合法性
if (commentContent.match(/^\s*$/)){
isError = true;
errorMsg += __("评论内容不能为空") + "</br>";
}
if (!$("#post_comment").hasClass("no-need-name-email")){
if (commentName.match(/^\s*$/)){
isError = true;
errorMsg += __("昵称不能为空") + "</br>";
}
if ($("#post_comment").hasClass("enable-qq-avatar")){
if (!(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/).test(commentEmail) && !(/^[1-9][0-9]{4,10}$/).test(commentEmail)){
isError = true;
errorMsg += __("邮箱或QQ 号格式错误") + "</br>";
}
}else{
if (!(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/).test(commentEmail)){
isError = true;
errorMsg += __("邮箱格式错误") + "</br>";
}
}
}else{
if (commentEmail.length || (document.getElementById("comment_post_mailnotice") != null && document.getElementById("comment_post_mailnotice").checked == true)){
if ($("#post_comment").hasClass("enable-qq-avatar")){
if (!(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/).test(commentEmail) && !(/^[1-9][0-9]{4,10}$/).test(commentEmail)){
isError = true;
errorMsg += __("邮箱或QQ 号格式错误") + "</br>";
}
}else{
if (!(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/).test(commentEmail)){
isError = true;
errorMsg += __("邮箱格式错误") + "</br>";
}
}
}
}
if (commentLink != "" && !(/https?:\/\//).test(commentLink)){
isError = true;
errorMsg += __("网站格式错误 (不是 http(s):// 开头") + "</br>";
}
// 如果基本表单验证失败,显示错误信息并返回
if (isError){
// 确保按钮和表单元素处于可用状态
$("#post_comment_send").removeAttr("disabled");
$("#post_comment_content").removeAttr("disabled");
$("#post_comment_name").removeAttr("disabled");
$("#post_comment_email").removeAttr("disabled");
$("#post_comment_link").removeAttr("disabled");
$("#post_comment_captcha").removeAttr("disabled");
$("#post_comment_reply_cancel").removeAttr("disabled");
$("#post_comment").removeClass("sending");
$("#post_comment_send .btn-inner--icon.hide-on-comment-editing").html("<i class='fa fa-send'></i>");
$("#post_comment_send .btn-inner--text.hide-on-comment-editing").html(__("发送"));
iziToast.show({
title: __("评论格式错误"),
message: errorMsg,
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#f5365c',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-close',
timeout: 5000
});
return;
}
// 基本验证通过后,检查验证码
if ($("#geetest-captcha").length > 0) {
// 检查Geetest 库是否加载失败
if (window.geetestLoadFailed) {
if (typeof loadGeetestScript === 'function' && typeof initGeetestCaptchaCore === 'function') {
try {
loadGeetestScript(function(){
initGeetestCaptchaCore();
setTimeout(function(){
if (window.geetestCaptcha) { try { window.geetestCaptcha.showBox(); } catch(e){} }
}, 0);
});
} catch(e) {}
}
return;
}
// 如果正在自动提交中,防止重复点击
if (window.geetestAutoSubmitting) {
return;
}
// 如果使用Geetest检查验证码是否已完成
if (!window.geetestVerified) {
// 验证码未完成,触发验证码显示
if (window.geetestCaptcha) {
// 重置验证码状态
window.geetestCaptcha.reset();
// 然后显示验证码
window.geetestCaptcha.showBox();
} else {
if (typeof loadGeetestScript === 'function' && typeof initGeetestCaptchaCore === 'function') {
try {
loadGeetestScript(function(){
initGeetestCaptchaCore();
setTimeout(function(){
if (window.geetestCaptcha) { try { window.geetestCaptcha.showBox(); } catch(e){} }
}, 0);
});
} catch(e) {}
}
}
return;
}
}
// 验证码已完成或不需要验证码,直接提交评论
postComment();
}
});
}();
/*评论点赞*/
$(document).on('click', '.comment-upvote', function(){
let $this = $(this);
let ID = $this.attr('data-id');
// 防止重复点击
if ($this.hasClass('comment-upvoting')) {
return;
}
$this.addClass('comment-upvoting');
$.ajax({
url: argonConfig.wp_path + 'wp-admin/admin-ajax.php',
type: 'POST',
dataType: 'json',
data: {
action: 'upvote_comment',
comment_id: ID,
},
success: function(result){
$this.removeClass('comment-upvoting');
if (result.status === 'success'){
$('.comment-upvote-num', $this).html(result.total_upvote);
if (result.upvoted) {
$this.addClass('upvoted');
} else {
$this.removeClass('upvoted');
}
} else {
$('.comment-upvote-num', $this).html(result.total_upvote);
iziToast.show({
title: result.msg,
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#f5365c',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-close',
timeout: 5000
});
}
},
error: function(xhr){
$this.removeClass('comment-upvoting');
iziToast.show({
title: __('点赞失败'),
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#f5365c',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-close',
timeout: 5000
});
}
});
});
/*评论表情面板*/
function lazyloadStickers(){
// 原生懒加载无需额外处理
}
$(document).on("click" , "#comment_emotion_btn" , function(){
$("#comment_emotion_btn").toggleClass("comment-emotion-keyboard-open");
});
$(document).on("click" , ".emotion-keyboard .emotion-group-name" , function(){
$(".emotion-keyboard .emotion-group-name.active").removeClass("active");
$(this).addClass("active");
$(".emotion-keyboard .emotion-group:not(d-none)").addClass("d-none");
$(".emotion-keyboard .emotion-group[index='" + $(this).attr("index") + "']").removeClass("d-none");
});
function inputInsertText(text, input){
$(input).focus();
let isSuccess = document.execCommand("insertText", false, text);
if (!isSuccess) { //FF
if (typeof input.setRangeText === "function"){
const start = input.selectionStart;
input.setRangeText(text);
input.selectionStart = input.selectionEnd = start + input.length;
const e = document.createEvent("UIEvent");
e.initEvent("input", true, false);
input.dispatchEvent(e);
}else{
let value = $(input).val();
let startPos = input.selectionStart, endPos = input.selectionEnd;
$(input).val(value.substring(0, startPos) + text + value.substring(endPos));
input.selectionStart = startPos + text.length;
input.selectionEnd = startPos + text.length;
}
}
$(input).focus();
}
$(document).on("click" , ".emotion-keyboard .emotion-item" , function(){
$("#comment_emotion_btn").removeClass("comment-emotion-keyboard-open");
if ($(this).hasClass("emotion-item-sticker")){
inputInsertText(" :" + $(this).attr("code") + ": ", document.getElementById("post_comment_content"));
}else{
inputInsertText($(this).attr("text"), document.getElementById("post_comment_content"));
}
});
$(document).on("dragstart" , ".emotion-keyboard .emotion-item > img, .comment-sticker" , function(e){
e.preventDefault();
});
document.addEventListener('click', (e) => {
if (document.getElementById("comment_emotion_btn") == null){
return;
}
  if(e.target.id != "comment_emotion_btn" && e.target.id != "emotion_keyboard" && !document.getElementById("comment_emotion_btn").contains(e.target) && !document.getElementById("emotion_keyboard").contains(e.target)){
$("#comment_emotion_btn").removeClass("comment-emotion-keyboard-open");
  }
})
/*查看评论编辑记录*/
function showCommentEditHistory(id){
let requestID = parseInt(new Date().getTime());
$("#comment_edit_history").data("request-id", requestID);
$("#comment_edit_history .modal-title").html(__("评论 #") + id + " " + __("的编辑记录"));
$("#comment_edit_history .modal-body").html("<div class='comment-history-loading'><span class='spinner-border text-primary'></span><span style='display: inline-block;transform: translateY(-4px);margin-left: 15px;font-size: 18px;'>加载中/span></div>");
$("#comment_edit_history").modal(null);
$.ajax({
type: 'POST',
url: argonConfig.wp_path + "wp-admin/admin-ajax.php",
dataType : "json",
data: {
action: "get_comment_edit_history",
id: id
},
success: function(result){
if ($("#comment_edit_history").data("request-id") != requestID){
return;
}
$("#comment_edit_history .modal-body").hide();
$("#comment_edit_history .modal-body").html(result.history);
$("#comment_edit_history .modal-body").fadeIn(300);
},
error: function(result){
if ($("#comment_edit_history").data("request-id") != requestID){
return;
}
$("#comment_edit_history .modal-body").hide();
$("#comment_edit_history .modal-body").html(__("加载失败"));
$("#comment_edit_history .modal-body").fadeIn(300);
}
});
}
$(document).on("click" , ".comment-edited.comment-edithistory-accessible" , function(){
showCommentEditHistory($(this).parent().parent().parent().parent().data("id"));
});
/*过长评论折叠*/
function foldLongComments(){
if (argonConfig.fold_long_comments == false){
return;
}
$(".comment-item-inner").each(function(){
if ($(this).hasClass("comment-unfolded")){
return;
}
if (this.clientHeight > 800){
$(this).addClass("comment-folded");
$(this).append("<div class='show-full-comment'><button><i class='fa fa-angle-down' aria-hidden='true'></i> " + __("展开") + "</button></div>");
}
});
}
foldLongComments();
$(document).on("click" , ".show-full-comment" , function(){
$(this).parent().removeClass("comment-folded").addClass("comment-unfolded");
});
/*评论文字头像*/
function generateCommentTextAvatar(img){
let emailHash = '';
try{
emailHash = img.attr("src").match(/([a-f\d]{32}|[A-F\d]{32})/)[0];
}catch{
emailHash = img.parent().parent().parent().find(".comment-name").text().trim();
if (emailHash == '' || emailHash == undefined){
emailHash = img.parent().find("*[class*='comment-author']").text().trim();
}
}
let hash = 0;
for (i in emailHash){
hash = (hash * 233 + emailHash.charCodeAt(i)) % 16;
}
let colors = ['#e25f50', '#f25e90', '#bc67cb', '#9672cf', '#7984ce', '#5c96fa', '#7bdeeb', '#45d0e2', '#48b7ad', '#52bc89', '#9ace5f', '#d4e34a', '#f9d715', '#fac400', '#ffaa00', '#ff8b61', '#c2c2c2', '#8ea3af', '#a1877d', '#a3a3a3', '#b0b6e3', '#b49cde', '#c2c2c2', '#7bdeeb', '#bcaaa4', '#aed77f'];
let text = $(".comment-name", img.parent().parent().parent()).text().trim()[0];
if (text == '' || text == undefined){
text = img.parent().find("*[class*='comment-author']").text().trim()[0];
}
let classList = img.attr('class') + " text-avatar";
img.prop('outerHTML', '<div class="' + classList + '" style="background-color: ' + colors[hash] + ';">' + text + '</div>');
}
document.addEventListener("error", function(e){
let img = $(e.target);
if (!img.hasClass("avatar")){
return;
}
generateCommentTextAvatar(img);
}, true);
function refreshCommentTextAvatar(){
$(".comment-item-avatar > img.avatar").each(function(index, img){
if (!img.complete){
return;
}
if (img.naturalWidth !== 0){
return false;
}
generateCommentTextAvatar($(img));
});
}
refreshCommentTextAvatar();
$(window).on("load", function(){
refreshCommentTextAvatar();
});
/*需要密码的文章加载*/
$(document).on("submit" , ".post-password-form" , function(){
$("input[type='submit']", this).attr("disabled", "disabled");
let url = $(this).attr("action");
$.pjax.form(this, {
push: false,
replace: false
});
return false;
});
/*评论分页加载*/
!function(){
$(document).on("click" , "#comments_navigation .page-item > div" , function(){
$("#comments").addClass("comments-loading");
NProgress.set(0.618);
url = $(this).attr("href");
$.ajax({
type: 'POST',
url: url,
dataType : "html",
success : function(result){
NProgress.done();
$vdom = $(result);
$("#comments").html($("#comments", $vdom).html());
$("#comments").removeClass("comments-loading");
$("body,html").animate({
scrollTop: $("#comments").offset().top - 100
}, 500, 'easeOutExpo');
foldLongComments();
calcHumanTimesOnPage();
panguInit();
},
error : function(){
window.location.href = url;
}
});
});
$(document).on("click" , "#comments_more" , function(){
$("#comments_more").attr("disabled", "disabled");
NProgress.set(0.618);
url = $(this).attr("href");
$.ajax({
type: 'POST',
url: url,
data: {
no_post_view: 'true'
},
dataType : "html",
success : function(result){
NProgress.done();
$vdom = $(result);
$("#comments > .card-body > ol.comment-list").append($("#comments > .card-body > ol.comment-list", $vdom).html());
if ($("#comments_more", $vdom).length == 0){
$("#comments_more").remove();
$(".comments-navigation-more").html("<div class='comments-navigation-nomore'>" + __("没有更多了") + "</div>");
}else{
$("#comments_more").attr("href", $("#comments_more", $vdom).attr("href"));
$("#comments_more").removeAttr("disabled");
}
foldLongComments();
calcHumanTimesOnPage();
panguInit();
},
error : function(){
window.location.href = url;
}
});
});
}();
/*URL 和# 根据 ID 定位*/
function gotoHash(hash, durtion, easing = 'easeOutExpo'){
if (!hash || hash === "#"){
return;
}
var target = null;
var decodedId = "";
try {
decodedId = decodeURIComponent(hash.slice(1));
} catch (err) {
decodedId = hash.slice(1);
}
if (decodedId) {
target = document.getElementById(decodedId);
}
if (!target) {
try {
target = document.querySelector(hash);
} catch (err) {
return;
}
}
if (!target){
return;
}
if (durtion == null){
durtion = 200;
}
$("body,html").stop().animate({
scrollTop: $(target).offset().top - 80
}, durtion, easing);
}
function getHash(url){
return url.substring(url.indexOf('#'));
}
!function(){
$(window).on("hashchange" , function(){
gotoHash(window.location.hash);
});
$(window).trigger("hashchange");
}();
/*显示文章过时信息 Toast*/
function showPostOutdateToast(){
if ($("#primary #post_outdate_toast").length > 0){
iziToast.show({
title: '',
message: $("#primary #post_outdate_toast").data("text"),
class: 'shadow-sm',
position: 'topRight',
backgroundColor: 'var(--themecolor)',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-info',
close: false,
timeout: 8000
});
$("#primary #post_outdate_toast").remove();
}
}
showPostOutdateToast();
/*Zoomify*/
// 全局 Zoomify 实例数组,用于清理
var zoomifyInstances = [];
function zoomifyInit(){
// 清理旧的 Zoomify 实例
if (zoomifyInstances.length > 0) {
zoomifyInstances.forEach(function(instance) {
try {
if (instance && typeof instance.destroy === 'function') {
instance.destroy();
}
} catch(e) {}
});
zoomifyInstances = [];
}
if (argonConfig.zoomify == false){
return;
}
if (typeof $.fn.zoomify === 'function') {
$("article img:not(.zoomify-initialized)").each(function() {
let $img = $(this);
$img.addClass('zoomify-initialized');
try {
let instance = $img.zoomify(argonConfig.zoomify).data('zoomify');
if (instance) {
zoomifyInstances.push(instance);
}
} catch(e) {}
});
}
}
zoomifyInit();
/*Fancybox*/
$.fancybox.defaults.transitionEffect = "slide";
$.fancybox.defaults.buttons = ["zoom", "fullScreen", "thumbs", "close"];
$.fancybox.defaults.lang = argonConfig.language;
$.fancybox.defaults.i18n = {
en_US: {
CLOSE: "Close",
NEXT: "Next",
PREV: "Previous",
ERROR: "The requested content cannot be loaded. <br/> Please try again later.",
PLAY_START: "Start slideshow",
PLAY_STOP: "Pause slideshow",
FULL_SCREEN: "Full screen",
THUMBS: "Thumbnails",
DOWNLOAD: "Download",
SHARE: "Share",
ZOOM: "Zoom"
},
zh_CN: {
CLOSE: "关闭",
NEXT: "下一个",
PREV: "上一个",
ERROR: "图片加载失败",
PLAY_START: "开始幻灯片展示",
PLAY_STOP: "暂停幻灯片展示",
FULL_SCREEN: "全屏",
THUMBS: "缩略图",
DOWNLOAD: "下载",
SHARE: "分享",
ZOOM: "缩放"
}
};
/*Lazyload - 使用 IntersectionObserver 实现懒加载
/*
* 优化说明:
* 1. 使用全局 lazyloadObserver 变量,便于在 PJAX 切换时清理
* 2. 添加 Observer 存在性检查,防止重复初始化
* 3. 使用 requestAnimationFrame 替代 setTimeout 实现加载效果
* 4. 实现滚动监听降级方案,支持不兼容 IntersectionObserver 的浏览器
* 5. 使用 transitionend 事件清理样式,避免固定延迟
*/
// 全局 Observer 实例,用于清理
var lazyloadObserver = null;
// 全局滚动监听 handler用于降级方案清理
var lazyloadScrollHandler = null;
function lazyloadInit() {
// 清理旧的 Observer防止重复初始化
if (lazyloadObserver) {
try {
lazyloadObserver.disconnect();
lazyloadObserver = null;
ArgonDebug.log('清理旧的 Lazyload Observer');
} catch(e) {
ArgonDebug.warn('清理 Lazyload Observer 失败:', e);
lazyloadObserver = null;
}
}
// 清理旧的滚动监听器(降级方案)
if (lazyloadScrollHandler) {
try {
window.removeEventListener('scroll', lazyloadScrollHandler);
window.removeEventListener('resize', lazyloadScrollHandler);
lazyloadScrollHandler = null;
ArgonDebug.log('清理旧的滚动监听器');
} catch(e) {
ArgonDebug.warn('清理滚动监听器失败:', e);
lazyloadScrollHandler = null;
}
}
// 检查是否启用懒加载
if (argonConfig.lazyload === false || argonConfig.lazyload === 'false') {
// 未启用懒加载时,直接加载所有图片
loadAllImagesImmediately();
return;
}
let images = document.querySelectorAll('img.lazyload[data-src]');
if (images.length === 0) {
ArgonDebug.log('没有需要懒加载的图片');
return;
}
let effect = argonConfig.lazyload_effect || 'fadeIn';
let threshold = parseInt(argonConfig.lazyload_threshold) || 800;
ArgonDebug.log(`初始化懒加载: ${images.length} 张图片, 效果: ${effect}, 阈值: ${threshold}px`);
// 使用 IntersectionObserver 实现懒加载
if ('IntersectionObserver' in window) {
try {
lazyloadObserver = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
let img = entry.target;
loadImageOptimized(img, effect);
lazyloadObserver.unobserve(img);
}
});
}, {
rootMargin: threshold + 'px 0px'
});
images.forEach(function(img) {
// 重置图片状态
img.style.opacity = '';
img.style.transform = '';
img.style.transition = '';
lazyloadObserver.observe(img);
});
ArgonDebug.log('使用 IntersectionObserver 实现懒加载');
} catch(e) {
ArgonDebug.error('IntersectionObserver 初始化失败,使用降级方案:', e);
lazyloadFallback(images, effect, threshold);
}
} else {
// 降级方案:使用滚动监听
ArgonDebug.log('浏览器不支持 IntersectionObserver使用滚动监听降级方案');
lazyloadFallback(images, effect, threshold);
}
}
/**
* 优化的图片加载函数
* 使用 requestAnimationFrame 替代 setTimeout
* @param {HTMLImageElement} img - 图片元素
* @param {string} effect - 加载效果类型 ('fadeIn' 或'slideDown')
*/
function loadImageOptimized(img, effect) {
let src = img.getAttribute('data-src');
if (!src) {
// 如果没有 data-src取消 Observer 监听
if (lazyloadObserver) {
lazyloadObserver.unobserve(img);
}
return;
}
// 预加载图片
let tempImg = new Image();
tempImg.onload = function() {
// 使用 requestAnimationFrame 优化 DOM 操作
requestAnimationFrame(function() {
img.src = src;
img.removeAttribute('data-src');
let srcset = img.getAttribute('data-srcset');
if (srcset) {
img.setAttribute('srcset', srcset);
img.removeAttribute('data-srcset');
}
let sizes = img.getAttribute('data-sizes');
if (sizes) {
img.setAttribute('sizes', sizes);
img.removeAttribute('data-sizes');
}
img.classList.remove('lazyload');
// 移除所有lazyload-style-* 类
img.className = img.className.replace(/\blazyload-style-\d+\b/g, '').trim();
// 应用加载效果
applyLoadEffectOptimized(img, effect);
});
};
tempImg.onerror = function() {
// 加载失败时使用降级方案
requestAnimationFrame(function() {
img.src = src;
img.removeAttribute('data-src');
let srcset = img.getAttribute('data-srcset');
if (srcset) {
img.setAttribute('srcset', srcset);
img.removeAttribute('data-srcset');
}
let sizes = img.getAttribute('data-sizes');
if (sizes) {
img.setAttribute('sizes', sizes);
img.removeAttribute('data-sizes');
}
img.classList.remove('lazyload');
img.className = img.className.replace(/\blazyload-style-\d+\b/g, '').trim();
// 取消 Observer 监听
if (lazyloadObserver) {
lazyloadObserver.unobserve(img);
}
});
};
tempImg.src = src;
}
/**
* 使用 requestAnimationFrame 应用加载效果
* @param {HTMLImageElement} img - 图片元素
* @param {string} effect - 加载效果类型 ('fadeIn' 或'slideDown')
*/
function applyLoadEffectOptimized(img, effect) {
if (effect === 'fadeIn') {
img.style.opacity = '0';
img.style.transition = 'opacity 0.3s ease';
requestAnimationFrame(function() {
requestAnimationFrame(function() {
img.style.opacity = '1';
});
});
// 使用 transitionend 事件清理样式,更可靠
img.addEventListener('transitionend', function cleanup() {
img.style.transition = '';
img.removeEventListener('transitionend', cleanup);
}, {once: true});
} else if (effect === 'slideDown') {
img.style.opacity = '0';
img.style.transform = 'translateY(-20px)';
img.style.transition = 'opacity 0.3s ease, transform 0.3s ease';
requestAnimationFrame(function() {
requestAnimationFrame(function() {
img.style.opacity = '1';
img.style.transform = 'translateY(0)';
});
});
// 使用 transitionend 事件清理样式
img.addEventListener('transitionend', function cleanup() {
img.style.transition = '';
img.style.transform = '';
img.removeEventListener('transitionend', cleanup);
}, {once: true});
}
}
/**
* 降级方案:使用滚动监听实现懒加载
* 当浏览器不支持IntersectionObserver 时使用
* @param {NodeList|Array} images - 需要懒加载的图片元素列表
* @param {string} effect - 加载效果类型
* @param {number} threshold - 提前加载的阈值(像素)
*/
function lazyloadFallback(images, effect, threshold) {
let loadedImages = new Set();
function checkImagesInView() {
let viewportHeight = window.innerHeight;
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
images.forEach(function(img) {
if (loadedImages.has(img)) return;
let rect = img.getBoundingClientRect();
if (rect.top < viewportHeight + threshold && rect.bottom > -threshold) {
loadImageOptimized(img, effect);
loadedImages.add(img);
}
});
// 如果所有图片都已加载,清理监听器
if (loadedImages.size === images.length) {
if (lazyloadScrollHandler) {
window.removeEventListener('scroll', lazyloadScrollHandler);
window.removeEventListener('resize', lazyloadScrollHandler);
lazyloadScrollHandler = null;
ArgonDebug.log('所有图片已加载,清理滚动监听器');
}
}
}
// 使用 eventManager 的节流函数优化性能
lazyloadScrollHandler = argonEventManager ?
argonEventManager.throttle(checkImagesInView, 100) :
checkImagesInView;
// 绑定事件监听器
window.addEventListener('scroll', lazyloadScrollHandler, {passive: true});
window.addEventListener('resize', lazyloadScrollHandler, {passive: true});
// 立即检查一次
checkImagesInView();
}
/**
* 立即加载所有图片(懒加载禁用时)
* 不应用任何加载效果,直接替换 src
*/
function loadAllImagesImmediately() {
let images = document.querySelectorAll('img.lazyload[data-src]');
images.forEach(function(img) {
let src = img.getAttribute('data-src');
if (src) {
img.src = src;
img.removeAttribute('data-src');
let srcset = img.getAttribute('data-srcset');
if (srcset) {
img.setAttribute('srcset', srcset);
img.removeAttribute('data-srcset');
}
let sizes = img.getAttribute('data-sizes');
if (sizes) {
img.setAttribute('sizes', sizes);
img.removeAttribute('data-sizes');
}
img.classList.remove('lazyload');
img.className = img.className.replace(/\blazyload-style-\d+\b/g, '').trim();
}
});
}
// 确保 DOM 加载完成后再初始化懒加载
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', lazyloadInit);
} else {
// DOM 已经加载完成,立即初始化
lazyloadInit();
}
/*Pangu.js*/
function panguInit(){
if (argonConfig.pangu.indexOf("article") >= 0){
pangu.spacingElementByClassName('post-content');
}
if (argonConfig.pangu.indexOf("comment") >= 0){
pangu.spacingElementById('comments');
}
if (argonConfig.pangu.indexOf("shuoshuo") >= 0){
pangu.spacingElementByClassName('shuoshuo-content');
}
}
panguInit();
/*Clamp.js*/
function clampInit(){
$(".clamp").each(function(index, dom) {
$clamp(dom, {clamp: dom.getAttribute("clamp-line")});
});
}
clampInit();
/*Tippy.js*/
function tippyInit(){
//Reference Popover
tippy('sup.reference[data-content]:not(.tippy-initialized)', {
content: (reference) => reference.getAttribute('data-content'),
allowHTML: true,
interactive: true,theme: 'light scroll-y',
delay: [100, 250],
animation: 'fade'
});
$("sup.reference[data-content]:not(.tippy-initialized)").addClass("tippy-initialized");
}
tippyInit();
/*Banner 全屏封面相关*/
if ($("html").hasClass("banner-as-cover")){
function classInit(){
if ($("#main").hasClass("article-list-home")){
if (!$("html").hasClass("is-home")){
$("html").addClass("is-home");
$("html").trigger("resize");
}
}else{
if ($("html").hasClass("is-home")){
$("html").removeClass("is-home");
$("html").trigger("resize");
}
}
}
classInit();
new MutationObserver(function(mutations, observer){
classInit();
}).observe(document.querySelector("#primary"), {
'childList': true
});
$(".cover-scroll-down").on("click" , function(){
gotoHash("#content", 600, 'easeOutCirc');
$("#content").focus();
});
$fabs = $("#float_action_buttons");
$coverScrollDownBtn = $(".cover-scroll-down");
function changeWidgetsDisplayStatus(){
let scrollTop = $(window).scrollTop();
if (scrollTop >= window.outerHeight * 0.2){
$fabs.removeClass("hidden");
}else{
$fabs.addClass("hidden");
}
if (scrollTop >= window.outerHeight * 0.6){
$coverScrollDownBtn.addClass("hidden");
}else{
$coverScrollDownBtn.removeClass("hidden");
}
}
changeWidgetsDisplayStatus();
$(window).scroll(function(){
changeWidgetsDisplayStatus();
});
$(window).resize(function(){
changeWidgetsDisplayStatus();
});
}
/*Pjax*/
var pjaxScrollTop = 0, pjaxLoading = false;
// ==========================================================================
// 统一的资源清理管理器
// ==========================================================================
// 在 PJAX 页面切换时清理所有旧页面资源,避免内存泄漏和功能失效
// Validates: Requirements 1.1, 1.2, 1.3, 1.4, 2.3, 6.1
// ==========================================================================
/**
* 清理 Lazyload Observer 和滚动监听器
* @returns {void}
*/
function cleanupLazyloadObserver() {
// 清理 IntersectionObserver
if (lazyloadObserver) {
try {
lazyloadObserver.disconnect();
lazyloadObserver = null;
ArgonDebug.log('Lazyload Observer 已清理');
} catch(e) {
ArgonDebug.warn('清理 Lazyload Observer 失败:', e);
lazyloadObserver = null;
}
}
// 清理滚动监听器(降级方案)
if (lazyloadScrollHandler) {
try {
window.removeEventListener('scroll', lazyloadScrollHandler);
window.removeEventListener('resize', lazyloadScrollHandler);
lazyloadScrollHandler = null;
ArgonDebug.log('Lazyload 滚动监听器已清理');
} catch(e) {
ArgonDebug.warn('清理 Lazyload 滚动监听器失败:', e);
lazyloadScrollHandler = null;
}
}
}
/**
* 清理 Zoomify 实例
* @returns {void}
*/
function cleanupZoomifyInstances() {
if (zoomifyInstances && zoomifyInstances.length > 0) {
let cleanedCount = 0;
zoomifyInstances.forEach(function(instance) {
try {
if (instance && typeof instance.destroy === 'function') {
instance.destroy();
cleanedCount++;
}
} catch(e) {
ArgonDebug.warn('销毁 Zoomify 实例失败:', e);
}
});
zoomifyInstances = [];
ArgonDebug.log(`已清理 ${cleanedCount} 个 Zoomify 实例`);
}
// 移除初始化标记
$('img.zoomify-initialized').removeClass('zoomify-initialized');
}
/**
* 清理 Tippy 实例
* @returns {void}
*/
function cleanupTippyInstances() {
if (typeof tippy !== 'undefined') {
let cleanedCount = 0;
document.querySelectorAll('[data-tippy-root]').forEach(function(el) {
try {
if (el._tippy && typeof el._tippy.destroy === 'function') {
el._tippy.destroy();
cleanedCount++;
}
} catch(e) {
ArgonDebug.warn('销毁 Tippy 实例失败:', e);
}
});
$('.tippy-initialized').removeClass('tippy-initialized');
if (cleanedCount > 0) {
ArgonDebug.log(`已清理 ${cleanedCount} 个 Tippy 实例`);
}
}
}
/**
* 清理动态添加的 style 标签
* @returns {void}
*/
function cleanupDynamicStyles() {
try {
// 只清理标记为动态的样式
const dynamicStyles = document.querySelectorAll('style[data-dynamic="true"]');
if (dynamicStyles.length > 0) {
dynamicStyles.forEach(function(style) {
style.remove();
});
ArgonDebug.log(`已清理 ${dynamicStyles.length} 个动态样式`);
}
} catch(e) {
ArgonDebug.warn('清理动态样式失败:', e);
}
}
/**
* 清理动态添加的 script 标签
* @returns {void}
*/
function cleanupDynamicScripts() {
try {
// 只清理标记为动态的脚本
const dynamicScripts = document.querySelectorAll('script[data-dynamic="true"]');
if (dynamicScripts.length > 0) {
dynamicScripts.forEach(function(script) {
script.remove();
});
ArgonDebug.log(`已清理 ${dynamicScripts.length} 个动态脚本`);
}
} catch(e) {
ArgonDebug.warn('清理动态脚本失败:', e);
}
}
/**
* 清理事件监听器
* @returns {void}
*/
function cleanupEventListeners() {
try {
// 注意:大部分事件使用事件委托,不需要手动清理
// 这里只清理特定的非委托事件
// Lazyload 滚动监听器已在 cleanupLazyloadObserver() 中清理
ArgonDebug.log('事件监听器已清理');
} catch(e) {
ArgonDebug.warn('清理事件监听器失败:', e);
}
}
/**
* 清理 PJAX 页面切换前的所有资源
* 统一的资源清理管理器,在 pjax:beforeReplace 事件中调用
*
* 清理内容包括:
* - Lazyload Observer
* - Zoomify 实例
* - Tippy 实例
* - 动态 style 标签
* - 动态 script 标签
* - 事件监听器
*
* @returns {void}
*/
function cleanupPjaxResources() {
ArgonDebug.log('开始清理 PJAX 资源...');
// 按顺序清理各类资源
cleanupLazyloadObserver();
cleanupZoomifyInstances();
cleanupTippyInstances(); cleanupDynamicStyles();
cleanupDynamicScripts();
cleanupEventListeners();
ArgonDebug.log('PJAX 资源清理完成');
}
/**
* 重置 GT4 验证码
* 清理状态变量、隐藏字段和容器,然后重新初始化
* 在 pjax:end 事件中调用
*/
function resetGT4Captcha() {
try {
if ($('#geetest-captcha').length > 0) {
// 重置前端状态,避免重复提交阻塞
window.geetestVerified = false;
window.geetestAutoSubmitting = false;
// 清空隐藏字段防止残留导致pass_token 复用
$('#geetest_lot_number').val('');
$('#geetest_captcha_output').val('');
$('#geetest_pass_token').val('');
$('#geetest_gen_time').val('');
// 清空容器防止重复appendTo 导致多个实例
$('#geetest-captcha').empty();
// 若页面脚本已提供初始化方法,则调用以加载验证码
if (typeof initGeetestCaptcha === 'function') {
initGeetestCaptcha();
} else if (typeof loadGeetestScript === 'function' && typeof initGeetestCaptchaCore === 'function') {
loadGeetestScript(function() {
initGeetestCaptchaCore();
});
}
}
} catch (e) {
ArgonDebug.warn('Geetest init on PJAX failed:', e);
}
}
function handleHashNavigation() {
if (!location.hash) {
return;
}
let target = null;
try {
target = document.getElementById(decodeURIComponent(location.hash.slice(1)));
} catch (e) {
target = document.querySelector(location.hash);
}
if (!target) {
return;
}
try { highlightJsRender(); } catch (err) { ArgonDebug.error('highlightJsRender failed:', err); }
try { lazyloadInit(); } catch (err) { ArgonDebug.error('lazyloadInit failed:', err); }
}
// ==========================================================================
// 内联脚本执行器 (Inline Script Executor)
// ==========================================================================
/**
* 执行单个脚本元素
* 需求 4.4: 脚本执行失败时捕获错误并记录日志,不中断其他脚本执行
*
* @param {HTMLScriptElement} oldScript - 原始脚本元素
* @returns {boolean} 是否执行成功
*/
function executeScript(oldScript) {
try {
// 创建新的 script 元素
const newScript = document.createElement('script');
// 复制脚本内容
if (oldScript.textContent) {
newScript.textContent = oldScript.textContent;
}
// 复制所有属性(包括 type, async, defer 等)
// 需求 4.5: 尊重 async 和 defer 属性的执行时机
Array.from(oldScript.attributes).forEach(attr => {
newScript.setAttribute(attr.name, attr.value);
});
// 将脚本添加到 head 并立即执行
document.head.appendChild(newScript);
// 执行后立即移除,避免污染 DOM
document.head.removeChild(newScript);
ArgonDebug.log('Script executed successfully:', oldScript.textContent.substring(0, 50) + '...');
return true;
} catch (error) {
// 需求 4.4: 捕获错误并记录日志
ArgonDebug.error('Script execution failed:', error);
ArgonDebug.error('Failed script content:', oldScript.textContent);
return false;
}
}
/**
* 执行新页面中的所有内联脚本
* 需求 4.1: 提取新页面中的所有 script 标签
* 需求 4.2: 区分内联脚本和外部脚本
* 需求 4.3: 按照脚本在 DOM 中的顺序执行
* 需求 4.4: 脚本执行失败不中断其他脚本执行
*
* @param {HTMLElement|Document} container - 新页面的容器元素或文档对象
* @returns {Object} 执行结果统计 {total, success, failed}
*/
function executeInlineScripts(container) {
// 如果没有传入容器,使用整个文档
if (!container) {
container = document;
}
// 需求 4.1: 提取所有 script 标签
const scripts = container.querySelectorAll('script');
if (scripts.length === 0) {
ArgonDebug.log('No scripts found in new page');
return {total: 0, success: 0, failed: 0};
}
let successCount = 0;
let failedCount = 0;
ArgonDebug.log(`Found ${scripts.length} script tags in new page`);
// 需求 4.3: 按照脚本在 DOM 中的顺序执行
scripts.forEach((script, index) => {
if (script.getAttribute('data-pjax-executed') === 'true') {
return;
}
// 需求 4.2: 只执行内联脚本(没有 src 属性的脚本)
if (!script.src) {
// 跳过空脚本
if (!script.textContent || script.textContent.trim() === '') {
ArgonDebug.log(`Script ${index + 1}: Empty, skipped`);
return;
}
ArgonDebug.log(`Executing inline script ${index + 1}/${scripts.length}`);
// 需求 4.4: 错误隔离 - 单个脚本失败不影响其他脚本
const success = executeScript(script);
if (success) {
script.setAttribute('data-pjax-executed', 'true');
successCount++;
} else {
failedCount++;
}
} else {
// 外部脚本由浏览器自动加载,不需要手动执行
ArgonDebug.log(`Script ${index + 1}: External (${script.src}), skipped`);
}
});
const result = {
total: scripts.length,
success: successCount,
failed: failedCount
};
ArgonDebug.log('Script execution completed:', result);
return result;
}
var pjaxContainerSelectors = ['#primary', '#leftbar_part1_menu', '#leftbar_part2_inner', '.page-information-card-container', '#rightbar', '#wpadminbar'];
var pjaxContainers = pjaxContainerSelectors.filter(function(selector) {
return document.querySelector(selector);
});
// ==========================================================================
// 现代化页面加载系统
// ==========================================================================
/**
* 页面加载管理器 - 提供智能加载动画和进度追踪
*/
const PageLoader = (function() {
// 配置常量
const CONFIG = {
OVERLAY_ID: 'page-loader',
MIN_DISPLAY_TIME: 400, // 最小显示时间(避免闪烁)
FADE_DURATION: 350, // 淡出动画时长
PROGRESS_STEP: 0.1, // 进度条步进
PROGRESS_INTERVAL: 200, // 进度更新间隔
SKELETON_DELAY: 150 // 骨架屏延迟显示
};
// 状态管理
let state = {
element: null,
isVisible: false,
startTime: 0,
progress: 0,
progressTimer: null,
hideTimer: null,
skeletonTimer: null
};
/**
* 创建加载动画 HTML
*/
function createHTML() {
return `
<div class="page-loader-backdrop"></div>
<div class="page-loader-content">
<!-- 进度环 -->
<div class="loader-ring-container">
<svg class="loader-ring" viewBox="0 0 100 100">
<circle class="loader-ring-bg" cx="50" cy="50" r="45"></circle>
<circle class="loader-ring-progress" cx="50" cy="50" r="45"></circle>
</svg>
<div class="loader-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 2v4m0 12v4M4.93 4.93l2.83 2.83m8.48 8.48l2.83 2.83M2 12h4m12 0h4M4.93 19.07l2.83-2.83m8.48-8.48l2.83-2.83"/>
</svg>
</div>
</div>
<!-- 加载文字 -->
<div class="loader-text">
<div class="loader-title">加载中</div>
<div class="loader-subtitle">正在为您准备内容</div>
</div>
<!-- 骨架屏(延迟显示) -->
<div class="loader-skeleton">
<div class="skeleton-card">
<div class="skeleton-image"></div>
<div class="skeleton-content">
<div class="skeleton-title"></div>
<div class="skeleton-line"></div>
<div class="skeleton-line short"></div>
</div>
</div>
</div>
</div>
`;
}
/**
* 创建加载器元素
*/
function createElement() {
const el = document.createElement('div');
el.id = CONFIG.OVERLAY_ID;
el.className = 'page-loader';
el.innerHTML = createHTML();
return el;
}
/**
* 获取或创建元素
*/
function getElement() {
if (!state.element) {
state.element = document.getElementById(CONFIG.OVERLAY_ID);
if (!state.element) {
state.element = createElement();
document.body.appendChild(state.element);
}
}
return state.element;
}
/**
* 更新进度环
*/
function updateProgress(progress) {
const el = state.element;
if (!el) return;
const circle = el.querySelector('.loader-ring-progress');
if (circle) {
const circumference = 2 * Math.PI * 45;
const offset = circumference - (progress / 100) * circumference;
circle.style.strokeDashoffset = offset;
}
state.progress = progress;
}
/**
* 自动递增进度
*/
function startProgressAnimation() {
stopProgressAnimation();
state.progress = 0;
updateProgress(0);
state.progressTimer = setInterval(function() {
if (state.progress < 90) {
// 使用缓动函数,越接近 90% 越慢
const increment = CONFIG.PROGRESS_STEP * (1 - state.progress / 100);
state.progress = Math.min(90, state.progress + increment * 10);
updateProgress(state.progress);
}
}, CONFIG.PROGRESS_INTERVAL);
}
/**
* 停止进度动画
*/
function stopProgressAnimation() {
if (state.progressTimer) {
clearInterval(state.progressTimer);
state.progressTimer = null;
}
}
/**
* 完成进度到 100%
*/
function completeProgress() {
stopProgressAnimation();
updateProgress(100);
}
/**
* 显示加载器
*/
function show() {
// 清理之前的定时器
if (state.hideTimer) {
clearTimeout(state.hideTimer);
state.hideTimer = null;
}
if (state.skeletonTimer) {
clearTimeout(state.skeletonTimer);
state.skeletonTimer = null;
}
const el = getElement();
state.startTime = Date.now();
state.isVisible = true;
// 移除隐藏类,添加显示类
el.classList.remove('is-hiding');
void el.offsetWidth; // 强制重排
el.classList.add('is-visible');
// 启动进度动画
startProgressAnimation();
// 延迟显示骨架屏(避免快速加载时闪烁)
state.skeletonTimer = setTimeout(function() {
if (state.isVisible && el) {
el.classList.add('show-skeleton');
}
}, CONFIG.SKELETON_DELAY);
}
/**
* 隐藏加载器
*/
function hide() {
if (!state.isVisible) return;
const el = state.element;
if (!el) return;
// 完成进度
completeProgress();
// 计算已显示时间
const elapsedTime = Date.now() - state.startTime;
const remainingTime = Math.max(0, CONFIG.MIN_DISPLAY_TIME - elapsedTime);
// 确保最小显示时间后再隐藏
state.hideTimer = setTimeout(function() {
el.classList.add('is-hiding');
el.classList.remove('show-skeleton');
// 动画结束后清理
setTimeout(function() {
el.classList.remove('is-visible', 'is-hiding');
state.isVisible = false;
stopProgressAnimation();
}, CONFIG.FADE_DURATION);
}, remainingTime);
}
/**
* 设置进度(手动控制)
*/
function setProgress(progress) {
progress = Math.max(0, Math.min(100, progress));
stopProgressAnimation();
updateProgress(progress);
}
/**
* 销毁加载器
*/
function destroy() {
stopProgressAnimation();
if (state.hideTimer) {
clearTimeout(state.hideTimer);
state.hideTimer = null;
}
if (state.skeletonTimer) {
clearTimeout(state.skeletonTimer);
state.skeletonTimer = null;
}
if (state.element && state.element.parentNode) {
state.element.parentNode.removeChild(state.element);
}
state.element = null;
state.isVisible = false;
}
// 公开 API
return {
show: show,
hide: hide,
setProgress: setProgress,
destroy: destroy
};
})();
function startPageTransition() {
document.documentElement.classList.add('page-transition-enter');
pjaxContainers.forEach(function(selector) {
var c = document.querySelector(selector);
if (c) c.classList.add('page-transition-content');
});
}
function activatePageTransition() {
requestAnimationFrame(function() {
document.documentElement.classList.add('page-transition-active');
});
}
function endPageTransition() {
document.documentElement.classList.remove('page-transition-active');
document.documentElement.classList.remove('page-transition-enter');
pjaxContainers.forEach(function(selector) {
var c = document.querySelector(selector);
if (c) c.classList.remove('page-transition-content');
});
}
$.pjax.defaults.timeout = 10000;
$.pjax.defaults.container = pjaxContainers;
$.pjax.defaults.fragment = pjaxContainers;
/*
* PJAX 事件处理优化说明:
* 1. pjax:beforeReplace - 统一清理资源LazyLoad Observer、Zoomify、Tippy
* 2. pjax:complete - 单次初始化所有功能模块,添加错误处理,初始化所有功能模块
* 3. pjax:end - 只处理特定任务移动端目录重置、GT4 验证码重置)
* 4. 移除了重复的初始化调用,避免资源泄漏和性能问题
*
* 需求映射:
* - pjax:beforeReplace: 需求 1.1-1.4 (资源清理)
* - pjax:complete: 需求 1.5, 1.6 (模块初始化和错误隔离)
* - pjax:end: 需求 1.7 (特定任务处理)
*/
if (argonConfig.disable_pjax != true && argonConfig.disable_pjax != 'true') {
$(document).pjax(
"a[href]:not([no-pjax]):not(.no-pjax):not([target='_blank']):not([download]):not(.reference-link):not(.reference-list-backlink):not([href^='#'])",
pjaxContainers.length ? pjaxContainers[0] : '#primary',
{ fragment: (pjaxContainers.length ? pjaxContainers : ['#primary']), timeout: $.pjax.defaults.timeout }
)
.on('pjax:click', function(e, f, g){
NProgress.remove();
NProgress.start();
pjaxLoading = true;
PageLoader.show();
}).on('pjax:afterGetContainers', function(e, f, g) {
pjaxScrollTop = 0;
if ($("html").hasClass("banner-as-cover")){
if (g.is(".page-link")){
pjaxScrollTop = $("#content").offset().top - 80;
}
}
}).on('pjax:send', function() {
NProgress.set(0.618);
startPageTransition();
}).on('pjax:beforeReplace', function(e, dom) {
// ========== 需求 1.1-1.4: 清理旧页面的所有资源 ==========
// 调用统一的资源清理管理器
// 清理内容Lazyload Observer、Zoomify、Tippy 实例、动态标签
cleanupPjaxResources();
// 更新 UI 状态
if ($("#post_comment", dom[0]).length > 0){
$("#fabtn_go_to_comment").removeClass("d-none");
}else{
$("#fabtn_go_to_comment").addClass("d-none");
}
// 处理滚动位置
if ($("html").hasClass("banner-as-cover")){
if (!$("#main").hasClass("article-list-home")){
pjaxScrollTop = 0;
}
}
}).on('pjax:complete', function() {
// ========== 需求 1.5, 1.6: 重新初始化所有功能模块 ==========
pjaxLoading = false;
NProgress.inc();
startPageTransition();
activatePageTransition();
setTimeout(function() {
PageLoader.hide();
endPageTransition();
}, 320);
// ========== 需求 4.1-4.5: 执行新页面中的内联脚本 ==========
try {
pjaxContainers.forEach(function(selector) {
var container = document.querySelector(selector);
if (container) {
executeInlineScripts(container);
}
});
} catch (err) {
ArgonDebug.error('executeInlineScripts failed:', err);
}
// MathJax 数学公式渲染
try{
if (MathJax != undefined){
if (MathJax.Hub != undefined){
MathJax.Hub.Typeset();
}else{
MathJax.typeset();
}
}
}catch (err){}
// KaTeX 数学公式渲染
try{
if (renderMathInElement != undefined){
renderMathInElement(document.body,{
delimiters: [
{left: "$$", right: "$$", display: true},
{left: "$", right: "$", display: false},
{left: "\\(", right: "\\)", display: false}
]
});
}
}catch (err){}
// 初始化各个功能模块(添加错误处理确保单个模块失败不影响其他模块)
try { waterflowInit(); } catch (err) { ArgonDebug.error('waterflowInit failed:', err); }
try { lazyloadInit(); } catch (err) { ArgonDebug.error('lazyloadInit failed:', err); }
try { zoomifyInit(); } catch (err) { ArgonDebug.error('zoomifyInit failed:', err); }
try { highlightJsRender(); } catch (err) { ArgonDebug.error('highlightJsRender failed:', err); }
try { panguInit(); } catch (err) { ArgonDebug.error('panguInit failed:', err); }
try { clampInit(); } catch (err) { ArgonDebug.error('clampInit failed:', err); }
try { tippyInit(); } catch (err) { ArgonDebug.error('tippyInit failed:', err); }
try { getGithubInfoCardContent(); } catch (err) { ArgonDebug.error('getGithubInfoCardContent failed:', err); }
try { showPostOutdateToast(); } catch (err) { ArgonDebug.error('showPostOutdateToast failed:', err); }
try { calcHumanTimesOnPage(); } catch (err) { ArgonDebug.error('calcHumanTimesOnPage failed:', err); }
try { foldLongComments(); } catch (err) { ArgonDebug.error('foldLongComments failed:', err); }
try { foldLongShuoshuo(); } catch (err) { ArgonDebug.error('foldLongShuoshuo failed:', err); }
try { handleHashNavigation(); } catch (err) { ArgonDebug.error('handleHashNavigation failed:', err); }
$("html").trigger("resize");
// 恢复滚动位置
if (pjaxScrollTop > 0) {
$("body,html").scrollTop(pjaxScrollTop);
pjaxScrollTop = 0;
}
// 调用用户自定义的 PJAX 加载完成回调
if (typeof(window.pjaxLoaded) == "function"){
try{
window.pjaxLoaded();
}catch (err){
ArgonDebug.error(err);
}
}
NProgress.done();
}).on('pjax:error', function() {
PageLoader.hide();
endPageTransition();
pjaxLoading = false;
}).on('pjax:end', function() {
// ========== 需求 1.7: 执行特定任务 ==========
// 重置移动端目录状态
if (typeof window.resetMobileCatalog === 'function') {
try {
window.resetMobileCatalog();
} catch (err) {
ArgonDebug.warn('resetMobileCatalog failed:', err);
}
}
// GT4: PJAX 后确保评论页验证码已初始化
resetGT4Captcha();
});
}
window.addEventListener('hashchange', function() {
handleHashNavigation();
});
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
handleHashNavigation();
});
} else {
handleHashNavigation();
}
/*Reference 跳转*/
$(document).on("click", ".reference-link , .reference-list-backlink" , function(e){
e.preventDefault();
var href = $(this).attr("href");
if (!href || href === "#" ) { return; }
var $target;
try {
$target = $(href);
} catch (err) {
return;
}
$("body,html").animate({
scrollTop: $target.offset().top - document.body.clientHeight / 2 - 75
}, 500, 'easeOutExpo')
setTimeout(function(){
if ($target.is("li")){
$(".space", $target).focus();
}else{
$target.focus();
}
}, 1);
});
/*Tags Dialog pjax 加载后自动关闭 */
$(document).on("click" , "#blog_tags .tag" , function(){
$("#blog_tags button.close").trigger("click");
});
$(document).on("click" , "#blog_categories .tag" , function(){
$("#blog_categories button.close").trigger("click");
});
/*侧栏 & 顶栏菜单手机适配*/
!function(){
$(document).on("click" , "#fabtn_open_sidebar, #open_sidebar" , function(){
$("html").addClass("leftbar-opened");
// 侧边栏打开时初始化移动端文章目录
initMobileCatalog();
// 如果有文章目录,默认展开
setTimeout(function() {
var catalogSection = $("#mobile_catalog_toggle").closest(".leftbar-mobile-collapse-section");
if (catalogSection.length > 0 && !catalogSection.hasClass("expanded")) {
catalogSection.addClass("expanded");
initMobileCatalog();
setTimeout(scrollMobileCatalogToActive, 200);
}
}, 100);
});
$(document).on("click" , "#sidebar_mask, #leftbar_close_btn" , function(){
$("html").removeClass("leftbar-opened");
// 关闭侧边栏时折叠所有面板
$(".leftbar-mobile-collapse-section.expanded").removeClass("expanded");
});
$(document).on("click" , "#leftbar a[href]:not([no-pjax]):not([href^='#']):not(.has-submenu)" , function(){
$("html").removeClass("leftbar-opened");
// 关闭侧边栏时折叠所有面板
$(".leftbar-mobile-collapse-section.expanded").removeClass("expanded");
});
// 移动端子菜单展开/收起
$(document).on("click" , ".leftbar-mobile-menu-item.has-children > a.has-submenu" , function(e){
e.preventDefault();
$(this).parent().toggleClass("expanded");
});
// 移动端侧边栏搜索
$(document).on("keydown" , "#leftbar_mobile_search_input" , function(e){
if (e.keyCode != 13){
return;
}
let word = $(this).val();
if (word == ""){
return;
}
$("html").removeClass("leftbar-opened");
// 关闭侧边栏时折叠所有面板
$(".leftbar-mobile-collapse-section.expanded").removeClass("expanded");
searchPosts(word);
});
$(document).on("click" , "#navbar_global.show .navbar-nav a[href]:not([no-pjax]):not([href^='#'])" , function(){
$("#navbar_global .navbar-toggler").click();
});
$(document).on("click" , "#navbar_global.show #navbar_search_btn_mobile" , function(){
$("#navbar_global .navbar-toggler").click();
});
// ========== 移动端折叠面板交互==========
$(document).on("click", ".leftbar-mobile-collapse-header", function(e) {
var section = $(this).closest(".leftbar-mobile-collapse-section");
var header = $(this);
var isExpanded = section.hasClass("expanded");
// 切换展开状态
section.toggleClass("expanded");
// 如果是文章目录面板展开,初始化目录并滚动到当前位置
if (!isExpanded && header.attr("id") === "mobile_catalog_toggle") {
initMobileCatalog();
setTimeout(scrollMobileCatalogToActive, 100);
}
});
// ========== 移动端文章目录初始化 ==========
window.mobileCatalogInitialized = false;
function initMobileCatalog() {
if (window.mobileCatalogInitialized) return;
var $mobileContainer = $("#leftbar_mobile_catalog");
var $postContent = $("#post_content");
if ($mobileContainer.length === 0) return;
if ($postContent.length === 0) return;
// 直接生成目录,不依赖 headIndex 插件
var $headers = $postContent.find('h1, h2, h3, h4, h5, h6');
if ($headers.length === 0) {
$mobileContainer.html('<div class="no-catalog">暂无目录</div>');
return;
}
// 构建目录树
var toc = [];
var stack = [{ level: 0, children: toc }];
$headers.each(function(index) {
var $h = $(this);
var level = parseInt(this.tagName.charAt(1));
var text = $h.text().trim();
var id = $h.attr('id');
// 确保标题有ID
if (!id) {
id = 'mobile-heading-' + index;
$h.attr('id', id);
}
var item = { id: id, text: text, level: level, children: [] };
// 找到合适的父级
while (stack.length > 1 && stack[stack.length - 1].level >= level) {
stack.pop();
}
stack[stack.length - 1].children.push(item);
stack.push({ level: level, children: item.children });
});
// 递归生成 HTML
function buildHtml(items, isRoot) {
if (!items || items.length === 0) return '';
var html = isRoot ? '<ul>' : '<ul class="index-subItem-box">';
for (var i = 0; i < items.length; i++) {
var item = items[i];
html += '<li class="index-item">';
html += '<a href="#' + item.id + '" class="index-link" data-target="' + item.id + '">' + item.text + '</a>';
if (item.children.length > 0) {
html += buildHtml(item.children, false);
}
html += '</li>';
}
html += '</ul>';
return html;
}
$mobileContainer.html(buildHtml(toc, true));
window.mobileCatalogInitialized = true;
// 绑定点击事件
$mobileContainer.off('click.mobileCatalog').on('click.mobileCatalog', '.index-link', function(e) {
e.preventDefault();
var targetId = $(this).attr('href');
if (targetId) {
var $target = $(targetId);
if ($target.length) {
$mobileContainer.find('.index-item').removeClass('current');
$(this).closest('.index-item').addClass('current');
$('html, body').animate({
scrollTop: $target.offset().top - 80
}, 500, 'easeOutExpo');
// 点击后关闭侧边栏
setTimeout(function() {
$("html").removeClass("leftbar-opened");
// 关闭侧边栏时折叠所有面板
$(".leftbar-mobile-collapse-section.expanded").removeClass("expanded");
}, 150);
}
}
});
// 初始化高亮并启动滚动监听
updateMobileCatalogHighlight();
setTimeout(scrollMobileCatalogToActive, 150);
}
// 更新移动端目录高亮
function updateMobileCatalogHighlight() {
var $mobileContainer = $("#leftbar_mobile_catalog");
var $postContent = $("#post_content");
if ($mobileContainer.length === 0 || $postContent.length === 0) return;
var scrollTop = $(window).scrollTop();
var $headers = $postContent.find('h1, h2, h3, h4, h5, h6');
var currentId = null;
$headers.each(function() {
var $h = $(this);
var top = $h.offset().top - 100;
if (scrollTop >= top) {
currentId = $h.attr('id');
}
});
if (currentId) {
$mobileContainer.find('.index-item').removeClass('current');
$mobileContainer.find('.index-link[href="#' + currentId + '"]').closest('.index-item').addClass('current');
}
}
// 重置移动端目录状态由PJAX 调用)
window.resetMobileCatalog = function() {
window.mobileCatalogInitialized = false;
$("#leftbar_mobile_catalog").empty();
};
// 滚动目录到当前激活项
function scrollMobileCatalogToActive() {
var container = $("#leftbar_mobile_catalog");
var activeItem = container.find(".index-item.current");
if (activeItem.length > 0 && container.length > 0) {
var containerHeight = container.height();
var itemTop = activeItem.position().top;
var itemHeight = activeItem.outerHeight();
var scrollTop = container.scrollTop();
var targetScroll = scrollTop + itemTop - (containerHeight / 2) + (itemHeight / 2);
container.stop().animate({
scrollTop: Math.max(0, targetScroll)
}, 300, 'easeOutCubic');
}
}
// 监听页面滚动,实时更新移动端目录高亮并自动滚动
var mobileCatalogScrollTimer = null;
$(window).on("scroll.mobileCatalog", function() {
if (!window.mobileCatalogInitialized) return;
// 节流处理
if (mobileCatalogScrollTimer) return;
mobileCatalogScrollTimer = setTimeout(function() {
mobileCatalogScrollTimer = null;
// 更新高亮状态
updateMobileCatalogHighlight();
// 只在侧边栏打开且目录展开时滚动
if ($("html").hasClass("leftbar-opened") &&
$("#mobile_catalog_toggle").closest(".leftbar-mobile-collapse-section").hasClass("expanded")) {
scrollMobileCatalogToActive();
}
}, 150);
});
// 点击目录项后关闭侧边栏(已在 initMobileCatalog 中处理)
// ========== 移动端TODO交互 ==========
function updateMobileTodoCount() {
var count = $("#mobile-todo-list .mobile-todo-item:not(.todo-completed)").length;
var completedCount = $("#mobile-todo-list .mobile-todo-item.todo-completed").length;
$("#mobile_todo_count").text(count);
// 同步更新桌面端计数
$(".todo-count").text(count);
// 更新分隔栏的已完成数量
var divider = $("#mobile-todo-collapse-btn");
if (divider.length) {
divider.find(".mobile-todo-completed-count").text(completedCount);
if (completedCount > 0) {
divider.show();
} else {
divider.hide();
}
}
}
// 移动端折叠/展开已完成任务
$(document).on("click", "#mobile-todo-collapse-btn", function(e) {
e.stopPropagation();
var btn = $(this);
var completedItems = $("#mobile-todo-list .mobile-todo-item.todo-completed");
var isCollapsed = btn.hasClass("collapsed");
if (isCollapsed) {
// 展开
btn.removeClass("collapsed");
completedItems.removeClass("collapsed");
} else {
// 折叠
btn.addClass("collapsed");
completedItems.addClass("collapsed");
}
});
// 添加TODO
$(document).on("click", "#mobile-todo-add-btn", function() {
addMobileTodo();
});
$(document).on("keypress", "#mobile-todo-input", function(e) {
if (e.key === "Enter") {
addMobileTodo();
}
});
function addMobileTodo() {
if (!window.mobileTodoConfig) return;
var input = $("#mobile-todo-input");
var content = input.val().trim();
if (!content) return;
var btn = $("#mobile-todo-add-btn");
btn.prop("disabled", true);
$.ajax({
url: window.mobileTodoConfig.ajaxUrl,
type: "POST",
data: {
action: "argon_add_todo",
nonce: window.mobileTodoConfig.nonce,
content: content
},
success: function(res) {
if (res.success) {
var list = $("#mobile-todo-list");
list.find(".mobile-todo-empty").remove();
var newItem = $('<li class="mobile-todo-item" data-id="' + res.data.id + '">' +
'<span class="mobile-todo-content">' + $("<div>").text(content).html() + '</span>' +
'<button class="mobile-todo-complete-btn" title="完成"><i class="fa fa-check"></i></button>' +
'</li>');
list.prepend(newItem);
input.val("");
updateMobileTodoCount();
// 同步到桌面端
syncTodoToDesktop(res.data.id, content, "add");
}
btn.prop("disabled", false);
},
error: function() {
btn.prop("disabled", false);
}
});
}
// 移动端TODO 验证码相关变量
var mobilePendingUrgeBtn = null;
var mobileGeetestCaptchaObj = null;
// 完成/删除/催促TODO
$(document).on("click", "#mobile-todo-list .mobile-todo-complete-btn, #mobile-todo-list .mobile-todo-delete-btn, #mobile-todo-list .mobile-todo-urge-btn", function() {
if (!window.mobileTodoConfig) return;
var btn = $(this);
var item = btn.closest(".mobile-todo-item");
var id = item.data("id");
if (btn.hasClass("mobile-todo-complete-btn")) {
btn.prop("disabled", true);
$.ajax({
url: window.mobileTodoConfig.ajaxUrl,
type: "POST",
data: {
action: "argon_complete_todo",
nonce: window.mobileTodoConfig.nonce,
id: id
},
success: function(res) {
if (res.success) {
item.addClass("todo-completed");
btn.replaceWith('<button class="mobile-todo-delete-btn" title="删除"><i class="fa fa-trash"></i></button>');
updateMobileTodoCount();
syncTodoToDesktop(id, "", "complete");
} else {
btn.prop("disabled", false);
}
}
});
} else if (btn.hasClass("mobile-todo-delete-btn")) {
btn.prop("disabled", true);
$.ajax({
url: window.mobileTodoConfig.ajaxUrl,
type: "POST",
data: {
action: "argon_delete_todo",
nonce: window.mobileTodoConfig.nonce,
id: id
},
success: function(res) {
if (res.success) {
item.addClass("todo-completing");
setTimeout(function() {
item.remove();
updateMobileTodoCount();
if ($("#mobile-todo-list .mobile-todo-item").length === 0) {
$("#mobile-todo-list").html('<li class="mobile-todo-empty">暂无待办事项</li>');
}
}, 350);
syncTodoToDesktop(id, "", "delete");
}
}
});
} else if (btn.hasClass("mobile-todo-urge-btn") && !btn.hasClass("urged")) {
// 检查是否需要验证码
if (window.mobileTodoConfig.needCaptcha) {
var captchaContainer = $(".mobile-todo-captcha-container");
if (captchaContainer.length > 0) {
captchaContainer.slideDown(200);
mobilePendingUrgeBtn = btn;
if (window.mobileTodoConfig.captchaType === 'geetest') {
// 极验验证码
if (!mobileGeetestCaptchaObj && typeof initGeetest4 === 'function') {
initGeetest4({
captchaId: window.mobileTodoConfig.geetestId,
product: 'bind'
}, function(captcha) {
mobileGeetestCaptchaObj = captcha;
captcha.onReady(function() {
captcha.showCaptcha();
}).onSuccess(function() {
var result = captcha.getValidate();
if (result && mobilePendingUrgeBtn) {
var urgeId = mobilePendingUrgeBtn.closest(".mobile-todo-item").data("id");
doMobileUrgeGeetest(mobilePendingUrgeBtn, urgeId, result);
}
}).onError(function() {
captchaContainer.slideUp(200);
mobilePendingUrgeBtn = null;
});
});
} else if (mobileGeetestCaptchaObj) {
mobileGeetestCaptchaObj.showCaptcha();
}
} else {
// 数学验证码
$("#mobile-todo-captcha-input").val("").focus();
}
return;
}
}
// 不需要验证码,直接催促
doMobileUrge(btn, id, "");
}
});
// 移动端数学验证码提交
$(document).on("click", "#mobile-todo-captcha-submit", function() {
if (!mobilePendingUrgeBtn) return;
var captchaInput = $("#mobile-todo-captcha-input");
var captchaValue = captchaInput.val().trim();
if (!captchaValue) {
captchaInput.focus();
return;
}
var id = mobilePendingUrgeBtn.closest(".mobile-todo-item").data("id");
doMobileUrge(mobilePendingUrgeBtn, id, captchaValue);
});
// 移动端验证码回车提交
$(document).on("keypress", "#mobile-todo-captcha-input", function(e) {
if (e.key === "Enter") {
$("#mobile-todo-captcha-submit").click();
}
});
// 执行移动端催促
function doMobileUrge(btn, id, captcha) {
btn.prop("disabled", true).html('<i class="fa fa-spinner fa-spin"></i>');
$.ajax({
url: window.mobileTodoConfig.ajaxUrl,
type: "POST",
data: {
action: "argon_urge_todo",
nonce: window.mobileTodoConfig.nonce,
id: id,
comment_captcha: captcha
},
success: function(res) {
handleMobileUrgeResponse(btn, res);
},
error: function() {
btn.prop("disabled", false).html('<i class="fa fa-bell"></i>');
}
});
}
// 极验验证码催促
function doMobileUrgeGeetest(btn, id, geetestResult) {
btn.prop("disabled", true).html('<i class="fa fa-spinner fa-spin"></i>');
$.ajax({
url: window.mobileTodoConfig.ajaxUrl,
type: "POST",
data: {
action: "argon_urge_todo",
nonce: window.mobileTodoConfig.nonce,
id: id,
lot_number: geetestResult.lot_number,
captcha_output: geetestResult.captcha_output,
pass_token: geetestResult.pass_token,
gen_time: geetestResult.gen_time
},
success: function(res) {
handleMobileUrgeResponse(btn, res);
if (mobileGeetestCaptchaObj) mobileGeetestCaptchaObj.reset();
},
error: function() {
btn.prop("disabled", false).html('<i class="fa fa-bell"></i>');
}
});
}
// 处理移动端催促响应
function handleMobileUrgeResponse(btn, res) {
var captchaContainer = $(".mobile-todo-captcha-container");
if (res.success) {
btn.addClass("urged").html('<i class="fa fa-check"></i>');
captchaContainer.slideUp(200);
mobilePendingUrgeBtn = null;
// 更新验证码文本
if (res.data && res.data.captcha) {
$(".mobile-todo-captcha-text").text(res.data.captcha);
}
// 同步到桌面端
var id = btn.closest(".mobile-todo-item").data("id");
syncTodoToDesktop(id, "", "urge");
// 显示成功提示
if (typeof iziToast !== 'undefined') {
iziToast.success({
title: '',
message: res.data && res.data.message ? res.data.message : '已提交',
position: 'topRight',
timeout: 3000
});
}
} else {
btn.prop("disabled", false).html('<i class="fa fa-bell"></i>');
// 显示错误提示
if (typeof iziToast !== 'undefined') {
iziToast.error({
title: '',
message: res.data || '操作失败',
position: 'topRight',
timeout: 3000
});
}
// 刷新验证码
if (res.data && res.data.captcha) {
$(".mobile-todo-captcha-text").text(res.data.captcha);
}
$("#mobile-todo-captcha-input").val("").focus();
}
}
// 同步TODO操作到桌面端
function syncTodoToDesktop(id, content, action) {
var desktopList = $("#todo-list");
if (desktopList.length === 0) return;
if (action === "add") {
desktopList.find(".todo-empty").remove();
var newItem = $('<li class="todo-item" data-id="' + id + '">' +
'<span class="todo-content">' + $("<div>").text(content).html() + '</span>' +
'<button class="todo-complete-btn" title="完成"><i class="fa fa-check"></i></button>' +
'</li>');
desktopList.prepend(newItem);
} else if (action === "complete") {
var item = desktopList.find('.todo-item[data-id="' + id + '"]');
item.addClass("todo-completed");
item.find(".todo-complete-btn").replaceWith('<button class="todo-delete-btn" title="删除"><i class="fa fa-trash"></i></button>');
} else if (action === "delete") {
desktopList.find('.todo-item[data-id="' + id + '"]').remove();
} else if (action === "urge") {
var urgeBtn = desktopList.find('.todo-item[data-id="' + id + '"] .todo-urge-btn');
urgeBtn.addClass("urged").prop("disabled", true).html('<i class="fa fa-check"></i>');
}
}
}();
/*折叠区块小工具*/
$(document).on("click" , ".collapse-block .collapse-block-title" , function(){
let block = $(this).parent();
$(block).toggleClass("collapsed");
let inner = $(".collapse-block-body", block);
if (block.hasClass("collapsed")){
inner.stop(true, false).slideUp(250, 'easeOutCirc');
}else{
inner.stop(true, false).slideDown(300, 'easeOutCirc');
}
$("html").trigger("scroll");
});
/*获得 Github Repo Shortcode 信息卡内容*/
function getGithubInfoCardContent(){
$(".github-info-card").each(function(){
(function($this){
if ($this.attr("data-getdata") == "backend"){
$(".github-info-card-description" , $this).html($this.attr("data-description"));
$(".github-info-card-stars" , $this).html($this.attr("data-stars"));
$(".github-info-card-forks" , $this).html($this.attr("data-forks"));
return;
}
$(".github-info-card-description" , $this).html("Loading...");
$(".github-info-card-stars" , $this).html("-");
$(".github-info-card-forks" , $this).html("-");
author = $this.attr("data-author");
project = $this.attr("data-project");
$.ajax({
url : "https://api.github.com/repos/" + author + "/" + project,
type : "GET",
dataType : "json",
success : function(result){
description = result.description;
if (result.homepage != "" && result.homepage != null){
description += " <a href='" + result.homepage + "' target='_blank' no-pjax>" + result.homepage + "</a>"
}
$(".github-info-card-description" , $this).html(description);
$(".github-info-card-stars" , $this).html(result.stargazers_count);
$(".github-info-card-forks" , $this).html(result.forks_count);
},
error : function(xhr){
if (xhr.status == 404){
$(".github-info-card-description" , $this).html(__("找不到该 Repo"));
}else{
$(".github-info-card-description" , $this).html(__("获取 Repo 信息失败"));
}
}
});
})($(this));
});
}
getGithubInfoCardContent();
/*说说点赞*/
$(document).on("click" , ".shuoshuo-upvote" , function(){
$this = $(this);
ID = $this.attr("data-id");
$this.addClass("shuoshuo-upvoting");
$.ajax({
url : argonConfig.wp_path + "wp-admin/admin-ajax.php",
type : "POST",
dataType : "json",
data : {
action: "upvote_shuoshuo",
shuoshuo_id : ID,
},
success : function(result){
$this.removeClass("shuoshuo-upvoting");
if (result.status == "success"){
$(".shuoshuo-upvote-num" , $this).html(result.total_upvote);
$("i.fa-thumbs-o-up" , $this).addClass("fa-thumbs-up").removeClass("fa-thumbs-o-up");
$this.addClass("upvoted");
$this.addClass("shuoshuo-upvoted-animation");
iziToast.show({
title: result.msg,
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#2dce89',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-check',
timeout: 5000
});
}else{
$(".shuoshuo-upvote-num" , $this).html(result.total_upvote);
iziToast.show({
title: result.msg,
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#f5365c',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-close',
timeout: 5000
});
}
},
error : function(xhr){
$this.removeClass("shuoshuo-upvoting");
iziToast.show({
title: __("点赞失败"),
class: 'shadow-sm',
position: 'topRight',
backgroundColor: '#f5365c',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-close',
timeout: 5000
});
}
});
});
//折叠长说说
function foldLongShuoshuo(){
if (argonConfig.fold_long_shuoshuo == false){
return;
}
$("#main .shuoshuo-foldable > .shuoshuo-content").each(function(){
if ($(this).hasClass("shuoshuo-unfolded")){
return;
}
if (this.clientHeight > 400){
$(this).addClass("shuoshuo-folded");
$(this).append("<div class='show-full-shuoshuo'><button class='btn btn-outline-primary'><i class='fa fa-angle-down' aria-hidden='true'></i> " + __("展开") + "</button></div>");
}
});
}
foldLongShuoshuo();
$(document).on("click" , ".show-full-shuoshuo" , function(){
$(this).parent().removeClass("shuoshuo-folded").addClass("shuoshuo-unfolded");
});
//颜色计算
function rgb2hsl(R,G,B){
let r = R / 255;
let g = G / 255;
let b = B / 255;
let var_Min = Math.min(r, g, b);
let var_Max = Math.max(r, g, b);
let del_Max = var_Max - var_Min;
let H, S, L = (var_Max + var_Min) / 2;
if (del_Max == 0){
H = 0;
S = 0;
}else{
if (L < 0.5){
S = del_Max / (var_Max + var_Min);
}else{
S = del_Max / (2 - var_Max - var_Min);
}
del_R = (((var_Max - r) / 6) + (del_Max / 2)) / del_Max;
del_G = (((var_Max - g) / 6) + (del_Max / 2)) / del_Max;
del_B = (((var_Max - b) / 6) + (del_Max / 2)) / del_Max;
if (r == var_Max){
H = del_B - del_G;
}
else if (g == var_Max){
H = (1 / 3) + del_R - del_B;
}
else if (b == var_Max){
H = (2 / 3) + del_G - del_R;
}
if (H < 0) H += 1;
if (H > 1) H -= 1;
}
return {
'h': H,//0~1
's': S,
'l': L,
'H': Math.round(H * 360),//0~360
'S': Math.round(S * 100),//0~100
'L': Math.round(L * 100),//0~100
};
}
function Hue_2_RGB(v1,v2,vH){
if (vH < 0) vH += 1;
if (vH > 1) vH -= 1;
if ((6 * vH) < 1) return (v1 + (v2 - v1) * 6 * vH);
if ((2 * vH) < 1) return v2;
if ((3 * vH) < 2) return (v1 + (v2 - v1) * ((2 / 3) - vH) * 6);
return v1;
}
function hsl2rgb(h,s,l){
let r, g, b, var_1, var_2;
if (s == 0){
r = l;
g = l;
b = l;
}
else{
if (l < 0.5){
var_2 = l * (1 + s);
}
else{
var_2 = (l + s) - (s * l);
}
var_1 = 2 * l - var_2;
r = Hue_2_RGB(var_1, var_2, h + (1 / 3));
g = Hue_2_RGB(var_1, var_2, h);
b = Hue_2_RGB(var_1, var_2, h - (1 / 3));
}
return {
'R': Math.round(r * 255),//0~255
'G': Math.round(g * 255),
'B': Math.round(b * 255),
'r': r,//0~1
'g': g,
'b': b
};
}
function rgb2hex(r,g,b){
let hex = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
let rh, gh, bh;
rh = "", gh ="", bh="";
while (rh.length < 2){
rh = hex[r%16] + rh;
r = Math.floor(r / 16);
}
while (gh.length < 2){
gh = hex[g%16] + gh;
g = Math.floor(g / 16);
}
while (bh.length < 2){
bh = hex[b%16] + bh;
b = Math.floor(b / 16);
}
return "#" + rh + gh + bh;
}
function hex2rgb(hex){
//hex: #XXXXXX
let dec = {
'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, 'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15
};
return {
'R': (dec[hex.substr(1,1)] * 16 + dec[hex.substr(2,1)]),//0~255
'G': (dec[hex.substr(3,1)] * 16 + dec[hex.substr(4,1)]),
'B': (dec[hex.substr(5,1)] * 16 + dec[hex.substr(6,1)]),
'r': (dec[hex.substr(1,1)] * 16 + dec[hex.substr(2,1)]) / 255,//0~1
'g': (dec[hex.substr(3,1)] * 16 + dec[hex.substr(4,1)]) / 255,
'b': (dec[hex.substr(5,1)] * 16 + dec[hex.substr(6,1)]) / 255
};
}
function rgb2gray(R,G,B){
return Math.round(R * 0.299 + G * 0.587 + B * 0.114);
}
function hex2gray(hex){
let rgb_array = hex2rgb(hex);
return hex2gray(rgb_array['R'], rgb_array['G'], rgb_array['B']);
}
function rgb2str(rgb){
return rgb['R'] + "," + rgb['G'] + "," + rgb['B'];
}
function hex2str(hex){
return rgb2str(hex2rgb(hex));
}
//颜色选择器& 切换主题色
if ($("meta[name='argon-enable-custom-theme-color']").attr("content") == 'true'){
let themeColorPicker = new Pickr({
el: '#theme-color-picker',
container: 'body',
theme: 'monolith',
closeOnScroll: false,
appClass: 'theme-color-picker-box',
useAsButton: false,
padding: 8,
inline: false,
autoReposition: true,
sliders: 'h',
disabled: false,
lockOpacity: true,
outputPrecision: 0,
comparison: false,
default: $("meta[name='theme-color']").attr("content"),
swatches: ['#5e72e4', '#fa7298', '#009688', '#607d8b', '#2196f3', '#3f51b5', '#ff9700', '#109d58', '#dc4437', '#673bb7', '#212121', '#795547'],
defaultRepresentation: 'HEX',
showAlways: false,
closeWithKey: 'Escape',
position: 'top-start',
adjustableNumbers: false,
components: {
palette: true,
preview: true,
opacity: false,
hue: true,
interaction: {
hex: true,
rgba: true,
hsla: false,
hsva: false,
cmyk: false,
input: true,
clear: false,
cancel: true,
save: true
}
},
strings: {
save: __('确定'),
clear: __('清除'),
cancel: __('恢复博客默认')
}
});
themeColorPicker.on('change', instance => {
updateThemeColor(pickrObjectToHEX(instance), true);
})
themeColorPicker.on('save', (color, instance) => {
updateThemeColor(pickrObjectToHEX(instance._color), true);
themeColorPicker.hide();
})
themeColorPicker.on('cancel', instance => {
themeColorPicker.hide();
themeColorPicker.setColor($("meta[name='theme-color-origin']").attr("content").toUpperCase());
updateThemeColor($("meta[name='theme-color-origin']").attr("content").toUpperCase(), false);
setCookie("argon_custom_theme_color", "", 0);
});
}
function pickrObjectToHEX(color){
let HEXA = color.toHEXA();
return ("#" + HEXA[0] + HEXA[1] + HEXA[2]).toUpperCase();
}
function updateThemeColor(color, setcookie){
let themecolor = color;
let themecolor_rgbstr = hex2str(themecolor);
let RGB = hex2rgb(themecolor);
let HSL = rgb2hsl(RGB['R'], RGB['G'], RGB['B']);
document.documentElement.style.setProperty('--themecolor', themecolor);
document.documentElement.style.setProperty('--themecolor-R', RGB['R']);
document.documentElement.style.setProperty('--themecolor-G', RGB['G']);
document.documentElement.style.setProperty('--themecolor-B', RGB['B']);
document.documentElement.style.setProperty('--themecolor-H', HSL['H']);
document.documentElement.style.setProperty('--themecolor-S', HSL['S']);
document.documentElement.style.setProperty('--themecolor-L', HSL['L']);
if (rgb2gray(RGB['R'], RGB['G'], RGB['B']) < 50){
$("html").addClass("themecolor-toodark");
}else{
$("html").removeClass("themecolor-toodark");
}
$("meta[name='theme-color']").attr("content", themecolor);
$("meta[name='theme-color-rgb']").attr("content", themecolor_rgbstr);
if (setcookie){
setCookie("argon_custom_theme_color", themecolor, 365);
}
}
/*打字效果*/
function typeEffect($element, text, now, interval){
if (now > text.length){
setTimeout(function(){
$element.removeClass("typing-effect");
}, 1000);
return;
}
$element[0].innerText = text.substring(0, now);
setTimeout(function(){typeEffect($element, text, now + 1, interval)}, interval);
}
function startTypeEffect($element, text, interval){
$element.addClass("typing-effect");
$element.attr("style", "--animation-cnt: " + Math.ceil(text.length * interval / 1000));
typeEffect($element, text, 1, interval);
}
!function(){
if ($(".banner-title").data("interval") != undefined){
let interval = $(".banner-title").data("interval");
let $title = $(".banner-title-inner");
let $subTitle = $(".banner-subtitle");
startTypeEffect($title, $title.data("text"), interval);
if (!$subTitle.length){
return;
}
setTimeout(function(){startTypeEffect($subTitle, $subTitle.data("text"), interval);}, Math.ceil($title.data("text").length * interval / 1000) * 1000);
}
}();
/*一言*/
if ($(".hitokoto").length > 0){
$.ajax({
type: 'GET',
url: "https://v1.hitokoto.cn",
success: function(result){
$(".hitokoto").text(result.hitokoto);
},
error: function(result){
$(".hitokoto").text(__("Hitokoto 获取失败"));
}
});
}
/*Highlight.js*/
function randomString(len) {
len = len || 32;
let chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let res = "";
for (let i = 0; i < len; i++) {
res += chars.charAt(Math.floor(Math.random() * chars.length));
}
res[0] = chars.charAt(Math.floor(Math.random() * (chars.length - 10)));
return res;
}
var codeOfBlocks = {};
function getCodeFromBlock(block){
if (codeOfBlocks[block.id] != undefined){
return codeOfBlocks[block.id];
}
let lines = $(".hljs-ln-code", block);
let res = "";
for (let i = 0; i < lines.length - 1; i++){
res += lines[i].innerText;
res += "\n";
}
res += lines[lines.length - 1].innerText;
codeOfBlocks[block.id] = res;
return res;
}
function highlightJsRender(){
if (typeof(hljs) == "undefined"){
return;
}
if (typeof(argonConfig.code_highlight.enable) == "undefined"){
return;
}
if (!argonConfig.code_highlight.enable){
return;
}
$("article pre.code").each(function(index, block) {
if ($(block).hasClass("no-hljs")){
return;
}
$(block).html("<code>" + $(block).html() + "</code>");
});
$("article pre > code").each(function(index, block) {
if ($(block).hasClass("no-hljs")){
return;
}
$(block).parent().attr("id", randomString());
hljs.highlightBlock(block);
hljs.lineNumbersBlock(block, {singleLine: true});
$(block).parent().addClass("hljs-codeblock");
if (argonConfig.code_highlight.hide_linenumber){
$(block).parent().addClass("hljs-hide-linenumber");
}
if (argonConfig.code_highlight.break_line){
$(block).parent().addClass("hljs-break-line");
}
if (argonConfig.code_highlight.transparent_linenumber){
$(block).parent().addClass("hljs-transparent-linenumber");
}
$(block).attr("hljs-codeblock-inner", "");
let copyBtnID = "copy_btn_" + randomString();
$(block).parent().append(`<div class="hljs-control hljs hljs-title">
<div class="hljs-control-btn hljs-control-toggle-linenumber" tooltip-hide-linenumber="` + __("隐藏行号") + `" tooltip-show-linenumber="` + __("显示行号") + `">
<i class="fa fa-list"></i>
</div>
<div class="hljs-control-btn hljs-control-toggle-break-line" tooltip-enable-breakline="` + __("开启折行") + `" tooltip-disable-breakline="` + __("关闭折行") + `">
<i class="fa fa-align-left"></i>
</div>
<div class="hljs-control-btn hljs-control-copy" id=` + copyBtnID + ` tooltip="` + __("复制") + `">
<i class="fa fa-clipboard"></i>
</div>
<div class="hljs-control-btn hljs-control-fullscreen" tooltip-fullscreen="` + __("全屏") + `" tooltip-exit-fullscreen="` + __("退出全屏") + `">
<i class="fa fa-arrows-alt"></i>
</div>
</div>`);
let clipboard = new ClipboardJS("#" + copyBtnID, {
text: function(trigger) {
return getCodeFromBlock($(block).parent()[0]);
}
});
clipboard.on('success', function(e) {
iziToast.show({
title: __("复制成功"),
message: __("代码已复制到剪贴板"),
class: 'shadow',
position: 'topRight',
backgroundColor: '#2dce89',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-check',
timeout: 5000
});
});
clipboard.on('error', function(e) {
iziToast.show({
title: __("复制失败"),
message: __("请手动复制代码"),
class: 'shadow',
position: 'topRight',
backgroundColor: '#f5365c',
titleColor: '#ffffff',
messageColor: '#ffffff',
iconColor: '#ffffff',
progressBarColor: '#ffffff',
icon: 'fa fa-close',
timeout: 5000
});
});
});
}
$(document).ready(function(){
// ==========================================================================
// 初始化性能优化模块
// ==========================================================================
if (typeof initArgonPerformance === 'function') {
// 调用性能优化模块的初始化函数
initArgonPerformance();
// 创建各个优化模块的实例
try {
// 1. 性能监控模块(最先初始化,用于监控其他模块)
if (typeof ArgonPerformanceMonitor !== 'undefined') {
argonPerformanceMonitor = new ArgonPerformanceMonitor();
ArgonDebug.info('✓ 性能监控模块已初始化');
}
// 2. DOM 缓存模块
if (typeof ArgonDOMCache !== 'undefined') {
argonDOMCache = new ArgonDOMCache();
// 设置性能监控器引用
if (argonPerformanceMonitor) {
argonDOMCache.setPerformanceMonitor(argonPerformanceMonitor);
}
// 初始化缓存
argonDOMCache.init();
ArgonDebug.info('✓ DOM 缓存模块已初始化');
}
// 3. 事件管理模块
if (typeof ArgonEventManager !== 'undefined') {
argonEventManager = new ArgonEventManager();
ArgonDebug.info('✓ 事件管理模块已初始化');
}
// 4. 资源加载模块
if (typeof ArgonResourceLoader !== 'undefined') {
argonResourceLoader = new ArgonResourceLoader();
ArgonDebug.info('✓ 资源加载模块已初始化');
}
// 5. 渲染优化模块
if (typeof ArgonRenderOptimizer !== 'undefined') {
argonRenderOptimizer = new ArgonRenderOptimizer();
ArgonDebug.info('✓ 渲染优化模块已初始化');
}
// 6. 内存管理模块
if (typeof ArgonMemoryManager !== 'undefined') {
argonMemoryManager = new ArgonMemoryManager();
ArgonDebug.info('✓ 内存管理模块已初始化');
}
ArgonDebug.info('🚀 Argon 性能优化模块全部初始化完成');
} catch (error) {
ArgonDebug.error('性能优化模块初始化失败:', error);
}
} else {
ArgonDebug.warn('性能优化模块未加载,请确保 argon-performance.js 已正确引入');
}
// ==========================================================================
// 原有初始化代码
// ==========================================================================
highlightJsRender();
waterflowInit();
});
$(document).on("click" , ".hljs-control-fullscreen" , function(){
let block = $(this).parent().parent();
block.toggleClass("hljs-codeblock-fullscreen");
if (block.hasClass("hljs-codeblock-fullscreen")){
$("html").addClass("noscroll codeblock-fullscreen");
}else{
$("html").removeClass("noscroll codeblock-fullscreen");
}
});
$(document).on("click" , ".hljs-control-toggle-break-line" , function(){
let block = $(this).parent().parent();
block.toggleClass("hljs-break-line");
});
$(document).on("click" , ".hljs-control-toggle-linenumber" , function(){
let block = $(this).parent().parent();
block.toggleClass("hljs-hide-linenumber");
});
/*时间差计算/
function addPreZero(num, n) {
var len = num.toString().length;
while(len < n) {
num = "0" + num;
len++;
}
return num;
}
function humanTimeDiff(time){
let now = new Date();
time = new Date(time);
let delta = now - time;
if (delta < 0){
delta = 0;
}
if (delta < 1000 * 60){
return __("刚刚");
}
if (delta < 1000 * 60 * 60){
return parseInt(delta / (1000 * 60)) + " " + __("分钟前);
}
if (delta < 1000 * 60 * 60 * 24){
return parseInt(delta / (1000 * 60 * 60)) + " " + __("小时前);
}
let yesterday = new Date(now - 1000 * 60 * 60 * 24);
yesterday.setHours(0);
yesterday.setMinutes(0);
yesterday.setSeconds(0);
yesterday.setMilliseconds(0);
if (time > yesterday){
return __("昨天") + " " + time.getHours() + ":" + addPreZero(time.getMinutes(), 2);
}
let theDayBeforeYesterday = new Date(now - 1000 * 60 * 60 * 24 * 2);
theDayBeforeYesterday.setHours(0);
theDayBeforeYesterday.setMinutes(0);
theDayBeforeYesterday.setSeconds(0);
theDayBeforeYesterday.setMilliseconds(0);
if (time > theDayBeforeYesterday && argonConfig.language.indexOf("zh") == 0){
return __("前天") + " " + time.getHours() + ":" + addPreZero(time.getMinutes(), 2);
}
if (delta < 1000 * 60 * 60 * 24 * 30){
return parseInt(delta / (1000 * 60 * 60 * 24)) + " " + __("天前");
}
let theFirstDayOfThisYear = new Date(now);
theFirstDayOfThisYear.setMonth(0);
theFirstDayOfThisYear.setDate(1);
theFirstDayOfThisYear.setHours(0);
theFirstDayOfThisYear.setMinutes(0);
theFirstDayOfThisYear.setSeconds(0);
theFirstDayOfThisYear.setMilliseconds(0);
if (time > theFirstDayOfThisYear){
if (argonConfig.dateFormat == "YMD" || argonConfig.dateFormat == "MDY"){
return (time.getMonth() + 1) + "-" + time.getDate();
}else{
return time.getDate() + "-" + (time.getMonth() + 1);
}
}
if (argonConfig.dateFormat == "YMD"){
return time.getFullYear() + "-" + (time.getMonth() + 1) + "-" + time.getDate();
}else if (argonConfig.dateFormat == "MDY"){
return time.getDate() + "-" + (time.getMonth() + 1) + "-" + time.getFullYear();
}else if (argonConfig.dateFormat == "DMY"){
return time.getDate() + "-" + (time.getMonth() + 1) + "-" + time.getFullYear();
}
}
function calcHumanTimesOnPage(){
$(".human-time").each(function(){
$(this).text(humanTimeDiff(parseInt($(this).data("time")) * 1000));
});
}
calcHumanTimesOnPage();
setInterval(function(){
calcHumanTimesOnPage()
}, 15000);
/*Console*/
!function(){
void 0;
}();
/* ========== Modern UI Enhancements - 现代化交互动画增强========== */
(function() {
'use strict';
// 1. 图片加载动画
function initImageLoadAnimation() {
var images = document.querySelectorAll('article img[loading="lazy"], .post-thumbnail img');
images.forEach(function(img) {
if (img.dataset.loadAnimInit) return;
img.dataset.loadAnimInit = 'true';
if (img.complete) { img.classList.add('loaded'); }
else { img.addEventListener('load', function() { this.classList.add('loaded'); }); }
});
}
// 3. 滚动入场动画
function initScrollAnimations() {
if (!('IntersectionObserver' in window)) return;
var animatedElements = document.querySelectorAll('.article-list article.post, .comment-item, .timeline-item, .friend-link-item, #leftbar .card, #rightbar .card');
var observer = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) { entry.target.classList.add('animate-in'); observer.unobserve(entry.target); }
});
}, { threshold: 0.1, rootMargin: '0px 0px -50px 0px' });
animatedElements.forEach(function(el) { if (!el.classList.contains('animate-in')) observer.observe(el); });
}
// 4. 平滑滚动
function initSmoothScroll() {
document.querySelectorAll('a[href^="#"]').forEach(function(anchor) {
if (anchor.dataset.smoothScrollInit) return;
anchor.dataset.smoothScrollInit = 'true';
anchor.addEventListener('click', function(e) {
var targetId = this.getAttribute('href');
if (targetId === '#') return;
var target = document.querySelector(targetId);
if (target) { e.preventDefault(); target.scrollIntoView({ behavior: 'smooth', block: 'start' }); }
});
});
}
// 5. 页面加载进度条
function initLoadingBar() {
if (document.getElementById('page-loading-bar')) return;
var bar = document.createElement('div');
bar.id = 'page-loading-bar';
bar.style.width = '0%';
document.body.appendChild(bar);
var progress = 0;
var interval = setInterval(function() {
progress += Math.random() * 10;
if (progress >= 90) { clearInterval(interval); progress = 90; }
bar.style.width = progress + '%';
}, 100);
var overlay = document.getElementById('article-loading-overlay');
if (!overlay) {
overlay = document.createElement('div');
overlay.id = 'article-loading-overlay';
var inner = document.createElement('div');
inner.className = 'overlay-content';
inner.innerHTML = '<div class="overlay-title"></div><div class="overlay-thumb"></div><div class="overlay-row" style="width:85%"></div><div class="overlay-row" style="width:70%"></div><div class="overlay-row" style="width:90%"></div><div class="overlay-grid"><div class="overlay-grid-item"></div><div class="overlay-grid-item"></div></div><div class="center-spinner"><div class="loading-spinner"></div><div class="overlay-row" style="width:120px;height:14px;margin:0"></div></div>';
overlay.appendChild(inner);
document.body.appendChild(overlay);
}
overlay.classList.remove('is-hiding');
requestAnimationFrame(function() {
overlay.classList.add('is-visible');
});
window.addEventListener('load', function() {
clearInterval(interval);
bar.style.width = '100%';
setTimeout(function() { bar.style.opacity = '0'; setTimeout(function() { bar.remove(); }, 300); }, 200);
if (overlay) {
overlay.classList.remove('is-visible');
overlay.classList.add('is-hiding');
setTimeout(function() { if (overlay && overlay.parentNode) overlay.parentNode.removeChild(overlay); }, 360);
}
});
}
// 6. PJAX 加载动画
function initPjaxAnimations() {
if (typeof jQuery === 'undefined') return;
jQuery(document).on('pjax:start', function() {
jQuery('#primary').addClass('pjax-loading');
var bar = document.getElementById('page-loading-bar');
if (!bar) { bar = document.createElement('div'); bar.id = 'page-loading-bar'; document.body.appendChild(bar); }
bar.style.opacity = '1'; bar.style.width = '30%';
setTimeout(function() { bar.style.width = '60%'; }, 200);
var overlay = document.getElementById('article-loading-overlay');
if (!overlay) {
overlay = document.createElement('div');
overlay.id = 'article-loading-overlay';
var inner = document.createElement('div');
inner.className = 'overlay-content';
inner.innerHTML = '<div class="overlay-title"></div><div class="overlay-thumb"></div><div class="overlay-row" style="width:85%"></div><div class="overlay-row" style="width:70%"></div><div class="overlay-row" style="width:90%"></div><div class="overlay-grid"><div class="overlay-grid-item"></div><div class="overlay-grid-item"></div></div><div class="center-spinner"><div class="loading-spinner"></div><div class="overlay-row" style="width:120px;height:14px;margin:0"></div></div>';
overlay.appendChild(inner);
document.body.appendChild(overlay);
}
overlay.classList.remove('is-hiding');
requestAnimationFrame(function() {
overlay.classList.add('is-visible');
});
});
jQuery(document).on('pjax:end', function() {
jQuery('#primary').removeClass('pjax-loading');
var bar = document.getElementById('page-loading-bar');
if (bar) { bar.style.width = '100%'; setTimeout(function() { bar.style.opacity = '0'; setTimeout(function() { bar.remove(); }, 300); }, 200); }
setTimeout(function() { initImageLoadAnimation(); initScrollAnimations(); initSmoothScroll(); }, 100);
var overlay = document.getElementById('article-loading-overlay');
if (overlay) {
overlay.classList.remove('is-visible');
overlay.classList.add('is-hiding');
setTimeout(function() { if (overlay && overlay.parentNode) overlay.parentNode.removeChild(overlay); }, 360);
}
});
}
// 7. 主题切换动画 - 已在 header.php 中通过 setDarkmode 函数处理,此处不再重复
function initThemeTransition() {
// 移除 MutationObserver 避免无限循环导致内存泄漏
// 主题切换过渡效果已在 setDarkmode() 函数中实现
}
// 8. 减少动画偏好检查
function checkReducedMotion() {
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
document.documentElement.classList.add('reduced-motion');
}
}
// 初始化
function init() {
checkReducedMotion();
initImageLoadAnimation();
initScrollAnimations();
initSmoothScroll();
initPjaxAnimations();
initThemeTransition();
}
if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); }
else { init(); }
if (document.readyState !== 'complete') { initLoadingBar(); }
})();
/* ========== End of Modern UI Enhancements ========== */
// ========== jQuery Easing 备用(确保在所有脚本加载后仍可用)==========
(function() {
if (typeof jQuery === 'undefined') return;
var $ = jQuery;
if (!$.easing) $.easing = {};
if (!$.easing.easeOutCirc) {
$.easing.easeOutCirc = function(x) {
return Math.sqrt(1 - Math.pow(x - 1, 2));
};
}
if (!$.easing.easeOutExpo) {
$.easing.easeOutExpo = function(x) {
return x === 1 ? 1 : 1 - Math.pow(2, -10 * x);
};
}
})();