fixed 弹幕修复
This commit is contained in:
1 parent
eddfac9a7b
commit
dd642782b4
8 files changed
+417
-135
No files matched your search
@@ -126,6 +126,7 @@ hasCJKLanguage = true
|
|||||||
# 弹幕配置 (Barrage Configuration)
|
# 弹幕配置 (Barrage Configuration)
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
[params.barrage]
|
[params.barrage]
|
||||||
|
enable = true
|
||||||
enableHitokoto = true
|
enableHitokoto = true
|
||||||
hitokotoUrl = "https://v1.hitokoto.cn?c=a&c=b&c=c&c=d&c=i"
|
hitokotoUrl = "https://v1.hitokoto.cn?c=a&c=b&c=c&c=d&c=i"
|
||||||
|
|
||||||
|
|||||||
+112
-55
@@ -2192,69 +2192,126 @@ input[type=submit] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 弹幕css */
|
/* 弹幕css */
|
||||||
.barrage {
|
.barrager {
|
||||||
display: -webkit-box;
|
position: fixed;
|
||||||
display: -webkit-flex;
|
top: 0;
|
||||||
display: -moz-box;
|
left: 0;
|
||||||
display: -ms-flexbox;
|
width: 100%;
|
||||||
display: flex;
|
height: 100%;
|
||||||
-webkit-box-orient: horizontal;
|
pointer-events: none; /* 容器不阻挡点击 */
|
||||||
-webkit-box-direction: normal;
|
z-index: 1; /* 在 main (z-index: 10) 背后,但在 body 背景之上 */
|
||||||
-webkit-flex-direction: row;
|
overflow: hidden;
|
||||||
-moz-box-orient: horizontal;
|
}
|
||||||
-moz-box-direction: normal;
|
|
||||||
-ms-flex-direction: row;
|
/* 弹幕条目 (左到右) */
|
||||||
flex-direction: row;
|
.barrage-item {
|
||||||
cursor: pointer;
|
|
||||||
-webkit-flex-wrap: nowrap;
|
|
||||||
-ms-flex-wrap: nowrap;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
-webkit-box-align: center;
|
|
||||||
-webkit-align-items: center;
|
|
||||||
-moz-box-align: center;
|
|
||||||
-ms-flex-align: center;
|
|
||||||
align-items: center;
|
|
||||||
word-break: keep-all;
|
|
||||||
white-space: nowrap;
|
|
||||||
-webkit-border-radius: 20px;
|
|
||||||
border-radius: 20px;
|
|
||||||
padding: 0 20px;
|
|
||||||
padding-left: 15px;
|
|
||||||
opacity: 0.8;
|
|
||||||
will-change: transform;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
-webkit-user-select: none;
|
display: inline-flex;
|
||||||
-moz-user-select: none;
|
align-items: flex-start; /* 顶部对齐 */
|
||||||
-ms-user-select: none;
|
white-space: nowrap;
|
||||||
|
will-change: transform;
|
||||||
|
pointer-events: auto; /* 弹幕本身可点击 */
|
||||||
user-select: none;
|
user-select: none;
|
||||||
pointer-events: auto;
|
transform: translateX(-100%); /* 初始在左侧外 */
|
||||||
text-shadow: 0ch;
|
z-index: 10;
|
||||||
z-index: 11;
|
/* 初始透明度,配合动画实现淡入淡出 */
|
||||||
|
opacity: 0.9;
|
||||||
|
/* 缩小整体尺寸 */
|
||||||
|
transform-origin: left top;
|
||||||
}
|
}
|
||||||
|
|
||||||
.barrage .header-avatar {
|
/* 头像样式 */
|
||||||
-webkit-border-radius: 50%;
|
.barrage-avatar {
|
||||||
|
width: 28px; /* 缩小头像 */
|
||||||
|
height: 28px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
position: relative;
|
margin-right: 8px;
|
||||||
right: 7px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 26px !important;
|
|
||||||
height: 26px !important;
|
|
||||||
min-width: 26px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.barrage .header-avatar img {
|
|
||||||
width: 26px !important;
|
|
||||||
height: 26px !important;
|
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
border-radius: 50%;
|
border: 1px solid rgba(0,0,0,0.05);
|
||||||
|
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
|
||||||
|
flex-shrink: 0;
|
||||||
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pause {
|
/* 聊天气泡样式 (仿QQ/微信风格) */
|
||||||
-webkit-animation-play-state: paused;
|
.barrage-bubble {
|
||||||
animation-play-state: paused;
|
background: #ffffff; /* QQ/微信 白底 */
|
||||||
|
color: #1f1f1f; /* 深黑文字 */
|
||||||
|
padding: 6px 10px; /* 缩小内边距 */
|
||||||
|
border-radius: 6px; /* 稍微减小圆角 */
|
||||||
|
font-size: 13px; /* 缩小字体 */
|
||||||
|
line-height: 1.4;
|
||||||
|
position: relative;
|
||||||
|
box-shadow: 0 1px 5px rgba(0,0,0,0.08);
|
||||||
|
max-width: 260px; /* 减小最大宽度 */
|
||||||
|
white-space: normal;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 气泡小尾巴 */
|
||||||
|
.barrage-bubble::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 10px; /* 调整位置 */
|
||||||
|
left: -5px; /* 调整大小 */
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-top: 5px solid transparent;
|
||||||
|
border-bottom: 5px solid transparent;
|
||||||
|
border-right: 5px solid #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 昼夜切换适配 */
|
||||||
|
[data-theme="dark"] .barrage-avatar {
|
||||||
|
border-color: #444;
|
||||||
|
background: #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .barrage-bubble {
|
||||||
|
background: #262626; /* 深色模式深灰底 */
|
||||||
|
color: #e5e5e5;
|
||||||
|
border: 1px solid rgba(255,255,255,0.05);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .barrage-bubble::before {
|
||||||
|
border-right-color: #262626;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 悬停效果 */
|
||||||
|
.barrage-item:hover .barrage-bubble {
|
||||||
|
background: #f0f0f0; /* 悬停微暗 */
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.barrage-item:hover .barrage-bubble::before {
|
||||||
|
border-right-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .barrage-item:hover .barrage-bubble {
|
||||||
|
background: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .barrage-item:hover .barrage-bubble::before {
|
||||||
|
border-right-color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 左到右动画的关键帧 */
|
||||||
|
@keyframes barrage-slide-right {
|
||||||
|
0% {
|
||||||
|
transform: translateX(-100%); /* 左侧屏幕外 */
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
5% {
|
||||||
|
opacity: 1; /* 快速淡入 */
|
||||||
|
}
|
||||||
|
95% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateX(100vw); /* 右侧屏幕外 */
|
||||||
|
opacity: 0; /* 淡出 */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* artalk样式重写css */
|
/* artalk样式重写css */
|
||||||
|
|||||||
@@ -0,0 +1,285 @@
|
|||||||
|
// 弹幕功能封装
|
||||||
|
(function() {
|
||||||
|
// 异步初始化 Artalk 并获取评论数据
|
||||||
|
function initArtalkAndGetComments() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// 检查 Artalk 是否存在,增加轮询等待机制
|
||||||
|
if (typeof Artalk === 'undefined') {
|
||||||
|
let attempts = 0;
|
||||||
|
const maxAttempts = 50; // 最多等待 5 秒
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
attempts++;
|
||||||
|
if (typeof Artalk !== 'undefined') {
|
||||||
|
clearInterval(interval);
|
||||||
|
Artalk.use((ctx) => {
|
||||||
|
ctx.on('list-loaded', () => {
|
||||||
|
console.log('评论列表加载完毕');
|
||||||
|
const commentsData = ctx.getComments();
|
||||||
|
if (commentsData) {
|
||||||
|
resolve(commentsData);
|
||||||
|
} else {
|
||||||
|
reject('获取评论数据失败');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else if (attempts >= maxAttempts) {
|
||||||
|
clearInterval(interval);
|
||||||
|
console.warn('Artalk 加载超时');
|
||||||
|
reject('Artalk 未定义 (加载超时)');
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Artalk.use((ctx) => {
|
||||||
|
ctx.on('list-loaded', () => {
|
||||||
|
console.log('评论列表加载完毕');
|
||||||
|
const commentsData = ctx.getComments();
|
||||||
|
if (commentsData) {
|
||||||
|
resolve(commentsData);
|
||||||
|
} else {
|
||||||
|
reject('获取评论数据失败');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 弹幕类 (基于 min-barrage 逻辑)
|
||||||
|
class BarrageEngine {
|
||||||
|
constructor(options = {}) {
|
||||||
|
this.container = typeof options.container === 'string'
|
||||||
|
? document.querySelector(options.container)
|
||||||
|
: options.container;
|
||||||
|
|
||||||
|
if (!this.container) {
|
||||||
|
console.warn('[Barrage] 错误: 找不到弹幕容器');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.data = [];
|
||||||
|
this.index = 0;
|
||||||
|
this.timer = null;
|
||||||
|
this.isPaused = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始发送
|
||||||
|
start(data = []) {
|
||||||
|
console.log(`[Barrage] 启动弹幕,共 ${data.length} 条`);
|
||||||
|
this.data = data;
|
||||||
|
if (this.data.length === 0) return;
|
||||||
|
|
||||||
|
this.clear();
|
||||||
|
this.loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清空
|
||||||
|
clear() {
|
||||||
|
if (this.timer) clearTimeout(this.timer);
|
||||||
|
// 清除容器内所有弹幕元素
|
||||||
|
if (this.container) {
|
||||||
|
const items = this.container.querySelectorAll('.barrage-item');
|
||||||
|
items.forEach(item => item.remove());
|
||||||
|
}
|
||||||
|
this.index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 循环发射
|
||||||
|
loop() {
|
||||||
|
// 如果容器不在文档中(PJAX切换后),尝试重新获取容器
|
||||||
|
// (注意:this.container 是 DOM 引用,如果页面重绘,旧引用可能失效)
|
||||||
|
if (!document.body.contains(this.container)) {
|
||||||
|
console.warn('[Barrage] 容器失效,尝试重新获取...');
|
||||||
|
const newContainer = document.querySelector('.barrager');
|
||||||
|
if (newContainer) {
|
||||||
|
this.container = newContainer;
|
||||||
|
console.log('[Barrage] 容器重新获取成功,继续播放');
|
||||||
|
} else {
|
||||||
|
console.warn('[Barrage] 容器彻底丢失,停止播放');
|
||||||
|
return; // 真的没了再停止
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发射逻辑
|
||||||
|
if (!this.isPaused) {
|
||||||
|
const itemData = this.data[this.index];
|
||||||
|
this.shoot(itemData);
|
||||||
|
this.index = (this.index + 1) % this.data.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 随机间隔 1s - 3s
|
||||||
|
const interval = 1000 + Math.random() * 2000;
|
||||||
|
this.timer = setTimeout(() => this.loop(), interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发射单条
|
||||||
|
shoot(itemData) {
|
||||||
|
const { text, avatar, url, id } = itemData;
|
||||||
|
|
||||||
|
const item = document.createElement('div');
|
||||||
|
item.className = 'barrage-item';
|
||||||
|
|
||||||
|
// 构造内部 HTML 结构:头像 + 气泡
|
||||||
|
let html = '';
|
||||||
|
|
||||||
|
// 1. 头像
|
||||||
|
if (avatar) {
|
||||||
|
html += `<img src="${avatar}" class="barrage-avatar" draggable="false">`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 气泡 (包裹文本)
|
||||||
|
html += `<div class="barrage-bubble"><span class="barrage-text">${text}</span></div>`;
|
||||||
|
|
||||||
|
item.innerHTML = html;
|
||||||
|
|
||||||
|
// 点击跳转 (通用处理)
|
||||||
|
const jumpHandler = (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
console.log(`[Barrage] 点击跳转: ${url}`);
|
||||||
|
|
||||||
|
// 检查目标评论是否在当前页面
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (url && url !== '#') {
|
||||||
|
item.addEventListener('click', jumpHandler);
|
||||||
|
item.style.cursor = 'pointer';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 随机轨道 (Top 5% - 95%) - 避免太靠边
|
||||||
|
const tracks = 15;
|
||||||
|
const trackHeight = 100 / tracks;
|
||||||
|
const trackIndex = Math.floor(Math.random() * tracks);
|
||||||
|
const top = trackIndex * trackHeight + (Math.random() * 2);
|
||||||
|
|
||||||
|
item.style.top = `${top}%`;
|
||||||
|
|
||||||
|
// 随机速度 (18s - 25s) - 更慢一点,更自然
|
||||||
|
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 = '99999';
|
||||||
|
});
|
||||||
|
item.addEventListener('mouseleave', () => {
|
||||||
|
item.style.animationPlayState = 'running';
|
||||||
|
item.style.zIndex = '10';
|
||||||
|
});
|
||||||
|
|
||||||
|
// 动画结束移除
|
||||||
|
item.addEventListener('animationend', () => {
|
||||||
|
item.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.container.appendChild(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 挂载到 window,使用 BarrageEngine 避免冲突
|
||||||
|
window.BarrageEngine = BarrageEngine;
|
||||||
|
|
||||||
|
// 从 Artalk 评论数据生成弹幕
|
||||||
|
async function createBarragerFromArtalk(commentsData) {
|
||||||
|
const barragerContainer = document.querySelector('.barrager');
|
||||||
|
if (!barragerContainer) {
|
||||||
|
console.warn('[Barrage] 未找到弹幕容器 .barrager');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 数据预处理
|
||||||
|
const barrageList = commentsData.map(comment => {
|
||||||
|
// 清理 HTML 标签
|
||||||
|
const contentText = comment.content.replace(/<[^>]+>/g, "").substring(0, 50);
|
||||||
|
|
||||||
|
// 获取头像逻辑优化: 优先从 DOM 获取 Artalk 已渲染的头像,其次使用 API 数据
|
||||||
|
let avatarUrl = '';
|
||||||
|
|
||||||
|
// 尝试从 DOM 获取 (最准确,因为是 Artalk 自己渲染的)
|
||||||
|
const commentEl = document.getElementById(`atk-comment-${comment.id}`);
|
||||||
|
if (commentEl) {
|
||||||
|
const imgEl = commentEl.querySelector('.atk-avatar img');
|
||||||
|
if (imgEl && imgEl.src) {
|
||||||
|
avatarUrl = imgEl.src;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果 DOM 没取到,尝试从数据获取
|
||||||
|
if (!avatarUrl) {
|
||||||
|
if (comment.avatar) {
|
||||||
|
avatarUrl = comment.avatar;
|
||||||
|
} else if (comment.ua && comment.ua.avatar) {
|
||||||
|
avatarUrl = comment.ua.avatar;
|
||||||
|
} else {
|
||||||
|
avatarUrl = 'https://cravatar.cn/avatar/default?d=mp';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
text: contentText,
|
||||||
|
avatar: avatarUrl,
|
||||||
|
url: `#atk-comment-${comment.id}`, // 跳转锚点
|
||||||
|
id: comment.id
|
||||||
|
};
|
||||||
|
}).filter(item => item.text.trim() !== "");
|
||||||
|
|
||||||
|
if (barrageList.length === 0) {
|
||||||
|
console.log('[Barrage] 没有有效的评论弹幕数据');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 初始化 Barrage 实例
|
||||||
|
// 挂载到 window 以便调试或清理
|
||||||
|
if (window.myBarrage) {
|
||||||
|
window.myBarrage.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 window.BarrageEngine
|
||||||
|
if (window.BarrageEngine) {
|
||||||
|
window.myBarrage = new window.BarrageEngine({
|
||||||
|
container: barragerContainer
|
||||||
|
});
|
||||||
|
window.myBarrage.start(barrageList);
|
||||||
|
} else {
|
||||||
|
console.error('[Barrage] window.BarrageEngine 未定义');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载弹幕主函数
|
||||||
|
async function loadBarrager() {
|
||||||
|
try {
|
||||||
|
const commentsData = await initArtalkAndGetComments();
|
||||||
|
if (commentsData) {
|
||||||
|
await createBarragerFromArtalk(commentsData);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载弹幕时发生错误:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化监听
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
loadBarrager(); // 页面首次加载时启动弹幕
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('pjax:complete', function() {
|
||||||
|
// PJAX 跳转后重新加载弹幕
|
||||||
|
loadBarrager();
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -79,81 +79,9 @@ if (typeof lazyLoadInit === 'function') {
|
|||||||
console.warn('lazyLoadInit is not defined');
|
console.warn('lazyLoadInit is not defined');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadBarrager() {
|
|
||||||
try {
|
|
||||||
const commentsData = await initArtalkAndGetComments();
|
|
||||||
if (commentsData) {
|
|
||||||
await createBarragerFromArtalk(commentsData);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('加载弹幕时发生错误:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 异步初始化 Artalk 并获取评论数据
|
// 异步初始化 Artalk 并获取评论数据 (Moved to barrage.js)
|
||||||
function initArtalkAndGetComments() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
Artalk.use((ctx) => {
|
|
||||||
ctx.on('list-loaded', () => {
|
|
||||||
console.log('评论列表加载完毕');
|
|
||||||
const commentsData = ctx.getComments();
|
|
||||||
if (commentsData) {
|
|
||||||
resolve(commentsData);
|
|
||||||
// console.log(commentsData);
|
|
||||||
} else {
|
|
||||||
reject('获取评论数据失败');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 从 Artalk 评论数据生成弹幕
|
|
||||||
async function createBarragerFromArtalk(commentsData) {
|
|
||||||
// 确保弹幕容器存在
|
|
||||||
const barragerContainer = document.querySelector('.barrager');
|
|
||||||
if (!barragerContainer) {
|
|
||||||
console.warn('未找到弹幕容器 .barrager');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. 过滤和处理评论数据 (只保留昵称和内容)
|
|
||||||
const barrageList = commentsData.map(comment => {
|
|
||||||
// 简单清理 HTML 标签,保留纯文本 (可选)
|
|
||||||
const contentText = comment.content.replace(/<[^>]+>/g, "").substring(0, 50); // 限制长度
|
|
||||||
return {
|
|
||||||
info: contentText, // 弹幕内容
|
|
||||||
href: '#', // 链接 (可选,点击弹幕跳转)
|
|
||||||
speed: 10 + Math.random() * 5, // 随机速度
|
|
||||||
color: '#fff', // 字体颜色 (白色)
|
|
||||||
old_ie_color: '#000000', // 旧版 IE 颜色
|
|
||||||
};
|
|
||||||
}).filter(item => item.info.trim() !== ""); // 过滤空评论
|
|
||||||
|
|
||||||
// 如果没有评论,则不显示弹幕
|
|
||||||
if (barrageList.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 初始化 jQuery.barrager (如果尚未初始化)
|
|
||||||
// 注意:这里假设 jquery.barrager.js 已经加载并挂载到 jQuery 对象上
|
|
||||||
// 由于 barrager 插件通常是直接操作 DOM,我们可能需要循环添加
|
|
||||||
|
|
||||||
// 简单的循环发送弹幕示例 (每隔一段时间发送一条)
|
|
||||||
let index = 0;
|
|
||||||
const sendBarrage = () => {
|
|
||||||
if (index >= barrageList.length) {
|
|
||||||
index = 0; // 循环播放
|
|
||||||
}
|
|
||||||
const item = barrageList[index];
|
|
||||||
// 使用 jQuery 选择器调用 barrager
|
|
||||||
$('body').barrager(item);
|
|
||||||
index++;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 每 2 秒发送一条弹幕
|
|
||||||
setInterval(sendBarrage, 2000);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async function fetchHitokoto() {
|
async function fetchHitokoto() {
|
||||||
@@ -225,11 +153,11 @@ function initCodeCopy() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 页面加载完成后初始化
|
// 页面加载完成后初始化 (Merged into main DOMContentLoaded listener)
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
// document.addEventListener('DOMContentLoaded', function() {
|
||||||
initCodeCopy();
|
// initCodeCopy();
|
||||||
initDescriptionHitokoto();
|
// initDescriptionHitokoto();
|
||||||
});
|
// });
|
||||||
|
|
||||||
// 初始化个人描述一言切换
|
// 初始化个人描述一言切换
|
||||||
function initDescriptionHitokoto() {
|
function initDescriptionHitokoto() {
|
||||||
@@ -367,11 +295,15 @@ function initFloatingTools() {
|
|||||||
document.addEventListener('pjax:complete', function() {
|
document.addEventListener('pjax:complete', function() {
|
||||||
updateFloatingToolsVisibility();
|
updateFloatingToolsVisibility();
|
||||||
hideSelectionPopup();
|
hideSelectionPopup();
|
||||||
|
// PJAX 跳转后重新加载弹幕 (Moved to barrage.js)
|
||||||
});
|
});
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
initFloatingTools();
|
initFloatingTools();
|
||||||
initSelectionPopup();
|
initSelectionPopup();
|
||||||
|
initCodeCopy();
|
||||||
|
initDescriptionHitokoto();
|
||||||
|
// 页面首次加载时启动弹幕 (Moved to barrage.js)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Selection Popup Logic
|
// Selection Popup Logic
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{{ if .Site.Params.barrage.enable }}
|
||||||
|
<!-- 弹幕容器 (body 标签下) -->
|
||||||
|
<div class="barrager"></div>
|
||||||
|
{{ end }}
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
{{ $easylazyload := resources.Get "js/EasyLazyload.min.js" }}
|
{{ $easylazyload := resources.Get "js/EasyLazyload.min.js" }}
|
||||||
{{ $viewimage := resources.Get "js/view-image.min.js" }}
|
{{ $viewimage := resources.Get "js/view-image.min.js" }}
|
||||||
{{ $artalk := resources.Get "js/Artalk.js" }}
|
{{ $artalk := resources.Get "js/Artalk.js" }}
|
||||||
|
{{ $barrage := resources.Get "js/barrage.js" }}
|
||||||
{{ $main := resources.Get "js/main.js" }}
|
{{ $main := resources.Get "js/main.js" }}
|
||||||
{{ $mypjax := resources.Get "js/mypjax.js" }}
|
{{ $mypjax := resources.Get "js/mypjax.js" }}
|
||||||
{{ $nprogress := resources.Get "js/nprogress.js" }}
|
{{ $nprogress := resources.Get "js/nprogress.js" }}
|
||||||
@@ -37,7 +38,7 @@
|
|||||||
{{ $echarts := resources.Get "js/echarts.min.js" }}
|
{{ $echarts := resources.Get "js/echarts.min.js" }}
|
||||||
{{ $tiaozhuan := resources.Get "js/tiaozhuan.js" }}
|
{{ $tiaozhuan := resources.Get "js/tiaozhuan.js" }}
|
||||||
|
|
||||||
{{ $scripts := slice $iconfont $lightgallery $uikit $easylazyload $viewimage $artalk $main $mypjax $nprogress $message $echarts $tiaozhuan | resources.Concat "js/bundle.js" | resources.Minify | resources.Fingerprint }}
|
{{ $scripts := slice $iconfont $lightgallery $uikit $easylazyload $viewimage $artalk $barrage $main $mypjax $nprogress $message $echarts $tiaozhuan | resources.Concat "js/bundle.js" | resources.Minify | resources.Fingerprint }}
|
||||||
<script src="{{ $scripts.RelPermalink }}"></script>
|
<script src="{{ $scripts.RelPermalink }}"></script>
|
||||||
<script async src="/js/bsz.js"></script>
|
<script async src="/js/bsz.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -206,7 +206,7 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script src="/js/jquery.min.js"></script>
|
<script src="/js/jquery.min.js"></script>
|
||||||
<script src="/js/barrage.min.js"></script>
|
|
||||||
|
|
||||||
<script src="/js/instantpage.min.js" type="module" defer></script>
|
<script src="/js/instantpage.min.js" type="module" defer></script>
|
||||||
<script src="/js/pjax.js"></script>
|
<script src="/js/pjax.js"></script>
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
<!-- 弹幕容器 (body 标签下) -->
|
||||||
|
{{ partial "barrage.html" . }}
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
|
|||||||
Reference in new issue
Block a user