抖音直播漂屏弹幕显示用户名称
netnr 2024-12-20
// 暴力猴 https://greasyfork.org/zh-CN/scripts/521309

// ==UserScript==
// @name         douyin_barrage
// @namespace    https://github.com/netnr
// @icon         https://zme.ink/favicon.svg
// @version      2024.12.21.1011
// @description  抖音直播漂屏弹幕显示用户名称
// @author       netnr
// @license      MIT
// @match        *://live.douyin.com/1*
// @match        *://live.douyin.com/2*
// @match        *://live.douyin.com/3*
// @match        *://live.douyin.com/4*
// @match        *://live.douyin.com/5*
// @match        *://live.douyin.com/6*
// @match        *://live.douyin.com/7*
// @match        *://live.douyin.com/8*
// @match        *://live.douyin.com/9*
// ==/UserScript==

let nrBarrage = {
    init: async () => {

        // 等待就绪
        for (let i = 0; i < 9; i++) {
            nrBarrage.domSide = document.querySelector("div.webcast-chatroom___items>div");
            if (document.querySelector("xg-danmu") && nrBarrage.domSide) {
                break;
            }
            await nrBarrage.sleep();
        }

        if (nrBarrage.domSide && !nrBarrage.tsObServer) {
            // 观察者实例、及处理方式
            nrBarrage.tsObServer = new MutationObserver(function (mutationsList) {
                for (const mutation of mutationsList) {
                    // 新增的节点(弹幕)
                    mutation.addedNodes.forEach(addedNode => {
                        let domBarrageNode = document.getElementById(addedNode.dataset.id);
                        // 漂屏弹幕
                        if (domBarrageNode) {
                            domBarrageNode.innerHTML = addedNode.innerHTML;
                            let height = window.getComputedStyle(domBarrageNode).height;
                            domBarrageNode.querySelectorAll("*").forEach(domToken => {
                                if (domToken.nodeName == "IMG") {
                                    domToken.removeAttribute("width");
                                    domToken.removeAttribute("height");
                                    domToken.style.height = height;
                                } else {
                                    Object.assign(domToken.style, {
                                        fontSize: "inherit",
                                        height: height,
                                    })
                                }
                            });
                        }
                    });
                }
            });

            // 开始观察右侧弹幕列表的变化
            nrBarrage.tsObServer.observe(nrBarrage.domSide, nrBarrage.tsConfig);

            console.debug("\n\n===== 已开启漂屏弹幕显示用户名称\n\n\n");
        }
    },
    destroy: () => {
        nrBarrage.tsObServer.disconnect();
        console.debug("\n\n===== 已重置\n\n\n")
    },
    domSide: null,
    tsObServer: null,
    tsConfig: {
        childList: true,  // 增加或删除
        attributes: false, // 属性
        subtree: false,   // 子节点
        characterData: false // 内容
    },
    sleep: (time) => new Promise(resolve => setTimeout(() => resolve(), time || 1000))
};

nrBarrage.init(); // 初始化
// nrBarrage.destroy(); // 取消
登录写评论