调整bilibili 分P视频合集列表,使得可以根据窗口大小上下铺满,标题显示得更长;适配了宽屏显示;支持小窗大小设置;支持右侧视频列表自定义宽度;支持视频列表标题换行显示;以及一些其他的调整
- // ==UserScript==
- // @name B站|bilibili 分P视频详情页优化
- // @license MIT
- // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAAyZJREFUaEPtWlFy2jAQ3XXof5pewJkpmekpAidJ+IQeAnKIwifkJDin6EzoTNwDlOYA4O2sVIEsFFuSkQdm8CfI0r6VdvftkxHO/MEQ+7/8eH3cJtvsffgtD3nf9s71bNV7H3Yz3/m8AdzMVmMgmPBCBW5um4K4nv1MkTpzBOgBwmQ97D75gPAHMH19A8BULdIEBBufUOdtbzDl69HdbVQActGrZVMQh8bzjkLf9xh57wB7xwYCiQZ/vt8tXLx3LON5rSAATUBwsCYESx1oiOfV+8EAQkAcGk95gTjwPTY6+AMAYhHAByJKEWgXrNVHYx/Uchx9kF7NcXIsAdamY0TICtg8m1mvBODzdLUU6eyEHzPWdgDOwfidX7V6IQDoxemEnV827T8ItKW0cwHBRRQ/8j6fNeY7pwGmkyZEc714ihpANMCb2a85ED2WDfUv6bGB2uoHIC7QGrwBpCo2ABGr0xXp6xBAdgHQhufVGpcdqPK2T5fGqRugkwJscp+G6Gg7wMYKFpMk90BFT6U3V0qtp24ORJESBdeBlypQwQBEsYNPY91Y624gLtbDr4O6uKiv/JLgEW4G+g41A1Bq/ewmsjf/jrr9OgCuvGs96pbIZjAAmYPLvXDJSMQF02Is6LdLVyYpO9wTQU9SdjvNNvvjZgBExS56gEmGRfGyTZjD+wVh1c4cgBLHsaxQNAJQdyza+P8CoA0vV61x2YGQHeCi55KZXOaOvgMmnVAFS5cfFY0IkVKiAmDjCXEu6gHBk6QZWqOEMOE6IceECcNRAezFATZaFSbKuW6YFMSVM5nHKjoAXlAVJPa2ukNQvwnPW8Qpl/N/6chcvRRzXCtHqE0AImFYZRVHXh/TWHNuqwDHmW2f/kqCRV7gtu/T7sUGY22CGEAV1xe6C9ZL37GNl1K/qZpL8e38xV3lPbvEGNu3YfPrrWu557TqpGGLxHrL7LutV0xIMG73poavpA77YiW5sDM4FgugZ5MEOl3yWZVhOJ6Cbc2EjgKzEwBbpmpyNWo7Xqbq4foFgDMARdSuCkqP/aGHnJvFs86DTgJd4sgLgMuEbY/5B0Ybna/xpe4TAAAAAElFTkSuQmCC
- // @namespace https://sumver.cn
- // @version 1.4.1
- // @description 调整bilibili 分P视频合集列表,使得可以根据窗口大小上下铺满,标题显示得更长;适配了宽屏显示;支持小窗大小设置;支持右侧视频列表自定义宽度;支持视频列表标题换行显示;以及一些其他的调整
- // @author lonelylizard
- // @match https://www.bilibili.com/video/*
- // @match https://www.bilibili.com/list/*
- // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
- // @grant GM_addStyle
- // @grant GM_registerMenuCommand
- // @grant GM_setValue
- // @grant GM_getValue
- // @grant GM_listValues
- // @grant GM_deleteValue
- // @run-at document-end
- // ==/UserScript==
- // 样式处理
- const setStyle = function (css) {
- let css_list = css.split("}")
- css_list.forEach((item, index, array) => {
- GM_addStyle(item + "}")
- });
- }
- // 控制菜单
- // 视频列表标题换行开关
- const menu_title_wrap_status = GM_registerMenuCommand("3、视频列表标题换行开关", function () {
- let cur_choose = window.confirm("使得右侧视频合集支持标题换行显示\n当前状态:\n" + (GM_getValue("title_wrap_status") === true ? "已开启" : "已关闭") +
- "\n\n按【确认】修改状态,按【取消】保持设置不变\n\n设置后请手动刷新一次网页");
- if (cur_choose) {
- if (GM_getValue("title_wrap_status")) {
- GM_setValue("title_wrap_status", false)
- } else {
- GM_setValue("title_wrap_status", true)
- }
- }
- });
- // 宽屏适配开关
- const menu_widescreen_status = GM_registerMenuCommand("1、宽屏适配开关", function () {
- let cur_choose = window.confirm("当前宽屏适配状态:\n" + (GM_getValue("widescreen_status") === true ? "已开启" : "已关闭") +
- "\n\n按【确认】修改状态,按【取消】保持设置不变\n注:只有在【视频合集宽度调整】未开启或设置为0时,宽屏模式才会生效\n设置后请手动刷新一次网页\n 开启该功能后,与B站视频播放器右下角的【宽屏模式】【网页全屏】会有冲突导致画面展示有可能混乱,请不要同时使用");
- if (cur_choose) {
- if (GM_getValue("widescreen_status")) {
- GM_setValue("widescreen_status", false)
- } else {
- GM_setValue("widescreen_status", true)
- }
- }
- });
- // 小窗尺寸设置开关
- // const miniwin_status = GM_registerMenuCommand("2、小窗尺寸设置", function () {
- // window.prompt("小窗功能已从本脚本移除,升级为全站小窗设置脚本,如有需要请手动复制以下的链接前往查看","https://greasyfork.org/zh-CN/scripts/494837")
- // });
- // 视频合集列表比例调整开关
- const menu_area_ratio = GM_registerMenuCommand("4、视频合集列表宽度调整", function () {
- let area_ratio_prompt = window.prompt("输入0.5表示视频列表占屏幕一半,输入0.25表示占屏幕1/4,\n当前比率:\n" + (GM_getValue("area_ratio") != 0 && typeof (GM_getValue(
- "area_ratio")) != 'undefined' ? GM_getValue("area_ratio") : "未设置") +
- "\n\n按【确认】修改状态,按【取消】保持设置不变\n如设置导致页面混乱,请输入0还原页面\n\n注意:该功能开启时,宽屏模式会自动关闭\n设置后请手动刷新一次网页\n 开启该功能后,与B站视频播放器右下角的【宽屏模式】【网页全屏】会有冲突导致画面展示有可能混乱,请不要同时使用");
- if (typeof (Number(area_ratio_prompt)) === 'number') {
- if (area_ratio_prompt.toString()
- .split('.')
- .pop()
- .length <= 2) {
- GM_setValue("area_ratio", area_ratio_prompt)
- }
- }
- });
- // 默认开启,去除菜单
- // // 非分P视频页支持宽屏、自定义比例开关 (即普通视频播放页)
- // const no_videos_list_support = GM_registerMenuCommand("5、让非分P视频页支持宽屏、自定义比例开关", function () {
- // let cur_choose = window.confirm("让普通的视频播放页(没有视频合集),也按照宽屏或自定义比例进行显示\n当前状态:\n" + (GM_getValue("no_videos_list_support_status") === true ? "已开启" :
- // "已关闭") + "\n\n该功能需要【视频合集列表宽度调整】或【宽屏适配开关】开启状态才生效\n按【确认】修改状态,按【取消】保持设置不变\n设置后请手动刷新一次网页");
- // if (cur_choose) {
- // if (GM_getValue("no_videos_list_support_status")) {
- // GM_setValue("no_videos_list_support_status", false)
- // } else {
- // GM_setValue("no_videos_list_support_status", true)
- // }
- // }
- // });
- // 自定义视频合集列表高度
- const menu_right_content_height = GM_registerMenuCommand("6、自定义视频合集列表高度", function () {
- let area_height_ratio_prompt = window.prompt("输入0.5表示占列表区域高度占屏幕高度一半,输入0.8表示占屏幕高度80%,\n当前比率:\n" + (GM_getValue("area_height_ratio") != 0 && typeof (GM_getValue(
- "area_height_ratio")) != 'undefined' ? GM_getValue("area_height_ratio") : "未设置") +
- "\n\n按【确认】修改状态,按【取消】保持设置不变\n如设置导致页面混乱,请输入0还原页面\n\n注意:设置的高度不包含标题,所以假如你希望右侧高度有一半用来显示推荐视频,那么设置值大概为0.3");
- if (typeof (Number(area_height_ratio_prompt)) === 'number') {
- if (area_height_ratio_prompt.toString()
- .split('.')
- .pop()
- .length <= 2) {
- GM_setValue("area_height_ratio", area_height_ratio_prompt)
- }
- }
- });
- // 重置脚本,删除所有设置,防止先后版本逻辑错误导致的设置不生效或出现错误的问题
- const reset_btn = GM_registerMenuCommand("7、重置脚本全部设置", function () {
- let cur_choose = window.confirm("重置该脚本的所有设置,通常只有在脚本运作发生混乱的情况下使用。");
- if (cur_choose) {
- const keys = GM_listValues();
- keys.forEach(element => {
- GM_deleteValue(element);
- });
- }
- });
- (function () {
- 'use strict';
- // 屏蔽广告
- let no_ad_fn = function () {
- let css =
- `#slide_ad {
- display: none
- }
- /* 去除右侧广告 */
- .ad-report {
- display: none !important;
- min-width: 0px !important;
- min-height: 0px !important
- }
- /* 去除简介下广告 */
- #activity_vote {
- display: none !important
- }
- /* 去除右下角直播窗口 */
- .pop-live-small-mode {
- display: none !important
- }
- /* 去除右侧游戏广告卡片 */
- .video-page-game-card-small {
- display: none !important
- }
- /* 去除视频下方的广播广告 */
- .reply-notice {
- display: none !important
- }`
- setStyle(css)
- }
- no_ad_fn()
- // 创建一个观察器实例并传入回调函数
- const observer = new MutationObserver((mutations) => {
- const targetElement = document.querySelector('.video-pod__body');
- if (targetElement) {
- fn1();
- // 当找到目标元素后停止观察
- // observer.disconnect();
- }
- });
- // 配置观察选项:
- const config = {
- attributes: false,
- childList: true,
- subtree: true
- };
- // 选择需要观察变动的节点
- const targetNode = document.body;
- // 开始观察目标节点
- observer.observe(targetNode, config);
- // 开始之前检查元素是否已经存在
- const existingElement = document.querySelector('.video-pod__body');
- if (existingElement) {
- observer.disconnect(); // 如果元素已经存在,则不需要继续观察
- }
- // 2024-10月B站对页面逻辑进行了改写,现在不需要区分那么多类型的合集了
- let fn1 = function () {
- if (document.querySelector(".video-pod")) {
- if (document.querySelector(".video-pod__body")) {
- change_title_wrap("fn1")
- let list_height = document.querySelector(".video-pod__list")
- .scrollHeight;
- let res_height = window.innerHeight;
- let right_content_top_heigt = document.querySelector(".video-pod__body")
- .offsetTop;
- let right_content_head = document.querySelector(".video-pod__header").offsetHeight;
- let dif_height = res_height - right_content_top_heigt -80;
- // 初始化,如果存在按用户设置的高度值,则优先使用用户设置,否则则给默认值
- let list_max_height
- if(GM_getValue("area_height_ratio") && GM_getValue("area_height_ratio") != 0){
- list_max_height = Math.round(res_height*GM_getValue("area_height_ratio"))
- }else{
- list_max_height = 1000
- }
- // 判断小节是否展开
- let viewpoint_status = false
- if (document.querySelector(".bpx-player-viewpoint")) {
- if (document.querySelector(".bpx-player-viewpoint")
- .getAttribute('fold') == 'true') {
- viewpoint_status = true
- }
- }
- // 没有字幕插件、没有小节,那就正常显示
- if (!document.querySelector(".transcript-box") && viewpoint_status == false) {
- if (list_height > dif_height) {
- // 计算列表高度,如果达不到一屏就不铺满
- let css =
- `.video-pod__body {
- height: ${dif_height}px !important;
- max-height: ${list_max_height}px !important
- }`
- setStyle(css)
- } else {
- // 如果高度小于一屏,同时开始换行功能,会导致高度不正确,这里修改为去除高度属性,让其自适应
- let css =
- `.video-pod__body {
- height: unset !important;
- max-height: ${list_max_height}px !important
- }`
- setStyle(css)
- }
- } else {
- // 兼容脚本:在侧边显示 Bilibili 视频字幕/文稿(原始版)
- // 兼容小节列表
- if (list_height > res_height) {
- let css =
- `.video-pod__body {
- height: ${res_height - 280}px !important;
- max-height: ${list_max_height}px !important
- }`
- setStyle(css)
- } else {
- let css =
- `.video-pod__body {
- height: unset !important;
- max-height: ${list_max_height}px !important
- border-width:2px !important
- }`
- setStyle(css)
- }
- }
- // 兼容 Bilibili Evolved中的黑夜模式,检测到开启了黑夜模式则禁用样式,避免合集字体一片黑
- if(!document.querySelector("#dark-mode-important")){
- let css =
- `
- /* 普通视频合集、带分类视频合集 */
- .video-pod .video-pod__header .header-top .left .title{
- display:unset !important
- }
- .pod-item.simple:hover{
- background: #DCE2E3;
- border-radius: 4px !important
- }
- /*去除蓝色字体*/
- .single-p:hover,.title-txt,.single-p:hover .title{
- color:#000 !important
- }
- /* 分P视频合集 */
- .simple-base-item.normal:hover{
- background: #DCE2E3;
- border-radius: 4px !important
- }
- .simple-base-item.normal:hover{
- color:#000 !important
- }
- /* 带封面的视频合集、带封面且带分类的视频合集 */
- .pod-item.normal:hover{
- background: #DCE2E3;
- border-radius: 4px !important
- }
- `
- setStyle(css)
- }
- }
- }
- };
- // 宽屏适配+自定义设置比率
- let change_right_width = function (source) {
- // 如果有自定义比率,则优先使用
- if (GM_getValue("area_ratio") && GM_getValue("area_ratio") != 0) {
- let body_width = document.querySelector("#app")
- .offsetWidth;
- let res_width = window.innerWidth;
- var dif_width = Math.round(res_width * GM_getValue("area_ratio"));
- let player_banner_height = document.querySelector(".bpx-player-sending-bar")
- .offsetHeight;
- // 播放全部视频合集和普通无合集视频,一起调整
- if (document.querySelector(".playlist-container--left")) {
- let css =
- `
- @media (min-width: 1681px) {
- .playlist-container .playlist-container--right {
- width: ${dif_width}px !important;
- }
- }
- .playlist-container .playlist-container--right{
- width: ${dif_width}px !important;
- }
- `
- setStyle(css)
- }
- // 专栏视频合集
- if (document.querySelector(".left-container")) {
- let css =
- `
- @media (min-width: 1681px) {
- .video-container-v1 .right-container {
- width: ${dif_width}px !important;
- }
- }
- .video-container-v1 .right-container{
- width: ${dif_width}px !important;
- }
- `
- setStyle(css)
- }
- } else if (GM_getValue("widescreen_status")) {
- let body_width = document.querySelector("#app")
- .offsetWidth;
- let res_width = window.innerWidth;
- if (res_width - 100 > body_width) {
- //带鱼屏
- let left_div = document.querySelector(".left-container")
- .offsetWidth;
- let right_div = document.querySelector(".right-container")
- .offsetWidth;
- var dif_width = (body_width - (left_div + right_div)) + right_div - 100;
- } else {
- //非带鱼屏
- let left_div = document.querySelector(".left-container")
- .offsetWidth;
- let right_div = document.querySelector(".right-container")
- .offsetWidth;
- var dif_width = (res_width - (left_div + right_div)) + right_div - 80;
- }
- // 没有参数即为普通视频页
- if (!source) {
- let css = `.right-container {
- width: ${dif_width}px !important
- }`
- setStyle(css)
- }
- }
- }
- // 支持自定义视频合集(如UP空间-播放全部、收藏夹-播放全部)
- let no_videos_list_change_right_width = function () {
- if (document.querySelector(".playlist-container--left")) {
- // 计算列表高度,如果达不到一屏就不铺满
- let list_height = document.querySelector(".action-list-inner")
- .scrollHeight;
- let res_height = window.innerHeight;
- var right_content_top_heigt = document.querySelector(".action-list-container")
- .offsetTop;
- var dif_height = res_height - right_content_top_heigt - 10;
- if (!document.querySelector(".transcript-box")) {
- if (list_height > dif_height) {
- let css =
- `.action-list-container {
- height: ${dif_height}px !important;
- max-height: 1000px !important
- }
- #playlist-video-action-list{
- max-height:1000px !important
- }
- .playlist-video-action-list-body,.action-list-body-bottomaction-list-body-bottom,playlist-video-action-list{
- height:100% !important
- }`
- setStyle(css)
- } else {
- let css =
- `.action-list-container {
- height: unset !important;
- max-height: 1000px !important
- }
- #playlist-video-action-list-body,#playlist-video-action-list{
- max-height: 1000px !important
- }`
- setStyle(css)
- }
- } else {
- // 兼容脚本:在侧边显示 Bilibili 视频字幕/文稿(原始版)
- if (list_height > res_height) {
- let css =
- `.action-list-container {
- height: ${res_height - 280}px !important;
- max-height: 1000px !important
- }`
- setStyle(css)
- } else {
- let css =
- `.action-list-container {
- height: unset !important;
- max-height: 1000px !important
- }`
- setStyle(css)
- }
- }
- let css =
- `/* 增加聚焦效果 */
- .action-list-item:hover {
- background: #DCE2E3;
- border-radius: 6px !important;
- }
- /* 去除蓝色字体提醒 */
- .action-list-item:hover .title {
- color: #000 !important
- }`
- setStyle(css)
- }
- }
- // 非视频合集的播放页这次自定义比例、宽屏模式
- let support_no_video_list = function () {
- if (GM_getValue("no_videos_list_support_status")) {
- change_right_width()
- }
- }
- // 视频合集换行功能,不限制标题行数
- let change_title_wrap = function (source) {
- if (GM_getValue("title_wrap_status")) {
- if (source == "fn1") {
- let css =
- ` .simple-base-item .title{
- height:unset !important;
- margin:4px
- }
- .simple-base-item .title .title-txt {
- display: block; /* 更改 display 属性以适应自动换行 */
- overflow: hidden;
- word-break: normal;
- line-break: anywhere;
- line-height: normal;
- white-space: normal; /* 允许自动换行 */
- }
- `
- setStyle(css)
- }
- }
- }
- // 小节处理函数
- let chapter_dispose = function () {
- let res_height = window.innerHeight;
- let css =
- `
- .bpx-player-viewpoint-body{
- max-height:${res_height - 280}px;
- height:min-content !important
- }
- li.bpx-player-viewpoint-menu-item:hover{
- background: #DCE2E3 !important
- }
- li.bpx-player-viewpoint-menu-item:hover .bpx-player-viewpoint-menu-item-content{
- color: #000 !important
- }
- .bpx-player-viewpoint-menu-item-content :has(.bpx-player-viewpoint-menu-item-active{
- color:#00a1d !important
- }
- `
- setStyle(css)
- }
- // 小窗处理函数
- const mini_win_fn = function () {
- // 如果用户使用过小窗,则给予弹窗提醒
- let reg1 = new RegExp(".","g")
- let version_str = GM_info.script.version.replace(reg1,"");
- if(!GM_getValue("mini_status")){
- if (GM_getValue("mini_height") != 0 && typeof (GM_getValue("mini_height"))!= 'undefined' && version_str <= 133) {
- let num = window.prompt("小窗功能已从本脚本移除,升级为全站小窗设置脚本,如有需要请手动复制以下的链接前往查看","https://greasyfork.org/zh-CN/scripts/494837")
- }
- GM_setValue("mini_status",true)
- }
- }
- // 超竖屏支持
- // 竖屏下,阿B原来的最小宽度适配是width=1080px,但是这会在实际1080P分辨率屏幕下内容向右溢出,此处调整为1000px修复该问题
- const support_portrait_fn = function () {
- let css = `#mirror-vdcon{
- min-width:1000px !important
- }`
- setStyle(css)
- }
- // 统一调用入口
- let run = function () {
- fn1();
- change_right_width();
- chapter_dispose();
- mini_win_fn();
- support_no_video_list();
- // no_videos_list_change_right_width();
- support_portrait_fn()
- }
- run()
- // 窗口大小变化时重新计算
- const getWindowInfo = () => {
- run()
- };
- const debounce = (fn, delay) => {
- let timer;
- return function () {
- if (timer) {
- clearTimeout(timer);
- }
- timer = setTimeout(() => {
- fn();
- }, delay);
- }
- };
- const cancalDebounce = debounce(getWindowInfo, 500);
- window.addEventListener('resize', cancalDebounce);
- window.addEventListener('pushState', function (e) {
- run()
- });
- window.addEventListener('replaceState', function (e) {
- run()
- });
- // B站视频详情页的自动播放下一个视频,或者点击其他视频,使用的是pushState不会刷新页面,这里需要重写pushState、replaceState为来实现监听页面视频是否切换
- const bindEventListener = function (type) {
- const historyEvent = history[type];
- return function () {
- const newEvent = historyEvent.apply(this, arguments);
- const e = new Event(type);
- e.arguments = arguments;
- window.dispatchEvent(e);
- return newEvent;
- };
- };
- history.pushState = bindEventListener('pushState');
- history.replaceState = bindEventListener('replaceState');
- // 浏览器前进、后退时,重新计算
- window.onpopstate = function (event) {
- run()
- };
- })();