您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
打开直播页面自动开始抓取数据,目前支持数据有:弹幕、SC、礼物、舰队、点赞总数、看过人数、粉丝数量变化!
// ==UserScript== // @name b站直播数据抓取助手(支持弹幕、礼物流水导出统计) // @namespace http://tampermonkey.net/ // @version 0.0.2 // @description 打开直播页面自动开始抓取数据,目前支持数据有:弹幕、SC、礼物、舰队、点赞总数、看过人数、粉丝数量变化! // @author 口吃者 // @match https://live.bilibili.com/* // @run-at document-start // @grant unsafeWindow // @license MIT // ==/UserScript== (function () { 'use strict'; class Node { constructor(data) { this.data = data; this.next = null; } } class HighPerformanceTableData { constructor() { this.head = null; // 指向链表的头节点 this.size = 0; // 记录链表中的元素数量 } // 从头部快速添加一个新元素 addFirst(element) { const newNode = new Node(element); newNode.next = this.head; this.head = newNode; this.size++; } // 将链表中的所有元素转换成数组 toArray() { const result = []; let current = this.head; while (current) { result.push(current.data); current = current.next; } return result; } // 获取容器大小 getSize() { return this.size; } // 打印链表中的元素(可选) print() { let str = ""; let current = this.head; while (current) { str += JSON.stringify(current.data) + " "; current = current.next; } console.log(str.trim()); } } layuiLoad(); var wssSubUrl = 'wss://zj-cn-live-comet.chat.bilibili.com:2245/sub' var originalWebSocket = WebSocket; var wsSub; var guardLvMapped = { 0: "无", 1: "总督", 2: "提督", 3: "舰长" }; var wsSubTable01Data = new HighPerformanceTableData(); var wsSubTable02Data = new HighPerformanceTableData(); var wsSubData03 = {fans:-1, watchedChange:-1, clickCount:-1, fansDate:-1, watchedChangeDate:-1, clickCountDate:-1}; HookedWebSocket.prototype = originalWebSocket.prototype; unsafeWindow.WebSocket = HookedWebSocket; window.addEventListener('load', getLiveData) window.addEventListener('load', addPanel) var cssText = ` #MyButton { color: #592A0E; background: #fff; border: none; padding: 10px 20px; display: inline-block; font-size: 11px; font-weight: 400; width: 70x; text-transform: uppercase; cursor: pointer; position: fixed; top: 50%; left: -40px; z-index: 1000; transition: all 0.7s; } #MyButton span { display: inline-block; } #MyButton::before { content: ''; position: absolute; top: 0; bottom: 0; left: 0; right: 100%; background-image: linear-gradient(to right, #ff8177 0%, #ff867a 0%, #ff8c7f 21%, #f99185 52%, #cf556c 78%, #b12a5b 100%); opacity: 0; z-index: -1; transition: all 0.7s; backface-visibility: hidden; } #MyButton:hover { overflow: hidden; left: -10px; color: #fff; transition: all 0.7s; } #MyButton:hover::before { left: 0; right: 0; opacity: 1; } #MyButton:active { letter-spacing: 1.5px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); transition: 100ms; } #MyButton:active::before { background-image: linear-gradient(to right, #e06a6a 0%, #e06d6d 0%, #e07373 21%, #d27878 52%, #ae4c4c 78%, #902525 100%); opacity: 1; } #tableBtnContainer{ text-align: right; } #tableBtnContainer01{ text-align: right; } ` GMaddStyle(cssText); function layuiLoad() { let link = document.createElement('link'); link.rel = 'stylesheet'; link.type = 'text/css'; link.href = 'https://www.layuicdn.com/layui/css/layui.css'; let script = document.createElement("script"); script.type = "text/javascript"; script.src = "https://www.layuicdn.com/layui/layui.js"; document.head.appendChild(script); document.head.appendChild(link); } function HookedWebSocket(url, protocols) { var socket = new originalWebSocket(url, protocols); if (url === wssSubUrl) { wsSub = socket; } return socket; } /* convertToObjectFuc env */ var wsBinaryHeaderList = [{ "name": "Header Length", "key": "headerLen", "bytes": 2, "offset": 4, "value": 16 }, { "name": "Protocol Version", "key": "ver", "bytes": 2, "offset": 6, "value": 1 }, { "name": "Operation", "key": "op", "bytes": 4, "offset": 8, "value": 2 }, { "name": "Sequence Id", "key": "seq", "bytes": 4, "offset": 12, "value": 1 }] function o_a_getDecoder() { return window.TextDecoder ? new window.TextDecoder : { decode: function (e) { return decodeURIComponent(window.escape(String.fromCharCode.apply(String, new Uint8Array(e)))) } } } var this_decoder; var r_a = { "WS_OP_HEARTBEAT": 2, "WS_OP_HEARTBEAT_REPLY": 3, "WS_OP_MESSAGE": 5, "WS_OP_USER_AUTHENTICATION": 7, "WS_OP_CONNECT_SUCCESS": 8, "WS_PACKAGE_HEADER_TOTAL_LENGTH": 16, "WS_PACKAGE_OFFSET": 0, "WS_HEADER_OFFSET": 4, "WS_VERSION_OFFSET": 6, "WS_OPERATION_OFFSET": 8, "WS_SEQUENCE_OFFSET": 12, "WS_BODY_PROTOCOL_VERSION_NORMAL": 0, "WS_BODY_PROTOCOL_VERSION_BROTLI": 3, "WS_HEADER_DEFAULT_VERSION": 1, "WS_HEADER_DEFAULT_OPERATION": 1, "WS_HEADER_DEFAULT_SEQUENCE": 1, "WS_AUTH_OK": 0, "WS_AUTH_TOKEN_ERROR": -101 } /* convert ArrayBuffer to Object */ function convertToObjectFuc(e) { var t = new DataView(e) , i = { body: [] }; if (i.packetLen = t.getInt32(r_a.WS_PACKAGE_OFFSET), wsBinaryHeaderList.forEach((function (e) { 4 === e.bytes ? i[e.key] = t.getInt32(e.offset) : 2 === e.bytes && (i[e.key] = t.getInt16(e.offset)) } )), i.packetLen < e.byteLength && convertToObjectFuc(e.slice(0, i.packetLen)), this_decoder || (this_decoder = o_a_getDecoder()), !i.op || r_a.WS_OP_MESSAGE !== i.op && i.op !== r_a.WS_OP_CONNECT_SUCCESS) i.op && r_a.WS_OP_HEARTBEAT_REPLY === i.op && (i.body = { count: t.getInt32(r_a.WS_PACKAGE_HEADER_TOTAL_LENGTH) }); else for (var n = r_a.WS_PACKAGE_OFFSET, s = i.packetLen, a = "", l = ""; n < e.byteLength; n += s) { s = t.getInt32(n), a = t.getInt16(n + r_a.WS_HEADER_OFFSET); if (i.ver === r_a.WS_BODY_PROTOCOL_VERSION_NORMAL) { var c = this_decoder.decode(e.slice(n + a, n + s)); l = 0 !== c.length ? JSON.parse(c) : null } else if (i.ver === r_a.WS_BODY_PROTOCOL_VERSION_BROTLI) { var h = e.slice(n + a, n + s) , u = unsafeWindow.BrotliDecode(new Uint8Array(h)); l = convertToObjectFuc(u.buffer).body } l && i.body.push(l) } return i } /* 转化为表格可用json数据 */ function convertToTableData(ele) { switch (ele.cmd) { case "DANMU_MSG": let damuInfo = ele.info; let damuUserInfo = damuInfo[0][15].user; let name = damuUserInfo.base.name; let is_mystery = damuUserInfo.base.is_mystery ? 1 : 0; let content = damuInfo[1]; let level = -1; let medal = -1; let guard_level = '无'; let score = -1; let medalFrom = -1; let uid = damuUserInfo.uid; if (damuUserInfo.medal) { level = damuInfo[3][0]; medal = damuInfo[3][1]; guard_level = guardLvMapped[damuUserInfo.medal.guard_level]; score = damuUserInfo.medal.score; medalFrom = damuInfo[3][2]; } let time = formatTimestamp(damuInfo[9].ts); let consumer_level = damuInfo[16][0]; let tableJsonData = { name: name, reply_is_mystery: is_mystery, level: level, medal: medal, guard_level: guard_level, score: score, medalFrom: medalFrom, time: time, consumer_level: consumer_level, content: content, uid: uid } wsSubTable01Data.addFirst(tableJsonData); break; case "SEND_GIFT": let sendGiftInfo = ele.data; let sendGiftGiftName = sendGiftInfo.giftName; let sendGiftDmScore = sendGiftInfo.dmscore; let sendGiftGuardLevel = guardLvMapped[sendGiftInfo.guard_level]; let sendGiftNum = sendGiftInfo.num; let sendGiftUid = sendGiftInfo.uid; let sendGiftTime = formatTimestamp(sendGiftInfo.timestamp); let sendGiftPrice = sendGiftInfo.price; let sendGiftUserName = sendGiftInfo.sender_uinfo.base.name; let sendGiftJsonData = { dmscore: sendGiftDmScore, num: sendGiftNum, price: sendGiftPrice, giftName: sendGiftGiftName, time: sendGiftTime, username: sendGiftUserName, uid: sendGiftUid, guard_level: sendGiftGuardLevel } wsSubTable02Data.addFirst(sendGiftJsonData); break; case "USER_TOAST_MSG": let userToastMsgInfo = ele.data; let userToastMsgDmScore = userToastMsgInfo.dmscore; let userToastMsgNum = userToastMsgInfo.num; let userToastMsgPrice = userToastMsgInfo.price; let userToastMsgRoleName = userToastMsgInfo.role_name; let userToastMsgSendTime = formatTimestamp(userToastMsgInfo.start_time); let userToastMsgUserName = userToastMsgInfo.username; let userToastMsgSUid = userToastMsgInfo.uid; let userToastMsgGuardLevel = guardLvMapped[userToastMsgInfo.guard_level]; let userToastMsgJsonData = { dmscore: userToastMsgDmScore, num: userToastMsgNum, price: userToastMsgPrice, giftName: userToastMsgRoleName, time: userToastMsgSendTime, username: userToastMsgUserName, uid: userToastMsgSUid, guard_level: userToastMsgGuardLevel } wsSubTable02Data.addFirst(userToastMsgJsonData); break; case "SUPER_CHAT_MESSAGE": let superChatMessageInfo = ele.data; let superChatMessageTime = formatTimestamp(superChatMessageInfo.ts); let superChatMessageGiftName = "醒目留言"; let superChatMessageGiftNum = superChatMessageInfo.gift.num; let superChatMessageContent = superChatMessageInfo.message; let superChatMessagePrice = superChatMessageInfo.price; let superChatMessageUserName = superChatMessageInfo.user_info.uname; let superChatMessageSUid = superChatMessageInfo.uinfo.uid; let superChatMessageGuardLevel = guardLvMapped[superChatMessageInfo.user_info.guard_level]; let superChatMessageDmScore = superChatMessageInfo.dmscore; let superChatMessageJsonData = { dmscore: superChatMessageDmScore, num: superChatMessageGiftNum, price: superChatMessagePrice, giftName: superChatMessageGiftName + ": " + superChatMessageContent, time: superChatMessageTime, username: superChatMessageUserName, uid: superChatMessageSUid, guard_level: superChatMessageGuardLevel, } wsSubTable02Data.addFirst(superChatMessageJsonData); break; case "LIKE_INFO_V3_UPDATE": wsSubData03.clickCount = ele.data.click_count; wsSubData03.clickCountDate = getCurrentFormattedDateTime(); break; case "WATCHED_CHANGE": wsSubData03.watchedChange = ele.data.num; wsSubData03.watchedChangeDate = getCurrentFormattedDateTime(); break; case "ROOM_REAL_TIME_MESSAGE_UPDATE": wsSubData03.fans = ele.data.fans; wsSubData03.fansDate = getCurrentFormattedDateTime(); break; default: // console.log("收到消息:", ele); break; } return true; } function formatTimestamp(timestamp) { // 创建一个新的Date对象,传入时间戳(如果时间戳是以秒为单位,需要乘以1000) const date = new Date(timestamp * 1000); // 获取年份、月份、日期、小时、分钟和秒数 const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始,所以需要加1 const day = String(date.getDate()).padStart(2, '0'); const hours = String(date.getHours()).padStart(2, '0'); const minutes = String(date.getMinutes()).padStart(2, '0'); const seconds = String(date.getSeconds()).padStart(2, '0'); // 返回格式化的日期时间字符串 return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; } function getCurrentFormattedDateTime() { const now = new Date(); // 获取年份 const year = now.getFullYear(); // 获取月份(注意:月份是从0开始的,所以需要加1) const month = String(now.getMonth() + 1).padStart(2, '0'); // 获取日期 const day = String(now.getDate()).padStart(2, '0'); // 获取小时 const hours = String(now.getHours()).padStart(2, '0'); // 获取分钟 const minutes = String(now.getMinutes()).padStart(2, '0'); // 获取秒 const seconds = String(now.getSeconds()).padStart(2, '0'); // 拼接成最终的字符串 return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; } /* 直播数据获取*/ function getLiveData() { if (!wsSub) { console.log('wsSub is null'); return; } let originalMessageFuc = wsSub.onmessage; wsSub.onmessage = function (event) { var objectData = convertToObjectFuc(event.data) try { if (objectData.body.length >= 1) { if (objectData.body[0].length >= 1) { objectData.body[0].forEach((ele) => { convertToTableData(ele); }) } } } catch (e) { console.log("解析消息失败:", e, objectData); } if (typeof originalMessageFuc === 'function') { originalMessageFuc.call(this, event); } }; } function addPanel() { // 定义表格数据 //默认按照时间戳降序排序 +荣誉等级 粉丝牌名 var tableData; var tableData01; var timer; function genButtonSpan(text, foo, id, fooParams = {}) { let b = document.createElement('button'); let textSpan = document.createElement('span'); textSpan.textContent = text; b.appendChild(textSpan); // 使用箭头函数创建闭包来保存 fooParams 并传递给 foo b.addEventListener('click', () => { foo.call(b, ...Object.values(fooParams)); // 使用 call 方法确保 this 指向按钮对象 }); if (id) { b.id = id }; return b; } function genButton(text, foo, id, fooParams = {}) { let b = document.createElement('button'); b.textContent = text; // 使用箭头函数创建闭包来保存 fooParams 并传递给 foo b.addEventListener('click', () => { foo.call(b, ...Object.values(fooParams)); // 使用 call 方法确保 this 指向按钮对象 }); if (id) { b.id = id }; return b; } function genTable(cls, id) { let tb = document.createElement('table'); if (cls) { tb.className = cls }; if (id) { tb.id = id }; return tb; } function genDiv(cls, id) { let d = document.createElement('div'); if (cls) { d.className = cls }; if (id) { d.id = id }; return d; } async function openPanelFunc() { layer.open({ type: 0, // page 层类型 title: '选择数据类型', shade: 0, btn: ['弹幕', '礼物+SC+舰队', '其他'], // 按钮1 的回调 btn1: btn1Fuction, btn2: btn2Fuction, btn3: btn3Fuction }); } function btn1Fuction(index, layero, that) { layui.use(['layer', 'table'], function () { var layer = layui.layer; var table = layui.table; // 使用 layer.open 打开一个新的弹出层 layer.open({ type: 1, // 表示这是一个页面层 title: '弹幕采集', shade: 0, shadeClose: true, // 点击遮罩关闭 area: ['40%', '40%'], // 设置宽度和高度 content: layui.$('#MyTableDiv'), // 显示隐藏的 div 内容 success: function (layero, index) { updateTableData(); renderTable(tableData); timer = setInterval(function () { updateTableData(tableData); table.reloadData('MyTable', { data: tableData }); }, 3000); let tableBtn02 = document.querySelector('#tableBtn02') if (tableBtn02.textContent == '开始') { tableBtn02.className += ' layui-btn-warm'; tableBtn02.textContent = '暂停'; } }, end: function () { if (timer) { clearInterval(timer); timer = undefined; // 清除引用 } } }); /* 渲染弹幕表格*/ function renderTable(data) { table.render({ id: 'MyTable', elem: '#MyTable', data: data, cols: [[ //排序默认是字典序,符合要求 { field: 'time', title: '时间', width: 160, sort: true, fixed: 'left' }, { field: 'name', title: '姓名', width: 120 }, { field: 'content', title: '消息', width: 160 }, { field: 'medal', title: '粉丝牌', width: 80 }, { field: 'medalFrom', title: '牌子主播', width: 80 }, { field: 'level', title: '粉丝牌LV', width: 100 }, { field: 'consumer_level', title: '荣誉LV', width: 100 }, { field: 'score', title: '贡献值', width: 100 }, { field: 'guard_level', title: '身份', width: 80 }, { field: 'reply_is_mystery', title: '匿名', width: 80 }, { field: 'uid', title: 'uid', width: 80 } ]], page: true // 不显示分页 }); } }); return false; } function btn2Fuction(index, layero, that) { layui.use(['layer', 'table'], function () { var layer = layui.layer; var table = layui.table; // 使用 layer.open 打开一个新的弹出层 layer.open({ type: 1, // 表示这是一个页面层 title: '流水采集', shade: 0, shadeClose: true, // 点击遮罩关闭 area: ['40%', '40%'], // 设置宽度和高度 content: layui.$('#MyTableDiv01'), // 显示隐藏的 div 内容 success: function (layero, index) { updateTableData01(); renderTable01(tableData01); timer = setInterval(function () { updateTableData01(); table.reloadData('MyTable01', { data: tableData01 }); }, 3000); let tableBtn02 = document.querySelector('#table01Btn02') if (tableBtn02.textContent == '开始') { tableBtn02.className += ' layui-btn-warm'; tableBtn02.textContent = '暂停'; } }, end: function () { if (timer) { clearInterval(timer); timer = undefined; // 清除引用 } } }); /* 渲染流水表格 */ function renderTable01(data) { table.render({ id: 'MyTable01', elem: '#MyTable01', data: data, cols: [[ //排序默认是字典序,符合要求 { field: 'time', title: '时间', width: 160, sort: true, fixed: 'left' }, { field: 'username', title: '姓名', width: 120 }, { field: 'giftName', title: '礼物', width: 160 }, { field: 'price', title: '价格(分)', width: 80 }, { field: 'num', title: '数量', width: 80 }, { field: 'uid', title: 'uid', width: 100 }, { field: 'guard_level', title: '身份', width: 100 }, { field: 'dmscore', title: '贡献值', width: 100 } ]], page: true // 不显示分页 }); } }); return false; } function btn3Fuction(index, layero, that) { layui.use(['layer'], function () { var layer = layui.layer; layer.open({ type: 1, // 表示这是一个页面层 title: '其他', shade: 0, shadeClose: true, // 点击遮罩关闭 area: ['40%', '40%'], // 设置宽度和高度 content: ` <div class="layui-padding-3" id="MyTableDiv03"> <blockquote class="layui-elem-quote layui-quote-nm"> <span class="layui-font-orange">${wsSubData03.watchedChange}</span> 看过直播 | 更新于: <span class="layui-badge-dot layui-bg-orange"></span> <span class="layui-font-orange">${wsSubData03.watchedChangeDate}</span> </blockquote> <blockquote class="layui-elem-quote layui-quote-nm"> <span class="layui-font-blue">${wsSubData03.clickCount}</span> 直播点赞总数 | 更新于: <span class="layui-badge-dot layui-bg-blue"></span> <span class="layui-font-blue">${wsSubData03.clickCountDate}</span> </blockquote> <blockquote class="layui-elem-quote layui-quote-nm"> <span class="layui-font-green">${wsSubData03.fans}</span> 主播粉丝数量 | 更新于: <span class="layui-badge-dot layui-bg-green"></span> <span class="layui-font-green">${wsSubData03.fansDate}</span> </div> `, success: function (layero, index) { updateTableData02(); timer = setInterval(function () { updateTableData02(); }, 3000); }, end: function () { if (timer) { clearInterval(timer); timer = undefined; // 清除引用 } } }); }); return false; } /* 更新弹幕表格数据 */ function updateTableData(data) { tableData = wsSubTable01Data.toArray(); } /* 更新礼物表格数据 */ function updateTableData01(data) { tableData01 = wsSubTable02Data.toArray(); } /* 更新其他数据 */ function updateTableData02(data) { document.querySelector("#MyTableDiv03 > blockquote:nth-child(1) span:nth-child(1)").textContent = wsSubData03.watchedChange; document.querySelector("#MyTableDiv03 > blockquote:nth-child(1) span:nth-child(3)").textContent = wsSubData03.watchedChangeDate; document.querySelector("#MyTableDiv03 > blockquote:nth-child(2) span:nth-child(1)").textContent = wsSubData03.clickCount; document.querySelector("#MyTableDiv03 > blockquote:nth-child(2) span:nth-child(3)").textContent = wsSubData03.clickCountDate; document.querySelector("#MyTableDiv03 > blockquote:nth-child(3) span:nth-child(1)").textContent = wsSubData03.fans; document.querySelector("#MyTableDiv03 > blockquote:nth-child(3) span:nth-child(3)").textContent = wsSubData03.fansDate; } function tableBtn01Fuc() { layui.use(['layer', 'table'], function () { var layer = layui.layer; var table = layui.table; table.exportFile('MyTable', tableData, { title: '弹幕' + Date.now().toString() }); }); } function table01Btn01Fuc() { layui.use(['layer', 'table'], function () { var layer = layui.layer; var table = layui.table; table.exportFile('MyTable01', tableData01, { title: '流水' + Date.now().toString() }); }); } function tableBtn02Fuc() { let tableBtn02 = document.querySelector('#tableBtn02') if (timer) { clearInterval(timer); timer = undefined; tableBtn02.classList.remove('layui-btn-warm'); tableBtn02.textContent = '开始'; return; } layui.use(['layer', 'table'], function () { var layer = layui.layer; var table = layui.table; timer = setInterval(function () { updateTableData(tableData); table.reloadData('MyTable', { data: tableData }); }, 3000); tableBtn02.className += ' layui-btn-warm'; tableBtn02.textContent = '暂停'; }) } function table01Btn02Fuc() { let table01Btn02 = document.querySelector('#table01Btn02') if (timer) { clearInterval(timer); timer = undefined; table01Btn02.classList.remove('layui-btn-warm'); table01Btn02.textContent = '开始'; return; } layui.use(['layer', 'table'], function () { var layer = layui.layer; var table = layui.table; timer = setInterval(function () { updateTableData01(); table.reloadData('MyTable01', { data: tableData01 }); }, 3000); table01Btn02.className += ' layui-btn-warm'; table01Btn02.textContent = '暂停'; }) } function genPanelButtonAndAppendToDOC() { let myButton = genButtonSpan('crawler', openPanelFunc, 'MyButton'); document.body.appendChild(myButton); } function genBarrageTableAndAppendToDOC() { let myTable = genTable('layui-hide', 'MyTable'); let myTableDiv = genDiv(undefined, 'MyTableDiv'); let tableBtnContainer = genDiv('layui-btn-container', 'tableBtnContainer'); let tableBtn01 = genButton('导出', tableBtn01Fuc, 'tableBtn01'); let tableBtn02 = genButton('暂停', tableBtn02Fuc, 'tableBtn02'); tableBtn01.className = 'layui-btn'; tableBtn01.className += ' layui-btn-sm'; tableBtn02.className = 'layui-btn'; tableBtn02.className += ' layui-btn-sm'; tableBtn02.className += ' layui-btn-warm'; tableBtnContainer.appendChild(tableBtn01); tableBtnContainer.appendChild(tableBtn02); myTableDiv.appendChild(tableBtnContainer); myTableDiv.appendChild(myTable); document.body.appendChild(myTableDiv); } function genGiftTableAndAppendToDOC() { let myTable01 = genTable('layui-hide', 'MyTable01'); let myTableDiv01 = genDiv(undefined, 'MyTableDiv01'); let tableBtnContainer01 = genDiv('layui-btn-container', 'tableBtnContainer01'); let table01Btn01 = genButton('导出', table01Btn01Fuc, 'table01Btn01'); let table01Btn02 = genButton('暂停', table01Btn02Fuc, 'table01Btn02'); table01Btn01.className = 'layui-btn'; table01Btn01.className += ' layui-btn-sm'; table01Btn02.className = 'layui-btn'; table01Btn02.className += ' layui-btn-sm'; table01Btn02.className += ' layui-btn-warm'; tableBtnContainer01.appendChild(table01Btn01); tableBtnContainer01.appendChild(table01Btn02); myTableDiv01.appendChild(tableBtnContainer01); myTableDiv01.appendChild(myTable01); document.body.appendChild(myTableDiv01); } /* 面板按钮 */ genPanelButtonAndAppendToDOC(); /* 弹幕表格 */ genBarrageTableAndAppendToDOC(); /* 礼物+SC+舰队表格 */ genGiftTableAndAppendToDOC(); } function GMaddStyle(css) { var myStyle = document.createElement('style'); myStyle.textContent = css; var doc = document.head || document.documentElement; doc.appendChild(myStyle); } })();