// ==UserScript== // @name 哔哩哔哩新版首页排版调整和去广告(bilibili) // @namespace http://tampermonkey.net/ // @version 1.3.5 // @author LingLing // @description 对新版B站首页的每行显示的视频数量进行调整, 同时删除所有广告 (大尺寸屏幕每行将显示更多的视频) // @license MIT // @icon data:image/png;base64,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 // @match *://www.bilibili.com/* // @exclude *://www.bilibili.com/all* // @exclude *://www.bilibili.com/video* // @exclude *://www.bilibili.com/anime* // @exclude *://www.bilibili.com/pgc* // @exclude *://www.bilibili.com/live* // @exclude *://www.bilibili.com/article* // @exclude *://www.bilibili.com/upuser* // @exclude *://www.bilibili.com/match* // @exclude *://www.bilibili.com/platform* // @exclude *://www.bilibili.com/bangumi* // @exclude *://www.bilibili.com/cheese* // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @compatible chrome // @compatible edge // @compatible firefox // @downloadURL none // ==/UserScript== (function () { ("use strict"); // >>>>> 请在浏览器右上角的油猴插件的设置面板中设置该插件的部分功能 <<<<< // 类名表 (或选择器) const classMap = { 标题: "h3 a", 作者: "bili-video-card__info--owner", // 含日期. 仅作者: bili-video-card__info--author 分类: "floor-title", vDom: "container", // 视频区域 的容器元素 nav: "bili-header__bar", // 导航栏的元素 banner: "bili-header__banner", // 横幅背景的元素 btn: "roll-btn", // 右侧换一换按钮 btn2: "flexible-roll-btn", // 新版右下角换一换按钮 }; const vDom = document.querySelector("." + classMap.vDom); const nav = document.querySelector("." + classMap.nav); const banner = document.querySelector("." + classMap.banner); if (!vDom) { return; } // 默认值 const base_isClearAd = true; // 是否删除'广告'(屏蔽视频). 默认 true const base_isTrueEnd = false; // 是否将广告移至预加载视频的后面. 默认 false const base_isLoadOne = false; // 是否视频全加载. 默认 false const base_videoNumRule = "0,1500,2; 1500,1800,3; 1800,3000,4; 3000,3700,5; 3700,6300,6"; const base_delClassArr = "广告, 推广"; // 获取存储的数据 const isClearAd = getValue("setting_isClearAd", base_isClearAd); const isTrueEnd = getValue("setting_isTrueEnd", base_isTrueEnd); const isLoadOne = getValue("setting_isLoadOne", base_isLoadOne); const videoNumRule = getValue("setting_videoNumRule", base_videoNumRule); // 视频排列规则, 其他尺寸按照初始方式排列 const delClassArr = getValue("setting_delClassArr", base_delClassArr); // 屏蔽的类名列表, 子元素包含某类名也可屏蔽 // console.log(isClearAd, isTrueEnd, isLoadOne, videoNumRule, delClassArr); // 屏蔽的类名表 const delClassMap = { 广告: "bili-video-card__info--ad", 推广: "bili-video-card__info--creative-ad", 特殊: "floor-single-card", 直播: "living", // 分类=直播 番剧: "分类=番剧", 综艺: "分类=综艺", 课堂: "分类=课堂", 漫画: "分类=漫画", 国创: "分类=国创", 电影: "分类=电影", 纪录片: "分类=纪录片", 电视剧: "分类=电视剧", }; // 设置的文本 const settingText = { isClearAd: `是否删除广告, 若不删除则会将所有广告移至视频列表的最后 默认: 是 (确定) 当前: `, isTrueEnd: `是否将广告移至预加载视频的后面, 关闭后广告将放置在预加载视频的前面 一般视频的后面. 开启的效率更高 默认: 否 (取消) 当前: `, isLoadOne: `是否在进入网站时加载视口区域的全部视频, 开启时视频将会全部加载, 但会闪一下 默认: 否 (取消) 当前: `, delClassArr: `屏蔽设置, 可根据需要自行修改, 可自定义, 每项用 ; 分隔 ----默认: 广告; 推广 ----可选: ('特殊'包含了直播 番剧 课堂...) 广告、推广、特殊、直播、番剧、综艺、课堂、漫画、国创、电影、纪录片、电视剧 ----自定义: 1. 标题=xxx, 可屏蔽标题含xxx的视频, xxx部分支持&&运算符, 如: 标题=A&&B, 表示屏蔽标题同时含有A B内容的视频 2. 作者=xxx, 可屏蔽作者名和发布日期中含xxx的视频`, videoNumRule: `视频排列规则, 每条规则用 ; 分隔. 其他尺寸按照初始方式排列 示例: 1450,2400,4 表示浏览器宽度在1450~2400像素时每行显示4个视频(前两行) 默认: 0,1500,2; 1500,1800,3; 1800,3000,4; 3000,3700,5; 3700,6300,6`, }; const errKeyArr = ["", "_2"]; const errKeyInfo = { disNum: "setting_err_disNum", errNum: "setting_err_num", errTime: "setting_err_time", isTip: "setting_err_isTip", }; const disErrTipNum = 3; // 每小段报错弹窗提醒次数 (短时间内的提醒次数) const errTipNum = 5 * disErrTipNum; // 报错弹窗的总提醒次数 const errTipInterval = 2; // 每段报错弹窗提醒时间间隔(小时) const errNumReset = 5; // 报错次数重置的天数 const queryNum = 0; // 处理的视频数量, 对前 queryNum 个视频中的广告进行处理(删除或置后), 0表示对全部视频进行处理. 默认 0 const marginTop1 = 40; // 第三行视频的上边距 const marginTop2 = 24; // 第四行及以上视频的上边距 let cssDom; let cssText; let oldCssText; let isChange = false; // 每行视频数是否需要变化 let showVideoNum = 3; // 当前每行显示的视频数 (以第一行为准), 网站默认值为3 let videoNum = 0; // 视频总数 let newVideoNum = 0; // 新获取的视频总数 let firstAdIndex = 0; // 第一个广告的索引 let pageZoom = 1; // 页面缩放 let w = getW(); // 浏览器视口宽度 videoNum = getVideoNum(vDom); // 计算当前视频总数 let adArr = getAd(queryNum, delClassArr, newVideoNum, 1); delAd(adArr, vDom); // 将所有广告放置在最后 或 删除 setTimeout(() => { delAdFn(); loadTopVideo(); }, 1000); zoomPage(); // 缩放页面 setStyle(); // 调整视频排列 resetErrInfo(); // 重置err相关的数据 let rollBtn; let btnSvg; let rollBtn2; // 刷新视频 window.addEventListener("click", () => { if (!rollBtn) { adArr = getAd(showVideoNum * 3 + 2, delClassArr, newVideoNum, 1); delAd(adArr, vDom); rollBtn = document.querySelector("button." + classMap.btn); // 换一换按钮 btnSvg = rollBtn && rollBtn.querySelector("svg"); // 换一换按钮的旋转图标 // 点击按钮后对新视频中的广告进行处理 if (btnSvg) { btnSvg.addEventListener("transitionend", () => { // console.log("视频刷新成功"); adArr = getAd(showVideoNum * 3 + 2 + 3, delClassArr, newVideoNum, 1); !isTrueEnd && adArr.forEach((item) => { item.forEach((adItem) => { adItem.style.display = "block"; }); }); delAd(adArr, vDom); }); } else { rollBtn && rollBtn.addEventListener("click", () => { setTimeout(() => { adArr = getAd( showVideoNum * 3 + 2 + 3, delClassArr, newVideoNum, 1 ); delAd(adArr, vDom); }, 500); }); } } if (!rollBtn2) { adArr = getAd(queryNum, delClassArr, newVideoNum, 1); delAd(adArr, vDom); rollBtn2 = document.querySelector("." + classMap.btn2); // 新版右下角的换一换按钮 // 点击按钮后对新视频中的广告进行处理 rollBtn2.addEventListener("click", () => { setTimeout(() => { videoNum = getVideoNum(vDom); // 计算当前视频总数 firstAdIndex = 0; adArr = getAd(queryNum, delClassArr, 0, 1, isTrueEnd ? true : false); delAd(adArr, vDom, true); // 强制删除广告 loadTopVideo(); }, 800); }); } }); // 窗口调整后重新计算视频的行数量 let timer; window.addEventListener("resize", () => { timer && clearTimeout(timer); timer = setTimeout(() => { console.log("窗口改变"); const newW = getW(); if (newW > w) { delAdFn(); // 若新增广告则删除 } w = newW; zoomPage(); setStyle(); }, 400); }); // 加载的新视频去除广告 let timer2, timer3; window.addEventListener("wheel", () => { timer2 && clearTimeout(timer2); timer3 && clearTimeout(timer3); timer2 = setTimeout(() => { delAdFn(timer3); }, 600); timer3 = setTimeout(() => { delAdFn(); }, 1500); }); GM_registerMenuCommand("重置设置", () => { resetSettings(); }); GM_registerMenuCommand("设置", () => { showSetting(settingText); }); // 获取视口宽度 function getW() { let width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; const zoom = window.devicePixelRatio; width *= zoom; // console.log("显示器缩放:", zoom); console.log("浏览器宽度:", width); return width; } // 缩放页面 至消除横向滚动条 function zoomPage() { const rootDom = document.documentElement; let rate = rootDom.scrollWidth / getMainW(); if (!rootDom.style.transformOrigin) { rootDom.style.transformOrigin = "top left"; document.body.style.overflow = "hidden auto"; } if (rate > 1) { // 存在横向滚动条 pageZoom *= 1 / rate; rootDom.style.transform = "scale(" + pageZoom + ")"; } else { pageZoom = 1; rootDom.style.transform = "scale(1)"; rate = rootDom.scrollWidth / getMainW(); if (rate > 1) { pageZoom *= 1 / rate; rootDom.style.transform = "scale(" + pageZoom + ")"; } } // 主区域的宽度, 部分时候总宽(导航栏)会大于主区域的宽度 function getMainW() { let navW = nav ? nav.scrollWidth : 0; let bannerW = banner ? banner.scrollWidth : 0; return navW > bannerW ? navW : rootDom.clientWidth; } } /** * 获取所有的 推广 和 广告 的元素的列表 * @param {*} queryNum 需要检索的视频数量 * @param {Array} delClassArr 需要删除的类名列表 * @param {*} vNum 视频总数 * @param {*} startIndex 检索的视频的起始索引位 * @param {Boolean} isAll 是否检索预加载视频以及后面的视频 * @returns {Array} 含各类广告列表的列表 [[...],[...],...] */ function getAd(queryNum, delClassArr, vNum, startIndex = 1, isAll = false) { const arr = []; delClassArr.forEach(() => { arr.push([]); }); const vList = [].slice.call(vDom.children); let len = vNum || vList.length; len = len > vList.length ? vList.length : len; queryNum = queryNum || len; // 0则全检索 queryNum += startIndex; if (queryNum > len) { queryNum = len; } // console.log("queryNum, vNum, startIndex, len\n",queryNum,vNum,startIndex,len); for (let i = startIndex; i < queryNum; i++) { const vItem = vList[i]; // console.log(i, item); if (!isAll && !vItem.querySelector("a")) { break; // 如果是预加载的视频 } for (let j = 0; j < delClassArr.length; j++) { if (isChecked(vItem, delClassArr[j])) { arr[j].push(vItem); break; } } } // console.log("广告列表:", arr); return arr; } // 删除广告 或 放置在最后, 返回减少的数量 function delAd(adArr, dom = vDom, isDel = false) { for (let i = adArr.length - 1; i >= 0; i--) { delInArr(adArr[i]); } function delInArr(arr) { arr.forEach((item) => { if (isClearAd || isDel) { item.remove(); newVideoNum--; videoNum--; } else { if (isTrueEnd) { dom.appendChild(item); // 放在最后 (预加载视频后) } else { dom.insertBefore(item, dom.children[newVideoNum]); // 放在预加载视频前 } } }); } } // 设置浏览器宽度在某个范围时[左闭右开], 每行显示的视频数 function setVideoNum(vRule) { const min = +vRule[0]; const max = +vRule[1]; const num = +vRule[2]; if ((min !== 0 && !min) || !max || !num) { errHandle({ errTxt: `插件设置的视频排列规则设置中 '${vRule.join("")}' 格式书写错误`, key: errKeyArr[1], // 2 }); return; } if (w >= min && w < max) { cssText = ` .container {grid-template-columns: repeat(${num + 2},1fr) !important} .container>div:nth-child(n){margin-top:${marginTop2}px !important} .container>div:nth-child(-n+${ num * 3 + 2 + 1 }){margin-top:${marginTop1}px !important;display:block !important} .container>div:nth-child(-n+${ (num + 1) * 2 - 1 }){margin-top:0px !important}`; isChange = true; showVideoNum = num; } if (!isChange) { cssText = ""; // 默认排列方式 showVideoNum = 3; } } // 调整每行显示个数 function setStyle() { isChange = false; // 每行视频数是否需要变化 videoNumRule.forEach((item) => { setVideoNum(item); // 视口宽度在 1450~2400 px 时则每行显示 4 个视频(前两行) }); if (isChange) { let isCssDom = !!cssDom; // 是否已添加style if (!isCssDom) { cssDom = document.createElement("style"); cssDom.setAttribute("type", "text/css"); } oldCssText !== cssText && (cssDom.innerHTML = cssText); oldCssText = cssText; !isCssDom && vDom.parentElement.insertBefore(cssDom, vDom); } else { // 尺寸缩小时触发 if (!isChange && cssDom) { oldCssText = ""; cssDom.innerHTML = ""; } } } // 获取视频总数 function getVideoNum(dom) { const arr = [].slice.call(dom.children); const len = arr.length; let i; let isGetAdIndex = false; for (i = 1; i < len; i++) { const item = arr[i]; // 获取第一个广告的索引 if (!isTrueEnd && !isGetAdIndex) { const vItem = dom.children[i]; for (let j = 0; j < delClassArr.length; j++) { if (isChecked(vItem, delClassArr[j])) { isGetAdIndex = true; firstAdIndex = i; break; } } } // 如果是预加载视频 if (!item.querySelector("a")) { newVideoNum = i; return i; } } newVideoNum = i; return i; } // 判断是否是查找的目标 function isChecked(vEle, delStr) { let flag = false; const map = classMap; delStr = delClassMap[delStr] || delStr; // 自定义的屏蔽内容 function custom(txt, type, selector) { const dom = vEle.querySelector(selector); if (!dom) { return; } const domTxt = dom.innerText; const txtArr = txt.replace(type, "").split("&&"); if (!txtArr[0]) { return; } let f = false; txtArr.forEach((item) => { f = f || domTxt.includes(item, ""); }); flag = flag || f; } if (delStr.includes("标题=")) { custom(delStr, "标题=", map.标题); } else if (delStr.includes("作者=")) { custom(delStr, "作者=", "." + map.作者); } else if (delStr.includes("分类=")) { custom(delStr, "分类=", "." + map.分类); } else { flag = flag || vEle.classList.contains(delStr); try { flag = flag || vEle.querySelector("." + delStr); } catch (e) { errHandle({ errTxt: `插件设置的屏蔽设置中 '${delStr}' 格式书写错误应以 '标题=' 或 '作者=' 开头`, e, }); } } return flag; } // 根据视频总数是否变化删除广告 function delAdFn(timer = null) { getVideoNum(vDom); if (newVideoNum > videoNum) { console.log("加载新视频"); adArr = getAd( queryNum, delClassArr, newVideoNum, isTrueEnd ? videoNum : firstAdIndex ); delAd(adArr, vDom); videoNum = newVideoNum; timer && clearTimeout(timer); } } // 加载顶部位置的接下来的一组视频 function loadTopVideo() { isLoadOne && document.documentElement.scrollTo(0, 400); isLoadOne && setTimeout(() => { document.documentElement.scrollTo(0, 0); setTimeout(() => { delAdFn(); }, 800); }, 20); } // 获取存储的值, 并解析成对应数据类型 function getValue(key, defa) { let value = GM_getValue(key); if (key === "setting_videoNumRule") { if (value !== undefined && value !== null) { value = getVideoNumRule(value); } else { defa = getVideoNumRule(defa); } } else if (key === "setting_delClassArr") { if (value !== undefined && value !== null) { value = getDelClassArr(value); } else { defa = getDelClassArr(defa); } } return value === undefined || value === null ? defa : value; } // 解析数据字符串为对应数据类型 function getVideoNumRule(value) { value = value.split(/;|;/); return value.map((item) => item.split(/,|,/)); } function getDelClassArr(value) { value = value.replaceAll("\n", "").replaceAll(" ", ""); return value.split(/;|;|,|,/); } // 设置 function showSetting(txt) { const isClearAd = confirm( txt.isClearAd + (GM_getValue("setting_isClearAd") ? "是 (确定)" : "否 (取消)") ); GM_setValue("setting_isClearAd", isClearAd); if (!isClearAd) { const value = GM_getValue("setting_isTrueEnd"); GM_setValue( "setting_isTrueEnd", confirm( txt.isTrueEnd + ((value === undefined ? base_isTrueEnd : value) ? "是 (确定)" : "否 (取消)") ) ); } else { GM_setValue("setting_isTrueEnd", base_isTrueEnd); } GM_setValue( "setting_isLoadOne", confirm( txt.isLoadOne + (GM_getValue("setting_isLoadOne") ? "是 (确定)" : "否 (取消)") ) ); if (confirm("是否进入更多设置")) { const value1 = GM_getValue("setting_videoNumRule"); const value2 = GM_getValue("setting_delClassArr"); const txt2 = prompt( txt.delClassArr, value2 === undefined || value2 === null ? base_delClassArr : value2 ); const txt1 = prompt( txt.videoNumRule, value1 === undefined || value1 === null ? base_videoNumRule : value1 ); GM_setValue("setting_videoNumRule", txt1 || value1); GM_setValue("setting_delClassArr", txt2 || value2); } history.go(0); // 刷新页面 } // 错误处理 function errHandle({ e = null, errTxt = "", logTxt = "", key = "" } = {}) { let errNum = GM_getValue(errKeyInfo.errNum) || 0; if (errNum >= errTipNum) { return; } let disErrNum = GM_getValue(errKeyInfo.disNum + key) || 0; const curTime = Date.now(); const errTime = GM_getValue(errKeyInfo.errTime + key) || curTime; let disS = (curTime - errTime) / 1000; disS = disS === 0 ? 5 : disS; if (disS < 5) { return; } let flag = GM_getValue(errKeyInfo.isTip + key); // 是否能弹窗提示 flag = flag === undefined ? true : flag; e && console.log(e); console.log(logTxt || errTxt); if (disS >= errTipInterval * 60 * 60) { // 每errTipInterval小时允许提醒disErrTipNum次 flag = true; GM_setValue(errKeyInfo.isTip + key, true); GM_setValue(errKeyInfo.disNum + key, 0); } if ( flag && disErrNum <= disErrTipNum && disS < (errTipInterval / 10) * 60 * 60 ) { // 在errTipInterval/10小时内允许disErrTipNum次提示 errNum++; disErrNum++; GM_setValue(errKeyInfo.errNum, errNum); GM_setValue(errKeyInfo.disNum + key, disErrNum); GM_setValue(errKeyInfo.errTime + key, curTime); alert(errTxt); disErrNum === disErrTipNum && GM_setValue(errKeyInfo.isTip + key, false); } } // 重置err相关的数据 function resetErrInfo() { const curTime = Date.now(); const errTime = errKeyArr.reduce((a, b) => { const t = +GM_getValue(errKeyInfo.errTime + b); return t < a ? t : a; }, curTime); if ((curTime - errTime) / 1000 >= errNumReset * 24 * 60 * 60) { GM_setValue(errKeyInfo.errNum, 0); // 重置 errKeyArr.forEach((key) => { GM_setValue(errKeyInfo.disNum + key, 0); // 重置 }); console.log("重置err相关的数据"); } } // 重置设置 function resetSettings() { GM_setValue("setting_isClearAd", base_isClearAd); GM_setValue("setting_isTrueEnd", base_isTrueEnd); GM_setValue("setting_isLoadOne", base_isLoadOne); GM_setValue("setting_videoNumRule", base_videoNumRule); GM_setValue("setting_delClassArr", base_delClassArr); GM_setValue(errKeyInfo.errNum, 0); errKeyArr.forEach((key) => { GM_setValue(errKeyInfo.disNum + key, 0); // 重置 }); history.go(0); // 刷新页面 } })();