您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
增强B站功能,B站小窗口视频的操作栏显示
// ==UserScript== // @name B站小窗口视频功能显示 // @description 增强B站功能,B站小窗口视频的操作栏显示 // @version 0.0.5 // @author Grant Howard, Coulomb-G // @copyright 2024, Grant Howard // @license MIT // @match *://*.bilibili.com/video/* // @match *://*.bilibili.com/bangumi/play/* // @exclude *://api.bilibili.com/* // @exclude *://api.*.bilibili.com/* // @exclude *://*.bilibili.com/api/* // @exclude *://member.bilibili.com/studio/bs-editor/* // @exclude *://t.bilibili.com/h5/dynamic/specification // @exclude *://bbq.bilibili.com/* // @exclude *://message.bilibili.com/pages/nav/header_sync // @exclude *://s1.hdslb.com/bfs/seed/jinkela/short/cols/iframe.html // @exclude *://open-live.bilibili.com/* // @run-at document-start // @grant unsafeWindow // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_info // @grant GM_xmlhttpRequest // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @grant GM_addStyle // @connect raw.githubusercontent.com // @connect github.com // @connect cdn.jsdelivr.net // @connect cn.bing.com // @connect www.bing.com // @connect translate.google.cn // @connect translate.google.com // @connect localhost // @connect * // @icon https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/images/logo-small.png // @icon64 https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/images/logo.png // @namespace https://greasyfork.org/users/734541 // ==/UserScript== (() => { GM_addStyle(` #commenBoxBody{ position: fixed; z-index: 100; bottom: 5px; left: 0; width:300px; height: 32px; background: transparent; padding: 0; } `); const console = (() => { const _console = window.console; return { log: (...args) => { _console.log( `%c ZAIZAI `, 'padding: 2px 1px; border-radius: 3px; color: #fff; background: #42c02e; font-weight: bold;', ...args, ); }, }; })(); function waitTime(callback, options = { time: 500, isSetup: false }) { let timeout = null; return new Promise((resolve) => { if (options.isSetup) { let res = callback(); if (res) resolve(res); } timeout = setInterval(() => { let res = callback(); if (res) { clearInterval(timeout); resolve(res); } }, options.time); }); } /** * 创建一个节流函数 * @param {Function} func 需要节流的函数 * @param {number} wait 函数执行的最小时间间隔 * @param {boolean} [options={leading=true, trailing=true}] 配置对象 * @returns {Function} 节流后的函数 */ function throttle(func, wait, options = {}) { let timeout = null; let context, args; let previousNow = 0; const { leading = true, trailing = true } = options; function wrapper() { // Save the context and arguments context = this; args = arguments; const previous = previousNow; const remaining = wait - (Date.now() - previous); const now = Date.now(); if (remaining <= 0 || remaining > wait) { // 如果当前调用距离上次调用超过了wait时间,则立即执行 clearTimeout(timeout); timeout = null; func.apply(context, args); previousNow = now; } else if (!timeout && trailing) { // 如果设置了trailing,则在wait时间结束时执行 timeout = setTimeout(() => { func.apply(context, args); previousNow = now; }, remaining); } if (leading && !timeout) { // 如果设置了leading,则在第一次调用时立即执行 func.apply(context, args); previousNow = now; } } return wrapper; } console.log('B站小窗口视频功能显示'); const state = { is: false, }; const onMouseover = async () => { if (state.is) { return; } state.is = true; const els = await waitTime( () => { const bpxplayercontrolmask = document.querySelector('.bpx-player-control-mask'); const bpxplayercontrolentity = document.querySelector('.bpx-player-control-entity'); const bpxplayercontrolbottom = document.querySelector('.bpx-player-control-bottom'); if (bpxplayercontrolmask && bpxplayercontrolentity && bpxplayercontrolbottom) { return [bpxplayercontrolmask, bpxplayercontrolentity, bpxplayercontrolbottom]; } }, { time: 0, }, ); els[0].style.opacity = 1; els[0].style.display = 'block'; els[1].style.opacity = 1; els[1].style.display = 'block'; els[2].style.opacity = 1; els[2].style.display = 'flex'; console.log('onMouseover 显示'); console.log(els); }; const onMouseout = async (e) => { if (!state.is && e.tae) { return; } state.is = false; const els = await waitTime( () => { const bpxplayercontrolmask = document.querySelector('.bpx-player-control-mask'); const bpxplayercontrolentity = document.querySelector('.bpx-player-control-entity'); const bpxplayercontrolbottom = document.querySelector('.bpx-player-control-bottom'); if (bpxplayercontrolmask && bpxplayercontrolentity && bpxplayercontrolbottom) { return [bpxplayercontrolmask, bpxplayercontrolentity, bpxplayercontrolbottom]; } }, { time: 0, }, ); els[0].style.opacity = 0; els[0].style.display = 'none'; els[1].style.opacity = 0; els[1].style.display = 'none'; els[2].style.opacity = 0; els[2].style.display = 'none'; console.log('onMouseout 隐藏'); console.log(els); }; const addCommentBoxButton = async () => { if (document.querySelector('#zaizai_commentBox')) { console.log('已经添加了评论框按钮'); return; } const elBut = await waitTime(() => { let button = document.querySelector('.bpx-player-ctrl-btn.bpx-player-ctrl-playbackrate'); let commentBox = document.querySelector('.bpx-player-video-inputbar'); if (button && commentBox) { button = button.cloneNode(true); button.children[0].textContent = '框'; button.id = 'zaizai_commentBox'; commentBox = commentBox.cloneNode(true); commentBox.querySelector('.bpx-player-video-btn-dm').remove(); commentBox.querySelector('.bpx-player-video-preview-emoji-wrap').remove(); commentBox.querySelector('.bpx-player-dm-hint').remove(); // 隐藏按钮 const hiheEl = document.createElement('div'); hiheEl.classList.add('bpx-player-video-btn-dm'); hiheEl.style.color = '#000'; hiheEl.style.lineHeight = '25px'; hiheEl.textContent = '隐藏'; commentBox.prepend(hiheEl); // 容器 const commenBoxBody = document.createElement('div'); commenBoxBody.id = 'commenBoxBody'; commenBoxBody.classList.add('bpx-player-sending-bar'); commenBoxBody.style.display = 'none'; commenBoxBody.style.padding = '0'; commenBoxBody.appendChild(commentBox); const sendBut = commentBox.querySelector('.bpx-player-dm-btn-send'); const inputEl = commentBox.querySelector('.bpx-player-dm-input'); return [button, commenBoxBody, hiheEl, sendBut, inputEl]; } }); elBut[0].addEventListener('click', () => { let display = elBut[1].style.display; elBut[1].removeAttribute('tsbrowser_force_hidden'); if (display === 'none') { elBut[1].style.display = 'block'; elBut[1].style.zIndex = 9999; elBut[1].style.left = (document.body.getBoundingClientRect().width - 300) / 2 + 'px'; } else { elBut[1].style.display = 'none'; } }); elBut[2].addEventListener('click', () => { elBut[1].style.display = 'none'; }); elBut[3].addEventListener('click', () => { const value = elBut[4].value; const playerInput = document.querySelector('#bilibili-player .bpx-player-dm-input'); playerInput.focus(); document.execCommand('insertText', false, value); document.querySelector('#bilibili-player .bpx-player-dm-btn-send').click(); elBut[4].value = ''; elBut[3].classList.add('bui-disabled'); elBut[3].children[0].textContent = '0'; let timeout = null; let count = 1; timeout = setInterval(() => { count++; if (count >= 6) { elBut[3].classList.remove('bui-disabled'); elBut[3].children[0].textContent = '发送'; clearTimeout(timeout); } else { elBut[3].children[0].textContent = count; } }, 1000); }); document.body.appendChild(elBut[1]); document.querySelector('.bpx-player-control-bottom-right').prepend(elBut[0]); }; window.onload = () => { window.addEventListener('resize', async () => { const { innerWidth, innerHeight } = window; if (innerWidth <= 565 && innerHeight <= 320) { window.addEventListener('mouseover', onMouseover); window.addEventListener('mouseout', onMouseout); addCommentBoxButton(); } else if (innerWidth > 565 && innerHeight > 320) { window.removeEventListener('mouseover', onMouseover); window.removeEventListener('mouseout', onMouseout); state.is = false; /** * 放大后清空 style 不然b站原本的css不会生效 */ const els = await waitTime( () => { const bpxplayercontrolmask = document.querySelector('.bpx-player-control-mask'); const bpxplayercontrolentity = document.querySelector('.bpx-player-control-entity'); const bpxplayercontrolbottom = document.querySelector('.bpx-player-control-bottom'); if (bpxplayercontrolmask && bpxplayercontrolentity && bpxplayercontrolbottom) { return [bpxplayercontrolmask, bpxplayercontrolentity, bpxplayercontrolbottom]; } }, { time: 0, }, ); els.forEach((item) => { item.style.cssText = ''; }); } if (innerWidth <= 520) { document.querySelector('.bpx-player-ctrl-time').style.display = 'none'; document.querySelector('.bpx-player-ctrl-quality').style.display = 'none'; } else { document.querySelector('.bpx-player-ctrl-time').style.display = 'block'; document.querySelector('.bpx-player-ctrl-quality').style.display = 'block'; } }); }; })();