您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
B站播放页自动宽屏、滚动控制、导航显示、带悬浮面板
// ==UserScript== // @name bilibili | b站播放页自动宽屏 // @author izcw // @license MIT // @namespace nana_vao_script // @description B站播放页自动宽屏、滚动控制、导航显示、带悬浮面板 // @version 1.0.4 // @match /^https?://www\.bilibili\.com/video/(BV|av)\w+/ // @include /^https?://(www\.bilibili\.com/(video/(BV|av)|bangumi/play|medialist|list)|bangumi\.bilibili\.com/anime)/ // @run-at document-end // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @grant GM_getResourceURL // @icon https://www.bilibili.com/favicon.ico // ==/UserScript== (function () { 'use strict'; /* 配置管理模块 */ const ConfigManager = { defaultConfig: { pageSettings: [ { name: "普通视频", title: 'video', status: true }, { name: "番剧", title: 'bangumi', status: true }, { name: "收藏夹", title: 'medialist', status: true }, { name: "列表", title: 'list', status: true } ], autoScroll: { // 自动滚动 enabled: false, offset: 100 }, showHeader: false, // 显示导航 burnInProtection: { // 新增防烧屏配置 enabled: true, step: 1, // 单次移动像素 maxOffset: 60, // 最大偏移量 interval: 5000 // 移动间隔(ms) }, listenUrlChange: false // 新增监听 URL 变化配置 }, getConfig() { const savedConfig = GM_getValue('biliConfig', {}); return this.migrateConfig(savedConfig); }, saveConfig(config) { GM_setValue('biliConfig', config); }, migrateConfig(config) { if (config.enabledPages && !config.pageSettings) { config.pageSettings = Object.entries(config.enabledPages).map(([title, status]) => ({ name: this.getPageName(title), title, status })); delete config.enabledPages; } // 确保防烧屏配置合并正确 return { ...this.defaultConfig, ...config, burnInProtection: { ...this.defaultConfig.burnInProtection, ...(config.burnInProtection || {}) } }; }, getPageName(title) { const nameMap = { video: '普通视频', bangumi: '番剧', medialist: '收藏夹', list: '列表' }; return nameMap[title] || title; } }; /* 悬浮控制面板模块 */ const FloatPanel = { panel: null, isExpanded: false, init() { this.createPanel(); this.bindEvents(); this.applyPanelStyles(); }, createPanel() { const config = ConfigManager.getConfig(); this.panel = document.createElement('div'); this.panel.id = 'bili-auto-wide-panel'; this.panel.innerHTML = ` <div class="config-content"> <div class="header"> <h3>bilibili播放页增强设置</h3> <button class="close-btn-tool">×</button> </div> <div class="config-section"> <h4>宽屏-页面类型(只有在勾选的视频类型才触发)</h4> <div class="config-items config-items-type"> ${config.pageSettings.map(item => `<label> <input type="checkbox" data-type="page" data-title="${item.title}" ${item.status ? 'checked' : ''}> ${item.name} </label>` ).join('')} </div> </div> <div class="config-section"> <h4>界面显示</h4> <div class="config-items"> <label> <input type="checkbox" data-type="showHeader" ${config.showHeader ? 'checked' : ''}> 显示顶部导航条 </label> </div> </div> <div class="config-section"> <h4>自动滚动</h4> <div class="config-items"> <label> <input type="checkbox" data-type="autoScroll" ${config.autoScroll.enabled ? 'checked' : ''}> 页面自动滚动(0-1000): <input type="number" class="number-input" value="${config.autoScroll.offset}" min="0" max="1000" step="10"> px </label> <label> <input type="checkbox" data-type="listenUrlChange" ${config.listenUrlChange ? 'checked' : ''}> 切换视频也执行滚动 </label> </div> </div> <div class="config-section"> <h4>其它</h4> <div class="config-items"> <label> <input type="checkbox" data-type="burnInProtection" ${config.burnInProtection.enabled ? 'checked' : ''}> 启用面板防烧屏保护 </label> </div> </div> <div class="footer"> <button class="reset-btn">恢复默认</button> <button class="save-btn">保存配置</button> </div> <div class="other"> <a href="https://www.zhangchengwei.work/message" target="_blank" rel="帮助" title="帮助">帮助</a> <a href="https://github.com/izcw/bilibili-AutoWidescreen" target="_blank" rel="Github" title="Github">Github</a> </div> </div> `; setTimeout(() => { document.getElementById('mirror-vdcon').append(this.panel); }, 3000); }, applyPanelStyles() { GM_addStyle(` #mirror-vdcon { position: relative; } #bili-auto-wide-panel { position: absolute; top: 0; right: 20px; width: 30px; height: 14px; border-radius: 0 0 6px 6px; box-shadow: 0 0px 12px #00000030; background: #00AEEC; cursor: pointer; transition: transform 1s ease-in-out; /* 平滑移动动画 */ overflow: hidden; z-index: 100; } #bili-auto-wide-panel.expanded { width: 320px; height: auto; max-height: 90vh; border-radius: 8px; background: #fff; } .config-content { display: none; padding: 15px; } #bili-auto-wide-panel.expanded .config-content { display: block; } .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .header h3{ font-size: 14px; } .close-btn-tool { width: 30px; height: 30px; background: none; border: none; font-size: 24px; cursor: pointer; color: #666; border-radius: 6px; box-sizing: border-box; } .close-btn-tool:hover{ background: #EFEFEF; } .config-section { margin-bottom: 1.5rem; } .config-section h4 { margin: 0 0 10px 0; color: #00A1D6; border-bottom: 1px solid #eee; padding: 4px 0; } .config-items { display: flex; flex-direction: column; gap: 8px; color: #444; padding: 0 10px; } .config-items label { display: flex; align-items: center; gap: 6px; cursor: pointer; } .config-items-type{ flex-direction: row; flex-wrap: wrap; } .config-items-type label{ width: 120px; } .number-input { width: 80px; padding: 4px; border: 1px solid #00A1D6; } .footer { margin-top: 15px; text-align: right; } .reset-btn { padding: 6px 20px; background: #EAEDF2; color: #333; border: none; border-radius: 4px; cursor: pointer; margin-right: 10px; } .save-btn { padding: 6px 20px; background: #00a1d6; color: white; border: none; border-radius: 4px; cursor: pointer; } .other a{ color:#999; padding-right: 4px; } a:hover{ color: #00A1D6; } `); }, bindEvents() { this.panel.addEventListener('click', (e) => { if (!this.isExpanded && e.target === this.panel) { this.expandPanel(); } }); this.panel.querySelector('.close-btn-tool').addEventListener('click', (e) => { e.stopPropagation(); this.collapsePanel(); }); this.panel.querySelector('.save-btn').addEventListener('click', () => { this.saveConfig(); }); this.panel.querySelector('.reset-btn').addEventListener('click', () => { this.resetConfig(); }); }, expandPanel() { this.isExpanded = true; this.panel.classList.add('expanded'); }, collapsePanel() { this.isExpanded = false; this.panel.classList.remove('expanded'); }, saveConfig() { const config = ConfigManager.getConfig(); // 1. 保存页面类型勾选状态 config.pageSettings = Array.from(this.panel.querySelectorAll('input[data-type="page"]')).map(input => ({ title: input.dataset.title, status: input.checked, // 读取勾选状态 name: ConfigManager.getPageName(input.dataset.title) })); // 2. 保存防烧屏设置 const burnInCheckbox = this.panel.querySelector('input[data-type="burnInProtection"]'); config.burnInProtection = { ...config.burnInProtection, // 保留原有参数(step/maxOffset等) enabled: burnInCheckbox.checked // 新状态覆盖旧值 }; // 3. 保存监听 URL 变化设置 const listenUrlChangeCheckbox = this.panel.querySelector('input[data-type="listenUrlChange"]'); config.listenUrlChange = listenUrlChangeCheckbox.checked; // 4. 原有逻辑(自动滚动和导航显示) const inputValue = this.panel.querySelector('.number-input').value; let offset = Number(inputValue); if (isNaN(offset) || offset < 0 || offset > 1000) offset = 0; config.autoScroll = { enabled: this.panel.querySelector('input[data-type="autoScroll"]').checked, offset: offset }; config.showHeader = this.panel.querySelector('input[data-type="showHeader"]').checked; // 5. 保存并刷新 ConfigManager.saveConfig(config); this.collapsePanel(); setTimeout(() => location.reload(), 300); }, resetConfig() { // 恢复默认配置 ConfigManager.saveConfig(ConfigManager.defaultConfig); this.collapsePanel(); setTimeout(() => location.reload(), 300); } }; /* 核心功能模块 */ const Core = { init() { const config = ConfigManager.getConfig(); this.toggleHeader(config.showHeader); if (this.shouldEnable()) { // 仅在勾选类型中触发以下功能 this.toggleHeader(config.showHeader); this.autoWidescreen(() => { this.handleAutoScroll(config); }); } else { // 非勾选类型时恢复默认 this.toggleHeader(true); window.scrollTo(0, 0); } if (config.burnInProtection.enabled) { this.startBurnInProtection(); } // 监听 URL 变化 if (config.listenUrlChange) { this.listenUrlChange(); } }, shouldEnable() { const pageType = this.getPageType(); const config = ConfigManager.getConfig(); return config.pageSettings.some(item => item.title === pageType && item.status ); }, getPageType() { const path = location.pathname; if (path.includes('/video/')) return 'video'; if (path.includes('/bangumi/')) return 'bangumi'; if (path.includes('/medialist/')) return 'medialist'; if (path.includes('/list/')) return 'list'; }, autoWidescreen(callback) { new MutationObserver((_, observer) => { const btn = document.querySelector('.bpx-player-ctrl-wide, .bilibili-player-wide-btn'); if (btn) { btn.click(); observer.disconnect(); if (typeof callback === 'function') callback(); } }).observe(document.body, { subtree: true, childList: true }); }, toggleHeader(show) { const header = document.querySelector('#biliMainHeader'); if (header) { header.style.display = show ? 'block' : 'none'; } }, handleAutoScroll(config) { if (config.autoScroll.enabled) { window.scrollTo(0, config.autoScroll.offset); } }, startBurnInProtection() { const config = ConfigManager.getConfig().burnInProtection; let currentOffset = 0; let direction = 1; // 1=左移,-1=右移 let animationInterval; const stopAnimation = () => { if (animationInterval) { clearInterval(animationInterval); animationInterval = null; } }; const startAnimation = () => { stopAnimation(); animationInterval = setInterval(() => { // 边界检查前先计算下一步偏移量 const nextOffset = currentOffset + direction * config.step; // 超过最大偏移时反转方向,并修正为最大值 if (nextOffset > config.maxOffset) { currentOffset = config.maxOffset; direction = -1; } // 低于最小偏移时反转方向,并修正为最小值 else if (nextOffset < 0) { currentOffset = 0; direction = 1; } // 正常范围时直接更新 else { currentOffset = nextOffset; } FloatPanel.panel.style.transform = `translateX(-${currentOffset}px)`; }, config.interval); }; startAnimation(); window.addEventListener('popstate', () => { stopAnimation(); currentOffset = 0; // 重置偏移量 direction = 1; // 新增:重置方向 startAnimation(); }); }, listenUrlChange() { const config = ConfigManager.getConfig(); let lastUrl = location.href; setInterval(() => { const currentUrl = location.href; if (currentUrl !== lastUrl) { lastUrl = currentUrl; this.handleUrlChange(config); } }, 500); // 每 500ms 检查一次 URL 变化 }, handleUrlChange(config) { // URL 变化时仅执行自动滚动 if (config.autoScroll.enabled) { window.scrollTo(0, config.autoScroll.offset); } } }; // 初始化 FloatPanel.init(); Core.init(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址