重构课外书;更新侧边栏;修复模态框、分享海报异常

This commit is contained in:
anian
2026-05-06 21:08:35 +08:00
parent 73dc2a1c1c
commit 061b00fc05
16 changed files with 1124 additions and 274 deletions
+73 -25
View File
@@ -27,7 +27,13 @@ const poster = (function() {
* @param {object} config - 配置对象
*/
function init(config) {
const $container = document.querySelector(config.selector)
const $container = config.container || document.querySelector(config.selector)
if (!$container) {
if (config.callback) {
config.callback(null)
}
return
}
// ------------------ 【修复点 2:清理容器,避免PJAX残余】 ------------------
// 在重新绘制前,确保清空容器,移除旧的 img 和 wrapper
$container.innerHTML = '';
@@ -121,7 +127,7 @@ const poster = (function() {
// 3. 绘制覆盖层
ctx.fillStyle="rgba(0, 0, 0, 0.3)";
ctx.fillRect(20, 20, $canvas.width - 40, $canvas.height / 1.2 - 40);        
ctx.fillRect(20, 20, $canvas.width - 40, $canvas.height / 1.2 - 40);
// 4. 绘制时间 (使用预先绘制好的 Canvas)
ctx.drawImage($day, -20, 50)
@@ -157,7 +163,7 @@ const poster = (function() {
// 移除旧的 wrapper 并添加最终海报图
$container.appendChild(img);
// 必须先移除再调用 callback,以确保 DOM 结构干净
$container.removeChild($wrapper)
$container.removeChild($wrapper)
if (config.callback) {
config.callback($container)
@@ -165,7 +171,9 @@ const poster = (function() {
}).catch(error => {
console.error('海报图片加载失败:', error);
// 可在此处添加错误处理,例如显示一个错误信息
$container.removeChild($wrapper);
if ($wrapper.parentNode === $container) {
$container.removeChild($wrapper);
}
if (config.callback) {
// 即使失败也调用回调,传入 null 或错误信息,以便上层逻辑处理
config.callback(null);
@@ -356,10 +364,26 @@ const poster = (function() {
// ajax生成文章海报
// 此处调用部分需要确保在 PJAX 环境下,该事件监听器能够重新绑定(如果使用传统的 document.ready,在 PJAX 中需要改为监听 pjax:success 等事件)
$('body').on('click', '.cr_poster', function () {
let closeLoading = null;
closeLoading = cocoMessage.loading('海报生成中...');
var $trigger = $(this);
var post_id = $(this).attr('poster-data');
var banner = $(this).attr('banner');
var single_content = $('.single-content');
var t_content = $('#post-'+post_id+' .t_content');
var modal = '#share_modal_' + post_id;
var $modalList = $(modal);
var $modal = $trigger.closest(modal);
if ($modal.length === 0) {
$modal = $(modal + ':visible').first();
}
if ($modal.length === 0) {
$modal = $modalList.first();
}
if ($modal.length === 0) {
return;
}
// 确保 content 区域存在
var content_element = single_content.length > 0 ? single_content[0] : (t_content.length > 0 ? t_content[0] : null);
@@ -392,43 +416,45 @@ $('body').on('click', '.cr_poster', function () {
new QRious({ element: twoCodeCanvas, value: permalink, size: 260, });
var poster_box_selector = '#share_modal_' + post_id + ' .poster_box';
var $posterBoxAp = $modal.find('.poster_box_ap').first();
if ($posterBoxAp.length === 0) {
return;
}
// ------------------ 【修复点 2:清理容器】 ------------------
// 先移除旧的 poster_box
$('.poster_box').remove();
// 仅在当前弹窗作用域内移除旧容器,避免影响 PJAX 残留节点
$posterBoxAp.find('.poster_box').remove();
// 重新创建并插入新的 poster_box
$('#share_modal_' + post_id + ' .poster_box_ap').append('<div class="poster_box"></div>');
var $posterBox = $('<div class="poster_box"></div>');
$posterBoxAp.append($posterBox);
// -----------------------------------------------------------------------
if (content_length > 120) {
content = content.substring(0, 80) + '...'
}
// Posterdown 函数中不再需要移除 loading_box,因为 init 会清空容器
// 海报生成回调
function Posterdown(e) {
var modal = '#share_modal_' + post_id;
// 检查海报是否成功生成
if (e && $(modal + ' .poster_box img').length > 0) {
var url = $(modal + ' .poster_box img').attr('src');
$(modal + ' .post_share_box').removeClass('hide');
$(modal + ' .poster_download').attr('href', url).attr('download', 'poster_' + post_id + '.png');
if (e && $posterBox.find('img').length > 0) {
closeLoading?.()
cocoMessage.success("海报生成成功!") // 图片加载完成后才触发
var url = $posterBox.find('img').attr('src');
var $shareBox = $modal.find('.post_share_box');
$shareBox.removeClass('hide');
$modal.find('.poster_download').attr('href', url).attr('download', 'poster_' + post_id + '.png');
} else {
// 错误处理,如果海报生成失败
cocoMessage.error("海报生成失败,请检查图片链接!");
closeLoading?. ();
cocoMessage.error("海报生成失败,请重试!")
}
}
// 移除 loading box 的时机提前,或者在 init 开始前完成
// $('.loading_box').remove(); // 原始代码中这行在创建 loading_box 之后,但其作用是移除**所有** .loading_box,可能存在问题
// 重新添加 loading 状态,并在 init 中等待
$(poster_box_selector).append('<div class="loading_box"><div uk-spinner></div></div>');
poster.init({
banner: banner,
selector: poster_box_selector, // 传入完整的选择器
selector: modal + ' .poster_box',
container: $posterBox[0],
title: title,
content: content,
logo: Theme.site_logo,
@@ -436,9 +462,31 @@ $('body').on('click', '.cr_poster', function () {
description: Theme.admin_des,
callback: Posterdown
});
});
$(document).on('pjax:success', function (event) {
// 清理 PJAX 残留的 modal:只删除那些在当前页面没有对应按钮的 modal
var allModals = $('[id^="share_modal_"]');
var currentPostIds = {};
// 移除 loading 动画
$(poster_box_selector + ' .loading_box').remove();
// 收集当前页面所有的 post_id
$('.cr_poster').each(function() {
var pid = $(this).attr('poster-data');
if (pid) {
currentPostIds[pid] = true;
}
});
// 只删除残留的 modal(不在当前页面按钮列表中的)
allModals.each(function() {
var $m = $(this);
var modalId = $m.attr('id');
var postId = modalId ? modalId.replace('share_modal_', '') : null;
if (postId && !currentPostIds[postId]) {
$m.remove();
}
});
});