From c952620fd607f56096760604b9b885379bbc5e99 Mon Sep 17 00:00:00 2001 From: zqlit Date: Sat, 3 Oct 2026 17:20:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=8B=E9=93=BE=E5=8D=A1=E7=89=87=E5=9B=BA?= =?UTF-8?q?=E5=AE=9A=E5=9C=A8=E8=AF=84=E8=AE=BA=E5=88=97=E8=A1=A8=E4=B8=8A?= =?UTF-8?q?=E6=96=B9(=E4=B8=8D=E5=86=8D=E8=A2=AB=E6=96=B0=E8=AF=84?= =?UTF-8?q?=E8=AE=BA=E6=8C=A4=E5=88=B0=E4=B8=AD=E9=97=B4)=EF=BC=9A?= =?UTF-8?q?=E6=95=B4=E6=9D=A1=E8=AF=84=E8=AE=BA=E7=94=A8class=E9=9A=90?= =?UTF-8?q?=E8=97=8F=EF=BC=8C=E5=8D=A1=E7=89=87=E6=8F=92=E5=85=A5atk-list-?= =?UTF-8?q?body=E9=A6=96=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- themes/Ying/assets/js/modules/artalk.js | 26 +++++++++++++++++++----- themes/Ying/layouts/partials/artalk.html | 14 ++++++------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/themes/Ying/assets/js/modules/artalk.js b/themes/Ying/assets/js/modules/artalk.js index 5f975d3c..9a81cda6 100644 --- a/themes/Ying/assets/js/modules/artalk.js +++ b/themes/Ying/assets/js/modules/artalk.js @@ -723,10 +723,14 @@ artalk.on('comment-rendered', function(node) { var content = String(d2.content || '').trim().replace(/\/+$/, '').toLowerCase(); if (content !== 'https://usj.cc/link-apply') return; - // 幂等 + 自愈:class 每次渲染都补一次(隐藏原评论内容的 CSS 规则依赖它), - // 已有卡片就直接返回,避免 Artalk 重渲染时出现第二张卡片 + // 幂等 + 自愈:class 每次渲染都补一次(CSS 靠它隐藏整条评论), + // 卡片始终挂在评论列表"上方"(.atk-list-body 的第一个子节点), + // 这样发新评论/切换排序都不会把卡片夹到评论中间。 el2.classList.add('atk-fl-apply'); - if (el2.querySelector('.atk-fl-card')) return; + var listBody = document.querySelector('.atk-list-body') || document.querySelector('.atk-list'); + var oldHolder = document.querySelector('.atk-fl-card-wrap'); + if (oldHolder && listBody && oldHolder.parentNode === listBody && oldHolder.isConnected) return; + if (oldHolder && oldHolder.parentNode) oldHolder.parentNode.removeChild(oldHolder); el2.style.cursor = 'pointer'; el2.title = '点击申请友链'; @@ -785,9 +789,21 @@ artalk.on('comment-rendered', function(node) { var nickRow = card.querySelector('span > span'); nickRow.appendChild(bw); } - // 卡片直接挂在评论节点(.atk-comment)下:宽度与评论输入框一致 + // 卡片包一层容器挂到列表上方(宽度与评论区一致,且不受列表排序/新增影响) if (contentEl) contentEl.innerHTML = ''; - commentEl.appendChild(card); + var holder = document.createElement('div'); + holder.className = 'atk-fl-card-wrap'; + holder.appendChild(card); + if (listBody) { + if (listBody.firstChild) listBody.insertBefore(holder, listBody.firstChild); + else listBody.appendChild(holder); + } else { + commentEl.appendChild(holder); + } + // 点击卡片即打开申请弹窗(原来挂在 el2 上,现在卡片已移出评论节点) + holder.addEventListener('click', function () { + if (window.flApplyOpenModal) window.flApplyOpenModal(); + }); // ── 打字机效果(PJAX 安全:卡片被移除/替换时定时器自动停止) ── // 注意:不要用 prefers-reduced-motion 跳过打字 —— Windows 关闭"动画效果" diff --git a/themes/Ying/layouts/partials/artalk.html b/themes/Ying/layouts/partials/artalk.html index 7fb103f8..76e37317 100644 --- a/themes/Ying/layouts/partials/artalk.html +++ b/themes/Ying/layouts/partials/artalk.html @@ -100,15 +100,15 @@ PJAX 下每次切页评论区都会重建卡片 → 入场动画与打字机自然重播; 打字机定时器在 artalk.js 里会检测卡片是否还在文档中(切页后自动停)。 */ - /* 卡片评论:常规内容(头像/昵称/正文/页脚)整体隐藏。 - 必须用 class + !important,不能用 JS 内联 display:none —— - Artalk 发完新评论会重渲染 .atk-main,内联样式会被抹掉, - 原评论正文(那条 URL)就会重新冒出来把卡片挤下去(刷新才恢复)。 */ - .atk-comment-wrap.atk-fl-apply > .atk-main, - .atk-comment-wrap.atk-fl-apply > .atk-comment > .atk-main, - .atk-comment.atk-fl-apply > .atk-main { + /* 被转换成卡片的评论:整条从列表里隐藏(卡片已移到列表上方单独显示, + 用 class + !important 声明式隐藏,Artalk 重渲染也压得住) */ + .atk-comment-wrap.atk-fl-apply { display: none !important; } + /* 卡片容器:固定在评论列表最上方 */ + .atk-fl-card-wrap { + margin: 0 0 6px; + } .atk-fl-card { animation: flApplyIn .5s cubic-bezier(.22, 1, .36, 1) both; }