留言板全页弹幕
留言板以前就是个评论框,访客留言之后除了他自己,没人知道这里发生过什么。B 站式的弹幕正好反过来——每条留言都飘在你眼前,页面是活的。这篇文章记录我怎么给 Hexo + Fluid + Twikoo 的留言板加全页弹幕:不改后端、不动 Twikoo 源码,一个 JS 文件加一段 CSS 搞定。
最终效果
- 评论区发言后,留言化作深灰胶囊弹幕飘过整个页面——不是评论框上方那一小条,是
position: fixed全屏悬浮层,横向飞过视口 - 昵称是金色的,博主回复走品牌蓝渐变胶囊,一眼分清谁在说话
- 点弹幕定位评论:点任意一条,页面平滑滚到对应评论并高亮闪烁两下
- 左下角开关:不想看弹幕一键关闭,选择存 localStorage,下次访问不打扰
- 还没有留言时飘欢迎弹幕兜底,引导访客抢第一条
原理
数据源用 Twikoo 现成的 COMMENT_GET 接口——就是评论区自己拉评论用的那个,POST 一个 { event: 'COMMENT_GET', url: '/message/' } 过去,返回当前页全部评论(含 id、nick、comment HTML、master 标记)。所以这套弹幕零后端改动,评论一发出来,刷新页面就能上弹幕。
实现
新建 source/js/message-danmaku.js(Fluid 放 custom_js 里全站加载,脚本内部按路径自启):
1 | |
几个关键点:
接口有主备。先打同源 /twikoo,失败换备用域名,都是静默降级——弹幕挂了不能影响评论区本身。
点击定位。每条评论带 id,弹幕元素上挂 click,scrollIntoView 平滑滚过去,再给评论节点加一个 box-shadow 闪烁动画(animation: dm-target-flash 1.6s ease 2)。有个细节:连续点同一条要重新触发动画,得先 classList.remove 再强制一次 offsetWidth 重排,否则动画不会重放。
开关带记忆。localStorage 记开关状态;关闭状态下连评论接口都不请求,只挂 UI,用户打开时才拉数据——省一次 API 调用,也尊重「我不想看弹幕」这个选择。
样式只在留言板出现。CSS 写在 source/message/index.md 页面内(弹幕胶囊、金色昵称、开关按钮、暗色模式适配、prefers-reduced-motion 降级为右上角静态一列),配合页面里的 #dm-root 容器。悬浮层 z-index: 90——低于导航栏(≥100)高于正文,且 pointer-events: none,只有弹幕本身可点,不挡页面任何交互。
样式细节
深灰胶囊 rgba(58,58,58,.78) + backdrop-filter: blur(3px),金色昵称 #f5c542 加粗,昵称后跟全角冒号;博主胶囊 linear-gradient(120deg, #426cb2, #3282...) 系。暗色模式胶囊更透一点。prefers-reduced-motion 用户不飞弹幕——静态贴右上角一列,可滚动查看。
弹幕字数截 60 字上限,超长的看评论区原文——弹幕是预告片,评论区才是正片。