From 5d5daaa3b77c2fcf216d6b38f5d8a687d965bf89 Mon Sep 17 00:00:00 2001 From: Vaica <94612053+zqlit@users.noreply.github.com> Date: Thu, 29 Jan 2026 21:19:49 +0800 Subject: [PATCH] =?UTF-8?q?fixed=20=E5=BC=B9=E5=B9=95=E5=8D=A1=E9=A1=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- themes/Ying/assets/css/main.css | 7 +++ themes/Ying/assets/js/barrage.js | 94 +++++++++++++++++++++----------- 2 files changed, 68 insertions(+), 33 deletions(-) diff --git a/themes/Ying/assets/css/main.css b/themes/Ying/assets/css/main.css index 0d41ab1d..e180e354 100644 --- a/themes/Ying/assets/css/main.css +++ b/themes/Ying/assets/css/main.css @@ -2224,6 +2224,10 @@ input[type=submit] { pointer-events: none; /* 容器不阻挡点击 */ z-index: 1; /* 在 main (z-index: 10) 背后,但在 body 背景之上 */ overflow: hidden; + /* 性能优化:CSS 隔离 */ + contain: layout style paint; + /* 某些浏览器可能支持 content-visibility */ + content-visibility: auto; } /* 弹幕条目 (左到右) */ @@ -2241,6 +2245,9 @@ input[type=submit] { opacity: 0.9; /* 缩小整体尺寸 */ transform-origin: left top; + /* 硬件加速 */ + backface-visibility: hidden; + -webkit-font-smoothing: antialiased; } /* 头像样式 */ diff --git a/themes/Ying/assets/js/barrage.js b/themes/Ying/assets/js/barrage.js index f7d789b3..21dfa96a 100644 --- a/themes/Ying/assets/js/barrage.js +++ b/themes/Ying/assets/js/barrage.js @@ -135,6 +135,54 @@ // 追踪当前屏幕上显示的弹幕 ID this.activeIds = new Set(); + // 最大同屏数量限制,防止卡顿 + this.maxActiveItems = 30; + + // 绑定事件委托 + this.initEventDelegation(); + } + + initEventDelegation() { + // 鼠标进入容器暂停 + this.container.addEventListener('mouseover', (e) => { + const item = e.target.closest('.barrage-item'); + if (item) { + item.style.animationPlayState = 'paused'; + item.style.zIndex = '9999'; + } + }); + + // 鼠标离开恢复 + this.container.addEventListener('mouseout', (e) => { + const item = e.target.closest('.barrage-item'); + if (item) { + item.style.animationPlayState = 'running'; + item.style.zIndex = ''; + } + }); + + // 点击事件 + this.container.addEventListener('click', (e) => { + const item = e.target.closest('.barrage-item'); + if (item) { + const url = item.dataset.url; + if (url && url !== '#') { + e.stopPropagation(); + e.preventDefault(); + + const targetId = url.split('#')[1]; + const targetEl = document.getElementById(targetId); + + if (targetEl) { + targetEl.scrollIntoView({ behavior: 'smooth', block: 'center' }); + targetEl.classList.add('atk-flash'); + setTimeout(() => targetEl.classList.remove('atk-flash'), 2000); + } else { + window.location.href = url; + } + } + } + }); } start(data = []) { @@ -180,6 +228,7 @@ this.isDestroyed = true; this.stop(); this.clearDOM(); + // 移除事件监听需要保存引用,这里因为容器可能被销毁,且是单例,暂不处理复杂的解绑 } loop() { @@ -187,15 +236,15 @@ // 容器检测 if (!document.body.contains(this.container)) { - // 尝试重新获取容器 (可能被 PJAX 替换但 ID 没变?) - // 这里简单处理:如果失效则停止 - // console.warn('[Barrage] 容器失效,停止'); this.destroy(); return; } if (!this.isPaused && this.data.length > 0) { - this.tryShoot(); + // 只有当前屏幕数量未满时才发射 + if (this.activeIds.size < this.maxActiveItems) { + this.tryShoot(); + } } // 随机间隔 2s - 4s @@ -226,33 +275,20 @@ const item = document.createElement('div'); item.className = 'barrage-item'; + // 存储 URL 到 dataset 以供事件委托使用 + if (url && url !== '#') { + item.dataset.url = url; + item.style.cursor = 'pointer'; + } let html = ''; + // 优化:只有当有头像时才渲染 img 标签 if (avatar) { - html += ``; + html += ``; } html += `
${text}
`; item.innerHTML = html; - if (url && url !== '#') { - item.style.cursor = 'pointer'; - item.addEventListener('click', (e) => { - e.stopPropagation(); - e.preventDefault(); - - const targetId = url.split('#')[1]; - const targetEl = document.getElementById(targetId); - - if (targetEl) { - targetEl.scrollIntoView({ behavior: 'smooth', block: 'center' }); - targetEl.classList.add('atk-flash'); - setTimeout(() => targetEl.classList.remove('atk-flash'), 2000); - } else { - window.location.href = url; - } - }); - } - // 样式与动画 const tracks = 10; const trackIndex = Math.floor(Math.random() * tracks); @@ -263,15 +299,7 @@ const duration = 18 + Math.random() * 7; item.style.animation = `barrage-slide-right ${duration}s linear forwards`; - item.addEventListener('mouseenter', () => { - item.style.animationPlayState = 'paused'; - item.style.zIndex = '9999'; - }); - item.addEventListener('mouseleave', () => { - item.style.animationPlayState = 'running'; - item.style.zIndex = ''; - }); - + // 仅绑定必要的生命周期事件 item.addEventListener('animationend', () => { item.remove(); this.activeIds.delete(id);