我把91视频的弹幕开关拆给你看:其实一点都不玄学

弹幕看起来神秘,实际上只是前端和后端几个开关配合的结果。把这些环节拆开来看,你就能明白为什么开关会“记住”你的选择、为什么有时候切了弹幕它还会跳出来,甚至可以自己动手实现更稳妥的关弹幕方式。下面一步步讲清楚,手把手教你从观察到改造。
一、先了解弹幕的常见实现方式
- DOM 元素叠加:很多站点把弹幕作为一组绝对定位的 DOM 节点(div、span)插入到视频容器上,靠 CSS 控制位置与动画。
- Canvas 渲染:性能更好的一种做法,弹幕绘制在 canvas 上,用 requestAnimationFrame 渲染。
- WebSocket / 长轮询:弹幕数据通常由服务器实时推送(WebSocket)或定时拉取。
- 状态保存:用户的“弹幕开关”通常保存在 localStorage、cookie、后端用户设置或 URL 参数中。
二、如何用浏览器开发者工具拆解弹幕开关
- 打开开发者工具(F12)→ Elements,播放页面时切换弹幕开关,观察哪些节点新增或隐藏:
- 如果看到类名像 danmaku、barrage、bullet、弹幕 等的元素增减,说明是 DOM 实现。
- 如果只是有一个 canvas 元素消失/出现,说明用的是 canvas 渲染。
- Network 面板:
- 切换弹幕看看是否触发 WebSocket 连接,或者是否有 /danmaku、/barrage 等接口请求,记录请求地址。
- Application 面板:
- 检查 localStorage、sessionStorage、cookie 有没有与弹幕相关的键(例如 showDanmaku=true)。
- Sources 面板:
- 给可能控制开关的函数(点击按钮触发的事件)设置断点,跟踪开关逻辑;或在 Event Listener 列表中定位按钮的点击处理函数。
三、常见场景与对应对策(从最简单到最彻底) 场景 A:弹幕为 DOM 元素
- 临时隐藏:在浏览器控制台执行 document.querySelectorAll('.danmaku, .barrage, .bullet').forEach(el => el.style.display='none')
- 更稳妥的办法:注入 CSS 覆盖(推荐在用户样式扩展或自定义 CSS 插件里) .danmaku, .barrage, .bullet { display: none !important; visibility: hidden !important; pointer-events: none !important; } 场景 B:弹幕绘在 canvas 上
- 隐藏画布:document.querySelector('canvas.danmaku-canvas').style.display='none'
- 若站点定期重建 canvas,可用 MutationObserver 或持续脚本自动隐藏。 场景 C:后端持续推送弹幕(WebSocket)
- 阻断数据源:使用 uBlock Origin 或类似扩展屏蔽 WebSocket 或特定请求 URL。
- 客户端拦截:用脚本覆盖 WebSocket 构造函数,禁止建立连接(高级用法)。 场景 D:开关状态会被后端记住
- 若是后端记录(登录用户设置),需要在个人设置里关闭;否则客户端隐藏仅影响本地显示,但不会更改服务器记录。
四、给你一个通用的 Tampermonkey 脚本范例(模板) 说明:下面是通用模板,需要把选择器改成目标站点实际使用的类名/ID。把这段脚本装到 Tampermonkey,能在页面加载时自动隐藏弹幕并对动态加载情况做处理。
// ==UserScript==
// @name 屏蔽弹幕(通用版)
// @match https://*/* // 按需限制域名
// @grant none
// ==/UserScript==
(function(){
const SELS = ['.danmaku', '.barrage', '.bullet', '#danmaku', 'canvas.danmaku-canvas']; // 根据站点调整
function hideAll() {
SELS.forEach(s=> {
document.querySelectorAll(s).forEach(el=>{
el.style.display = 'none';
el.style.visibility = 'hidden';
el.style.pointerEvents = 'none';
});
});
}
// 初次执行
hideAll();
// 监听 DOM 变化,防止站点重建弹幕层
const mo = new MutationObserver(hideAll);
mo.observe(document.documentElement || document.body, {childList:true, subtree:true});
})();
五、如果想“彻底”关弹幕
- 最彻底的客户端方式:同时屏蔽弹幕 DOM/canvas,阻断 WebSocket/接口请求(uBlock 规则),并在 localStorage/cookie 里把相关键设为 false。
- 若站点把偏好存在服务器端,需要在站内设置页修改或联系支持。
六、常见问题与解决办法
- 切了弹幕后刷新又出现:可能是后端默认开启,你只做了客户端隐藏,建议配合阻断 WebSocket 或修改存储键。
- 页面不停创建弹幕层:使用 MutationObserver 或更强的 CSS 选择器(!important)通常能解决。
- 找不到选择器:在 Elements 面板搜索关键词(danmaku、barrage、弹幕)或以 canvas 为线索检查父容器。