// ==UserScript==
// @name b站评论区简化(保存网页用)
// @namespace http://tampermonkey.net/
// @version 0.2
// @description 删除b站视频及动态中的多余元素,并展开评论区二级回复,以及调整页面样式,为通过SingleFile等工具导出网页备份评论区做准备。必须搭配油猴脚本“Bilibili - 在未登录(不可用)的情况下照常加载评论”使用。
// @license GPL-3.0
// @author Kooluve
// @match https://www.bilibili.com/video/*
// @match https://www.bilibili.com/opus/*
// @match https://t.bilibili.com/*
// @exclude https://t.bilibili.com/?tab=*
// @icon https://www.bilibili.com/favicon.ico
// @grant GM_addStyle
// @run-at document-start
// ==/UserScript==
(function() {
'use strict';
let currentUrl = window.location.href; // 网页链接
let isVideo, isOpus, isT;
if (currentUrl.includes('bilibili.com/video')) { isVideo = true} // 视频
else if (currentUrl.includes('bilibili.com/opus')) { isOpus = true} // 图文
else if (/^https:\/\/t\.bilibili\.com\/\d+$/.test(currentUrl)) { isT = true} // 转发
let singleFileName = ''; // singlefile文件名
let isScriptExecuting = false; // 脚本是否正在执行
let overlay; // 页面变暗的覆盖层
let messageBar; // 脚本执行提示条
let isDataLoaded = false; // 判断页面是否加载完毕,以便在一次网页刷新中重复启动脚本时顺利进行
let elementsToRemove; // 待删除元素(部分)
const webOpenTime = getWebOpenTime(); // 打开网页的时刻
const scrollInterval = 500; // 检查跳转到页面底部的间隔。时间单位都为毫秒
const scrollMaxIdleTime = 10000; // 页面底部无变化最多的停滞时间
const anchorForLoadingText = '所有评论已加载完毕'; // 加载完毕的文字
let isCommentLoading = true; // 评论区初始状态为正在加载
let lastScrollHeight = 0; // 记录上一次页面的高度
const clickIntervalMin = 100; // 展开二级回复的最小间隔
const clickIntervalMax = 200; // 展开二级回复的最大间隔
console.log('页面打开时刻: ', webOpenTime); // 输出打开网页的时刻
adjustBeforeSingleFile(); // 在singlefile保存网页前调整网页
// 输出打开网页的时刻,方便不使用该脚本后续功能,只是单纯截图时,知晓这个图片的保存时间。也便于调试脚本
function getWebOpenTime() {
const visitYearLocale = new Date().getFullYear();
const visitMonthLocale = String(new Date().getMonth() + 1).padStart(2, '0');
const visitDayLocale = String(new Date().getDate()).padStart(2, '0');
const visitTimeLocale = new Date().toLocaleTimeString();
const formattedTime = `(${visitYearLocale}-${visitMonthLocale}-${visitDayLocale} ${visitTimeLocale})`
return formattedTime;
}
// 使用方式1:在singlefile保存网页前自动调整网页
async function adjustBeforeSingleFile() {
dispatchEvent(new CustomEvent("single-file-user-script-init"));
addEventListener("single-file-on-before-capture-request", async event => {
event.preventDefault();
try {
await waitForVisibility(); // 等待标签页变为可见
await start(); // 开始脚本功能
console.log('start 函数执行完毕');
} catch (error) {
console.log('start 函数有错误');
} finally {
dispatchEvent(new CustomEvent("single-file-on-before-capture-response"));
}
});
}
// 等待标签页变为可见
async function waitForVisibility() {
// 如果标签页已经是可见的,直接执行
if (document.visibilityState === 'visible') {
console.log('标签页当前可见,直接执行函数');
return;
}
// 如果标签页不是可见的,则等待可见性变化
return new Promise((resolve) => {
function onVisibilityChange() {
if (document.visibilityState === 'visible') {
// 标签页切换到前台,执行函数
console.log('标签页变为可见,开始执行函数');
resolve(); // 解除等待
document.removeEventListener('visibilitychange', onVisibilityChange); // 移除事件监听
}
}
// 监听 visibilitychange 事件
document.addEventListener('visibilitychange', onVisibilityChange);
});
}
// 使用方式2:快捷键启动脚本调整网页
window.addEventListener('keydown', function(event) {
// Ctrl + Shift + Alt + Z 展开评论区,可根据需要修改
if (!isScriptExecuting && event.ctrlKey && event.shiftKey && event.altKey && event.key === 'Z') {
start();
}
});
async function start() {
console.log('脚本开始执行');
// 初始化变量
isCommentLoading = true;
isScriptExecuting = true;
// 创建变暗的覆盖层
createDarkOverlay();
// 显示提示条
showStickyMessage('脚本执行中...');
// 等待页面初步加载完毕
await waitLoading();
// 设置singlefile保存文件名
setSingleFileName();
// 预先删除页面中绝大部分没用的元素
await preRemove();
// 删除剩余元素
otherRemove();
// 点击最新按钮
await new Promise(resolve => {
setTimeout(function() {
clickLastedButton();
resolve();
}, 500); // 延迟0.5秒
});
// 开始自动跳转到底部
try {
await startAutoScrollToBottom();
} catch (error) {
messageBar.innerText = '滚动加载评论区失败,请刷新网页重试。滚动加载期间不要移开标签页';
// 在文件名中添加错误提示
singleFileName = singleFileName.replace(/\/([^\/]*)$/, '/【错误:滚动加载评论区失败】$1');
console.error('错误:', '滚动加载评论区失败');
throw new Error(error.message);
return;
}
// 展开二级回复
try {
await clickViewMoreBtns();
} catch (error) {
messageBar.innerText = '展开二级回复失败,请刷新网页重试。仍未解决请等一段时间再试';
// 在文件名中添加错误提示
singleFileName = singleFileName.replace(/\/([^\/]*)$/, '/【错误:展开二级回复失败】 $1');
console.error('错误:', '展开二级回复失败');
throw new Error(error.message);
return;
}
// 修改动态相册样式
modifyStyleAlbum();
// 修改样式
modifyStyle();
// 创建用于保存文件名的元素
addFilenameForSinglefile();
// 脚本结束
end();
}
// 创建一个模拟页面变暗的透明覆盖层
function createDarkOverlay() {
overlay = document.createElement('div');
overlay.id = 'darkOverlay';
overlay.style.position = 'fixed';
overlay.style.top = '0';
overlay.style.left = '0';
overlay.style.width = '100%';
overlay.style.height = '100%';
overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; // 半透明的黑色
overlay.style.zIndex = '9998'; // 确保它在页面内容下方但低于提示条
overlay.style.pointerEvents = 'none'; // 不干扰页面操作
document.body.appendChild(overlay);
}
// 创建并显示提示条
function showStickyMessage(message) {
messageBar = document.createElement('div');
messageBar.id = 'stickyMessage';
messageBar.style.position = 'fixed';
messageBar.style.top = '0';
messageBar.style.left = '0';
messageBar.style.width = '100%';
messageBar.style.padding = '10px';
messageBar.style.backgroundColor = '#ff9800'; // 使用鲜亮的背景色
messageBar.style.color = '#fff'; // 白色文本
messageBar.style.textAlign = 'center';
messageBar.style.zIndex = '9999'; // 确保提示条在最上面
messageBar.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.3)'; // 提示条阴影
messageBar.style.fontSize = '20px'; // 设置字体大小
messageBar.innerText = message;
document.body.appendChild(messageBar);
}
//删除覆盖和提示
function removeOverlayAndMessage() {
if (messageBar) {
messageBar.remove();
}
if (overlay) {
overlay.remove();
}
}
// 等待页面初步加载完毕
async function waitLoading() {
const checkAndRunScript = async () => {
const dataLoaded = document.querySelector('iframe[src="https://s1.hdslb.com/bfs/seed/jinkela/short/cols/iframe.html"][data-loaded="true"]');
if (dataLoaded) {
isDataLoaded = true;
console.log('网页加载完毕');
return 'case1';
} else if (isDataLoaded) { // 脚本已执行过,直接跳到滚动底部功能
console.log('网页已加载过');
return 'case2';
} else {
await new Promise(resolve => setTimeout(resolve, 500)); // 每0.5秒检查一次
return checkAndRunScript();
}
};
return await checkAndRunScript(); // 初始调用
}
// 获取为singlefile准备的保存文件名
function setSingleFileName() {
let resultName = '';
if (isVideo) {
let author = '';
const upName = document.querySelector('a.up-name')?.textContent;
let staffNameAll = '';
const staffNameList = document.querySelectorAll('a.staff-name');
for (const staff of staffNameList) {
staffNameAll += staff.textContent + ' ' ; // 最后一次循环多加了一个空格
}
let time = document.querySelector('.pubdate-ip-text')?.textContent || '';
let title = document.querySelector('.video-title')?.textContent || '';
author = upName?.slice(6, upName.length - 7) || staffNameAll?.slice(0, -1);
title = title.replace(/\//g, ' ');
resultName += author + '/视频 ' + time + ' ' + title + ' ' ;
} else if (isOpus) {
let author = document.querySelector('.opus-module-author__name')?.textContent || '';
let time = document.querySelector('.opus-module-author__pub__text')?.textContent || '';
let title = document.querySelector('.opus-module-title__text')?.textContent || '';
let content = document.querySelector('.opus-module-content')?.textContent || '';
time = (time.includes('编辑于') ? time.substring(4) + ' (已编辑)' : time);
time = time.replace(/(\d{4})年(\d{2})月(\d{2})日 (\d{2}:\d{2})/, "$1-$2-$3 $4:XX");
title = title.replace(/\//g, ' ');
content = content.replace(/\//g, ' ');
title = title ? title : (content ? (content.substring(0, 15) + '…') : '(无字)');
resultName += author + '/动态 ' + time + ' ' + title + ' (图文) ';
} else if (isT) {
let author = document.querySelector('span.bili-dyn-title__text')?.textContent || '';
let time = document.querySelector('.bili-dyn-time')?.textContent || '';
let content = document.querySelector('.bili-rich-text__content')?.textContent || '';
author = author.slice(4, author.length - 3);
time = time.substring(3, 20);
time = time.replace(/(\d{4})年(\d{2})月(\d{2})日 (\d{2}:\d{2})/, "$1-$2-$3 $4:XX");
content = content.replace(/\//g, ' ');
content = content.length > 0 ? content.substring(0, 15) + '…' : '(无字)';
resultName += author + '/动态 ' + time + ' ' + content + ' (转发) ';
}
// 以页面打开时刻作为保存时间
resultName += webOpenTime;
console.log('文件名设置完毕');
}
// 预先删除页面中绝大部分没用的元素
async function preRemove() {
// 获取head元素
const head = document.head || document.getElementsByTagName('head')[0];
const headElements = Array.from(head.children);
var keepHeadElements;
// 公用的保留的head元素条件
const commonHeadElements = [
{ tag: 'STYLE', innerHTMLInclude: '.reply-item .root-reply-avatar .avatar .bili-avatar' },
{ tag: 'STYLE', innerHTMLInclude: '.fan-medal' },
{ tag: 'STYLE', innerHTMLInclude: '.sub-reply-container .view-more-btn:hover' },
{ tag: 'STYLE', innerHTMLInclude: '.jump-link' },
{ tag: 'STYLE', innerHTMLInclude: ':root' },
{ tag: 'TITLE' },
];
// 保留的head元素条件
if (isVideo) {
keepHeadElements = [
...commonHeadElements,
{ tag: 'Link', href: '//s1.hdslb.com/bfs/seed/jinkela/short/bili-theme/map.css' },
{ tag: 'Link', href: '//s1.hdslb.com/bfs/seed/jinkela/short/bili-theme/light.css' },
{ tag: 'Link', href: '//s1.hdslb.com/bfs/static/jinkela/video/css/video' }, // 如'//s1.hdslb.com/bfs/static/jinkela/video/css/video.0.2ce49da9698008db82fd161474a3e2cc4dcc2c2a.css'
{ tag: 'STYLE', id: 'setSizeStyle' },
];
} else if (isOpus) {
keepHeadElements = [
...commonHeadElements,
{ tag: 'Link', href: '//s1.hdslb.com/bfs/seed/jinkela/short/bili-theme/map.css' },
{ tag: 'Link', href: '//s1.hdslb.com/bfs/seed/jinkela/short/bili-theme/light_u.css' },
{ tag: 'Link', href: '//s1.hdslb.com/bfs/seed/jinkela/short/bili-theme/light.css' },
{ tag: 'Link', href: '//s1.hdslb.com/bfs/static/stone-free/opus-detail/css/opus-detail.1.43b5e197533b9afa5213455ea78553d2ad191767.css' },
{ tag: 'Link', href: '//s1.hdslb.com/bfs/static/stone-free/opus-detail/css/opus-detail.0.43b5e197533b9afa5213455ea78553d2ad191767.css' },
{ tag: 'STYLE', type: 'text/css' },
{ tag: 'STYLE', id: 'bmgstyle-b-img__inner' },
];
} else if (isT) {
keepHeadElements = [
...commonHeadElements,
{ tag: 'STYLE', type: 'text/css' },
{ tag: 'STYLE', id: 'bmgstyle-b-img__inner' },
];
}
// 处理head中的元素
headElements.forEach(element => {
// 保留指定的head元素
const shouldKeep = keepHeadElements.some(item => {
const tagMatch = element.tagName === item.tag.toUpperCase();
const hrefMatch = item.href ? element.href && element.href.includes(item.href) : true;
const typeMatch = item.type ? element.type === item.type : true;
const idMatch = item.id ? element.id === item.id : true;
const innerHTMLIncludeMatch = item.innerHTMLInclude ? element.innerHTML.includes(item.innerHTMLInclude) : true;
return tagMatch && hrefMatch && typeMatch && idMatch && innerHTMLIncludeMatch;
});
if (!shouldKeep) {
element.remove();
}
});
// 获取body元素
const body = document.body;
const bodyElements = Array.from(body.children);
var keepBodyElements;
// 公用的保留的body元素条件
const commonBodyElements = [
//脚本增加的覆盖和提示
{ tag: 'DIV', id: 'darkOverlay' },
{ tag: 'DIV', id: 'stickyMessage' },
];
// 保留的body元素条件
if (isVideo || isOpus) {
keepBodyElements = [
...commonBodyElements,
{ tag: 'DIV', id: 'app' },
];
}
else if (isT) {
keepBodyElements = [
...commonBodyElements,
{ tag: 'Link', href: '//s1.hdslb.com/bfs/static/stone-free/dyn-detail/css/dyn-detail.1.43b5e197533b9afa5213455ea78553d2ad191767.css' },
{ tag: 'Link', href: '//s1.hdslb.com/bfs/static/stone-free/dyn-detail/css/dyn-detail.0.43b5e197533b9afa5213455ea78553d2ad191767.css' },
{ tag: 'DIV', id: 'app' },
];
}
// 处理body中的元素
bodyElements.forEach(element => {
// 保留指定的body元素
const shouldKeep = keepBodyElements.some(item => {
const tagMatch = element.tagName === item.tag.toUpperCase();
const hrefMatch = item.href ? element.href && element.href.includes(item.href) : true;
const idMatch = item.id ? element.id === item.id : true;
return tagMatch && hrefMatch && idMatch;
});
if (!shouldKeep) {
element.remove();
}
});
// 删除edge浏览器中的多余元素。其他浏览器待测试
// 获取html元素并遍历其直接子元素
const html = document.documentElement; // 获取 <html> 元素
const siblingElements = Array.from(html.children); // 获取 html 下的所有直接子元素(包括 <head> 和 <body>)
// 定义需要移除的同级元素条件
const removeSiblingElements = [
{ tag: 'DIV', style: 'all: initial;' },
{ tag: 'DIV', id: 'immersive-translate-popup' }
];
// 处理同级元素
siblingElements.forEach(element => {
const shouldRemove = removeSiblingElements.some(item => {
// 检查元素的style是否包含all: initial
const style = element.getAttribute('STYLE') || '';
const isStyleMatching = style.includes('all: initial');
const isIdMatching = !item.id || element.id === item.id;
// 如果匹配到条件,移除元素
return element.tagName === item.tag.toUpperCase() && isStyleMatching && isIdMatching;
});
if (shouldRemove) {
element.remove();
}
});
console.log('预先删除完毕');
}
// 删除剩余元素
function otherRemove() {
if (isVideo) {
elementsToRemove = [
'#biliMainHeader',
'#playerWrap',
'.right-container',
'.toggle-btn',
'.fixed-sidenav-storage',
'.activity-m-v1',
'.video-toolbar-right',
'.ad-report',
];
}
else if (isOpus) {
elementsToRemove = [
'.right-sidebar-wrap',
'.fixed-author-header',
'.opus-module-bottom',
];
}
else if (isT) {
elementsToRemove = [
'.sidebar-wrap',
];
}
const mainReplyBox = document.querySelector('.main-reply-box');
if (mainReplyBox) {
// 移除
mainReplyBox.remove();
}
// 删除元素
elementsToRemove.forEach(function(selector) {
var element = document.querySelector(selector);
if (element) {
element.remove();
}
});
console.log('删除剩余元素完毕');
}
// 点击最新按钮
function clickLastedButton() {
const lastedButton = document.querySelector('.time-sort');
if (lastedButton) {
lastedButton.click();
console.log('已点击最新按钮');
}
}
// 开始自动跳转到底部
async function startAutoScrollToBottom() {
document.documentElement.style.scrollBehavior = 'auto'; // 禁用平滑滚动
let lastScrollHeight = document.body.scrollHeight;
let lastUpdateTime = Date.now(); // 记录上次页面变化时间
while (isCommentLoading) {
// 判断页面是否加载完成
const isPageLoaded = monitorPageLoad(lastScrollHeight, lastUpdateTime);
if (isPageLoaded === 'case1') { // 页面加载完毕,退出循环
isCommentLoading = false;
break;
} else if (isPageLoaded === 'case2') { // 页面加载失败,退出函数
isCommentLoading = false;
throw new Error('滚动加载评论区失败'); // 抛出错误
return;
} else if (isPageLoaded === 'case3') { // 页面正在加载
}
scrollToBottom(); // 跳转到底部
await new Promise(resolve => setTimeout(resolve, scrollInterval)); // 等待一定时间后再继续检查
// 如果页面高度发生变化,更新上次变化的时间
if (document.body.scrollHeight !== lastScrollHeight) {
lastScrollHeight = document.body.scrollHeight;
lastUpdateTime = Date.now(); // 更新最后的变化时间
}
}
document.documentElement.style.scrollBehavior = 'smooth'; // 恢复平滑滚动
console.log('评论区加载完毕');
}
// 跳转到页面底部
function scrollToBottom() {
window.scrollTo(0, document.body.scrollHeight);
}
// 判断是否加载完毕
function monitorPageLoad(lastScrollHeight, lastUpdateTime) {
const currentScrollHeight = document.body.scrollHeight;
const anchorForLoading = document.querySelector('.anchor-for-loading');
if (anchorForLoading) { // 加载文字存在
// 加载文字完成
if (anchorForLoading.textContent.trim() === anchorForLoadingText) {
return 'case1'; // 加载完成
}
// 加载文字未完成,页面高度相同
else if(currentScrollHeight === lastScrollHeight) {
// 如果页面高度长时间没有变化,认为加载失败
if (Date.now() - lastUpdateTime > scrollMaxIdleTime) {
console.log('页面加载停滞,认为加载失败');
return 'case2'; // 加载失败
}
}
} else if(currentScrollHeight === lastScrollHeight) { // 加载文字不存在
// 如果页面高度长时间没有变化,认为加载完成
if (Date.now() - lastUpdateTime > scrollMaxIdleTime) {
console.log('页面加载停滞,认为加载完成');
return 'case1'; // 加载完成
}
return 'case3'; // 页面仍在加载
}
lastScrollHeight = currentScrollHeight; // 更新页面高度
return 'case3'; // 页面仍在加载
}
// 展开二级回复
async function clickViewMoreBtns() {
// 获取按钮
const viewMoreBtnList = document.querySelectorAll('.view-more-btn');
for (const viewMoreBtn of viewMoreBtnList) {
if (viewMoreBtn) {
// 生成随机延迟时间
const delay = Math.floor(Math.random() * (clickIntervalMax - clickIntervalMin + 1)) + clickIntervalMin;
viewMoreBtn.click();
await new Promise(resolve => setTimeout(resolve, delay));
}
}
// 延迟后再次检查按钮
await new Promise(resolve => setTimeout(() => {
// 再次获取按钮
const viewMoreBtnListRemain = document.querySelectorAll('.view-more-btn');
if (viewMoreBtnListRemain.length > 0) {
throw new Error('展开二级回复失败'); // 抛出错误
}
resolve();
}, 500));
console.log('展开二级回复完毕');
}
// 修改动态相册样式
function modifyStyleAlbum() {
// 检查是否存在 .horizontal-scroll-album__indicator
const indicator = document.querySelector('.horizontal-scroll-album__indicator');
if (!indicator) {
return; // 如果没有找到,退出函数
}
// 获取所有缩略图
const thumbnails = document.querySelectorAll('.horizontal-scroll-album__indicator__thumbnail');
// 依次点击所有缩略图
thumbnails.forEach((thumbnail, index) => {
setTimeout(() => {
// 点击缩略图
thumbnail.click();
}, index * 200); // 延迟200ms,避免过快点击
});
// 等待图片加载完成后,注入样式并等比缩放
setTimeout(() => {
const albumScreen = document.querySelector('.horizontal-scroll-album__screen');
const images = document.querySelectorAll('.horizontal-scroll-album__pic');
const imageElems = document.querySelectorAll('.horizontal-scroll-album__pic__img');
const albumContent = document.querySelector('.horizontal-scroll-album__content');
// 获取 horizontal-scroll-album__screen 容器的宽度
const screenWidth = albumScreen ? albumScreen.offsetWidth : 0;
if (screenWidth === 0) return; // 如果容器宽度为0,则退出
const gap = 5; // 图片间隔
// 计算去除间隔后的每张图片的宽度
const imageWidth = (screenWidth - (images.length - 1) * gap) / images.length;
// 使用 GM_addStyle 动态注入样式
GM_addStyle(`
.horizontal-scroll-album__screen {
transform: none !important; /* 取消水平滚动 */
display: flex !important; /* 使用 flex 布局排列图片 */
flex-wrap: nowrap !important; /* 禁用换行 */
overflow: hidden !important; /* 隐藏溢出的部分 */
}
.horizontal-scroll-album__pic {
display: flex !important; /* 使用 flex 布局 */
justify-content: center !important; /* 水平居中 */
align-items: center !important; /* 垂直居中 */
margin-bottom: 0 !important; /* 清除图片间距 */
width: ${imageWidth}px !important; /* 设置每张图片的宽度 */
height: auto !important; /* 高度自动调整,保持比例 */
margin-right: ${gap}px !important; /* 设置图片之间的间隔 */
}
/* 修改 .horizontal-scroll-album__pic__img 的样式 */
.horizontal-scroll-album__pic__img {
display: block !important; /* 确保图片显示为块级元素 */
width: 100% !important; /* 确保图片宽度适应容器 */
height: auto !important; /* 高度自动调整,保持比例 */
object-fit: contain !important; /* 保持等比缩放 */
}
`);
// 直接调整每张实际图片的尺寸
imageElems.forEach(img => {
// 选择实际的图片元素,并调整它们的尺寸
const actualImage = img.querySelector('img');
if (actualImage) {
// 清除图片的 width 和 height 属性,防止原始属性覆盖
actualImage.removeAttribute('width');
actualImage.removeAttribute('height');
// 强制设置图片的宽度和高度
actualImage.style.width = '100%'; // 强制设置图片宽度适应父容器
actualImage.style.height = 'auto'; // 高度按比例调整
actualImage.style.objectFit = 'contain'; // 保持等比缩放
}
});
// 获取所有 .horizontal-scroll-album__pic__img 元素的实际高度
let maxHeight = 0;
imageElems.forEach((imgElem) => {
const img = imgElem.querySelector('img');
if (img) {
// 获取实际的高度
const actualHeight = img.offsetHeight;
if (actualHeight > maxHeight) {
maxHeight = actualHeight;
}
}
});
// 如果找到了最大高度,设置 .horizontal-scroll-album__content 的高度
if (maxHeight > 0 && albumContent) {
albumContent.style.height = `${maxHeight}px`;
}
// 移除导航按钮
const albumNav= document.querySelector('.horizontal-scroll-album__nav');
if (albumNav) {
albumNav.remove();
}
// 移除模糊背景
const blurBgElements = document.querySelectorAll('.horizontal-scroll-album__pic__blurbg');
blurBgElements.forEach((bg) => {
bg.remove();
});
// 移除缩略图
if (indicator) {
indicator.remove();
}
console.log('修改相册样式完毕');
}, thumbnails.length * 500 + 500); // 等待所有图片加载完成
}
// 修改样式
function modifyStyle() {
if (isVideo) {
// 长标题换行
const videoTitle = document.querySelector('.video-title');
if (videoTitle) {
videoTitle.style.whiteSpace = 'normal';
videoTitle.style.flexShrink = 'initial';
videoTitle.style.marginRight = '0px';
}
// 标题容器的高度根据内容自动调整
const viewbox = document.querySelector('#viewbox_report');
if (viewbox) {
viewbox.style.height = 'auto'; // 设置父容器高度自适应
viewbox.style.overflow = 'visible'; // 取消溢出隐藏,确保内容能完全显示
}
// 删除展开箭头
const videoInfoTitleInner = document.querySelector('.video-info-title');
if (videoInfoTitleInner) {
// 获取该元素的所有1级子元素
const childElements = videoInfoTitleInner.children;
// 遍历所有子元素,删除注释节点
Array.from(childElements).forEach(child => {
if (child.nodeType === Node.COMMENT_NODE || child.classList.contains('show-more') || child.classList.contains('overflow-panel')) {
child.remove(); // 删除注释节点
}
});
}
GM_addStyle(`
.video-container-v1 {
min-width: 0px !important;
}
.left-container {
min-width: 0px !important;
max-width: 708px !important;
}
.basic-desc-info {
height: auto !important;
}
.tag.not-btn-tag {
display: block !important;
}
`);
}
else if (isOpus || isT) {
if (isOpus) {
GM_addStyle(`
.opus-module-title {
padding: 10px 20px 0 20px !important;
}
.opus-module-author {
padding: 10px 20px !important;
}
.opus-module-content {
padding: 0 20px !important;
}
`);
}
else if (isT) {
GM_addStyle(`
.bili-dyn-item{
min-width: 0px !important;
}
`);
}
GM_addStyle(`
#app {
min-width: 0px !important;
}
.opus-detail{
width: auto !important;
min-width: 0px !important;
max-width: 708px !important;
}
`);
}
GM_addStyle(`
.bili-tabs__header {
padding: 0 !important;
}
.bili-tabs__nav__item.is-active {
padding: 0 !important;
}
div.bili-comment-container {
padding: 0 10px 0 0px !important;
}
.reply-navigation {
margin: 20px 0 0 20px !important;
}
`);
console.log('修改样式完毕');
}
// 创建一个带有文件名称的 <meta> 元素,供singlefile使用(需要在singlefile的文件名规则中获取这个元素)
function addFilenameForSinglefile() {
const metaTag = document.createElement('meta');
// 设置属性
metaTag.setAttribute('name', 'singlefile-filename');
metaTag.setAttribute('content', singleFileName);
// 将 <meta> 元素添加到 <head> 标签中
document.head.appendChild(metaTag);
}
function end() {
isScriptExecuting = false;
//删除覆盖和提示
removeOverlayAndMessage();
// 跳转到页面底部
scrollToBottom();
console.log('脚本执行完毕');
}
})();