// ==UserScript== // @name 纯净版斗鱼(douyu) // @namespace https://github.com/ljezio // @version 4.2.0 // @description 斗鱼纯净版(douyu.com)。只保留直播和弹幕【斗鱼精简版、斗鱼极简版、斗鱼清爽版】;支持按钮切换关闭脚本;支持自动切换最高画质; // @homepage https://github.com/ljezio/pure-douyu // @author ljezio // @license MIT // @match *://*.douyu.com/0* // @match *://*.douyu.com/1* // @match *://*.douyu.com/2* // @match *://*.douyu.com/3* // @match *://*.douyu.com/4* // @match *://*.douyu.com/5* // @match *://*.douyu.com/6* // @match *://*.douyu.com/7* // @match *://*.douyu.com/8* // @match *://*.douyu.com/9* // @match *://*.douyu.com/topic/* // @match *://*.douyu.com/beta/* // @icon https://www.douyu.com/favicon.ico // @grant GM_addStyle // @downloadURL none // ==/UserScript== const switchKey = 'pure_douyu_switch'; const autoHighestImageKey = 'pure_douyu_auto_highest'; (function () { 'use strict'; window.onload = () => { const buttonGroup = functionButtons(); if (localStorage.getItem(switchKey)) return; restyle(); avoidSmallWindow(); autoFullWindow() .then(() => autoHighestImage()); dbClick(buttonGroup); }; })(); /** * 功能按钮 */ function functionButtons() { const buttonGroup = document.createElement('div'); buttonGroup.style.cssText = 'z-index: 999; position: fixed; top: 0; right: 0;'; document.body.appendChild(buttonGroup); // 开关脚本按钮 const switchButton = document.createElement('button'); switchButton.title = localStorage.getItem(switchKey) ? '启用脚本' : '关闭脚本'; switchButton.innerHTML = ` `; switchButton.onclick = () => { if (localStorage.getItem(switchKey)) { localStorage.removeItem(switchKey); } else { localStorage.setItem(switchKey, 'off'); } location.reload(); }; buttonGroup.appendChild(switchButton); if (!localStorage.getItem(switchKey)) { // 开关自动切换最高画质按钮 const autoHighestImageButton = document.createElement('button'); autoHighestImageButton.title = localStorage.getItem(autoHighestImageKey) ? '开启自动切换最高画质' : '关闭自动切换最高画质'; autoHighestImageButton.innerHTML = ` `; autoHighestImageButton.onclick = () => { if (localStorage.getItem(autoHighestImageKey)) { autoHighestImageButton.title = '关闭自动切换最高画质'; localStorage.removeItem(autoHighestImageKey); } else { autoHighestImageButton.title = '开启自动切换最高画质'; localStorage.setItem(autoHighestImageKey, 'off'); } }; buttonGroup.appendChild(autoHighestImageButton); } // 按钮半透明样式与鼠标悬停透明度变化 [...buttonGroup.children].forEach(button => { button.style.cssText = 'display: block; cursor: pointer; opacity: 0.5; transition: opacity 0.3s ease;'; button.onmouseover = () => button.style.opacity = '1'; button.onmouseout = () => button.style.opacity = '0.5'; }) return buttonGroup; } /** * 调整样式 */ function restyle() { GM_addStyle(` /* 隐藏无用元素 */ header, aside, .wm-general, .bc-wrapper , .RechangeJulyPopups, #js-bottom-left, #bc3, #bc3-bgblur, #js-player-dialog, #js-player-above-controller, #js-layout-fixed-buff, [class^="snapbar__"], [class^="sidebar__"], [class^="title__"], [class^="interactive__"], [class^="toggle__"] { display: none !important; } /* 修改样式 */ #root, #js-player-main { margin: 0 !important; } [class^="stream__"] { bottom: 0 !important; top: 0 !important; } [class^="case__"] { padding: 0 !important; } /* 强制修改伪元素样式 */ #js-player-main::before { content: none !important; } [class^="player__"]::before { padding-top: 0 !important; padding-bottom: ${innerHeight - 16}px !important; } `); } /** * 避免小窗口化 todo */ function avoidSmallWindow() { const observer = new MutationObserver(() => { document.querySelector('#js-player-video-widgets .roomSmallPlayerFloatLayout-closeBtn')?.click(); observer.disconnect(); }); observer.observe(document.querySelector('#js-player-video-case'), { attributes: true, attributeFilter: ['class', 'style'] }); } /** * 自动网页全屏 */ function autoFullWindow() { return new Promise((resolve) => { const fullWindowInterval = setInterval(() => { // 自动网页全屏 if (!controlBar.fullWindow()) return; setTimeout(() => { // 网页全屏可以输入弹幕 document.querySelector('#js-player-main [class^="toggle__"] button')?.click(); }, 10); clearInterval(fullWindowInterval); resolve(); }, 300); }) } /** * 自动切换最高画质 */ function autoHighestImage() { if (localStorage.getItem(autoHighestImageKey)) return; let times = 0; const highestImageInterval = setInterval(() => { if (times++ >= 10) { // 小主播没有画质切换功能 clearInterval(highestImageInterval); return; } const highestImageButton = document.querySelector('#js-player-controlbar [class^="tipItem-"]:nth-child(2) li:first-child'); if (!highestImageButton) return; setTimeout(() => { if (!highestImageButton.className.startsWith('selected-')) { highestImageButton.click(); } }, 5000); clearInterval(highestImageInterval); }, 1000); } /** * 双击全屏 */ function dbClick(buttonGroup) { document.body.ondblclick = event => { event.stopPropagation(); if (!document.fullscreenElement) { controlBar.fullScreen(); } else { document.exitFullscreen().then(); } }; document.onfullscreenchange = () => { if (!document.fullscreenElement) { setTimeout(() => controlBar.fullWindow(), 0); buttonGroup.style.display = 'block'; } else { buttonGroup.style.display = 'none'; } }; } /** * 获取控制栏按钮 */ const controlBar = { fullWindow() { return this._clickControlButton(2) }, fullScreen() { return this._clickControlButton(1) }, _clickControlButton(nthLast) { const parent = '#js-player-controlbar'; const nth = `:nth-last-child(${nthLast})`; const button = document.querySelector(`${parent} [class^="right-"] > ${nth}, ${parent} [class^="right__"] > ${nth}`); if (!button) return false; button.click(); return true; } }