您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
不可逆的默认屏蔽首页广告,并在左下角添加了屏蔽词功能,并能自定义每个屏蔽词的范围(真的会有人需要这种自定义吗)
当前为
// ==UserScript== // @name Bilibili Blacklist // @namespace http://tampermonkey.net/ // @version 0.8.3 // @description 不可逆的默认屏蔽首页广告,并在左下角添加了屏蔽词功能,并能自定义每个屏蔽词的范围(真的会有人需要这种自定义吗) // @author Aporia // @match *://*.bilibili.com/* // @icon https://www.google.com/s2/favicons?domain=google.cn // @grant GM_setValue // @grant GM_getValue // @grant GM_addElement // @grant GM_xmlhttpRequest // @require https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js // @run-at document-end // @license MIT // ==/UserScript== (function() { // Define page types let pageTypes = ['searchPage', 'mainPage', 'leaderboard', 'timeLine', 'recommand', 'reply']; let pageTypesCN = {searchPage : '搜索页面', mainPage : '主页面', leaderboard: '排行榜', timeLine: '动态', recommand: '推荐', reply: '回复'}; // Initialize blacklist with some default values let blacklist = GM_getValue('blacklist'); if (blacklist === undefined) { blacklist = [{ keyword: "此时一位萌新路过", isRegexp: false, searchPage: true, mainPage: true, leaderboard: true, timeLine: true, recommand: true, reply: true }]; GM_setValue('blacklist', JSON.stringify(blacklist)); } else { // Parse the stored JSON string back to a JavaScript object blacklist = JSON.parse(blacklist); // Upgrade script: add the 'isRegexp' property to all items in the blacklist for (let i = 0; i < blacklist.length; i++) { if (!('isRegexp' in blacklist[i])) { blacklist[i].isRegexp = false; } } // Save the updated blacklist back to GM storage GM_setValue('blacklist', JSON.stringify(blacklist)); } let blockPageTypes = { searchPage: { urlIncludes: 'search.bilibili.com', matchPairs: [ { matchSelector: "div.bili-video-card__info--right", parentSelector: 'div.col_3' }, { matchSelector: "div.media-card-content", parentSelector: "div.media-card" }, ], cssModifications: {} }, mainPage: { urlIncludes: 'www.bilibili.com', matchPairs: [ { matchSelector: "div.bili-video-card__info--right", parentSelector: "div.bili-video-card" }, { matchSelector: "div.bili-video-card__info--right", parentSelector: "div.feed-card" }, { matchSelector: "div.bili-video-card__info--right", parentSelector: "div.floor-single-card" }, ], cssModifications: '.recommended-container_floor-aside .container>*:nth-of-type(n + 8) {margin-top: 0px !important;}' }, leaderboard: { urlIncludes: 'www.bilibili.com/v/popular', matchPairs: [ { matchSelector: "div.video-card__info", parentSelector: "div.video-card" }, ], }, timeLine: { urlIncludes: 't.bilibili.com', matchPairs: [ { matchSelector: "div.bili-dyn-content", parentSelector: "div.bili-dyn-list__item" }, ], }, recommand: { urlIncludes: 'www.bilibili.com/video/BV', matchPairs: [ { matchSelector: "div.info", parentSelector: "div.video-page-card-small" }, ], }, reply: { urlIncludes: 'www.bilibili.com/video/BV', matchPairs: [ { matchSelector: "div.root-reply", parentSelector: "div.content-warp" }, { matchSelector: "span.reply-content-container.sub-reply-content", parentSelector: "div.sub-reply-item" }, ], }, }; let prepareRegex = function() { // Find the page info for the current URL let pageInfos = []; for (let pageType in blockPageTypes) { if (window.location.href.includes(blockPageTypes[pageType].urlIncludes)) { let pageInfo = blockPageTypes[pageType]; pageInfo.name = pageType; pageInfos.push(pageInfo); } } let containsStrings = []; if (pageInfos.length > 0) { pageInfos.forEach(pageInfo => { // Filter the blacklist to get the keywords that should be active on this page let activeKeywords = blacklist.filter(entry => entry[pageInfo.name]) .map(entry => entry.isRegexp ? entry.keyword : entry.keyword.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&')) .join('|'); if (activeKeywords) { containsStrings.push({ pageInfo: pageInfo, containsString: ":containsRegex('" + activeKeywords + "')" }); } }); return containsStrings; }; } let block_blacklist = function(prepArray){ // Block AD $("svg.bili-video-card__info--ad").parents("div.bili-video-card").hide(); $("svg.bili-video-card__info--ad").parents("div.feed-card").hide(); if (prepArray.length > 0) { prepArray.forEach(prep => { //console.log(prep.pageInfo.name) // Now hide all matching elements on the page prep.pageInfo.matchPairs.forEach(pair => { $(pair.matchSelector + prep.containsString).parents(pair.parentSelector).hide(); }); // Apply CSS modifications if(prep.pageInfo.cssModifications){ $('<style>').prop('type', 'text/css').html(prep.pageInfo.cssModifications).appendTo('head'); } }); } } let reblock_blacklist = function(){ let prepArray = prepareRegex(); block_blacklist(prepArray); } // Create the floating "B" button let buttonB = $('<button>', { text: '屏蔽', css: { position: 'fixed', bottom: '20px', left: '20px', zIndex: 9999, backgroundColor: 'gray', color: 'white', borderRadius: '8px', padding: '10px', border: '2px solid white' }, click: function() { let keyword = prompt('输入屏蔽关键词:'); if (keyword) { // Add the keyword with all pages selected by default blacklist.push({ keyword: keyword, isRegexp: false, searchPage: true, mainPage: true, leaderboard: true, timeLine: true, recommand: true, reply: true }); // Save the updated blacklist to GM storage GM_setValue('blacklist', JSON.stringify(blacklist)); reblock_blacklist(); } } }); // Create the floating "E" button let buttonE = $('<button>', { text: '屏蔽词管理', css: { position: 'fixed', bottom: '20px', left: '80px', zIndex: 9999, backgroundColor: 'gray', color: 'white', borderRadius: '8px', padding: '10px', border: '2px solid white' }, click: function() { if ($('#modal').length > 0) { $('#modal').remove(); return; } // Build a custom modal dialog let modal = $('<div>', { id: 'modal', css: { position: 'fixed', width: '700px', height: '400px', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', backgroundColor: '#fff', padding: '20px', zIndex: 9999, overflowY: 'auto', border: '2px solid #000' } }); // Add title let title = $('<h2>', { text: '屏蔽词管理', css: { textAlign: 'center', margin: '20px 0' } }); modal.append(title); // Add exit button let exitButton = $('<button>', { text: '❌', css: { position: 'absolute', top: '10px', right: '10px' }, click: function() { modal.remove(); } }); modal.append(exitButton); // Add each keyword to the modal with a '➖' button and checkboxes for each page type blacklist.forEach(function(entry, index) { let keyword = $('<span>', { text: entry.keyword, css: { display: 'inline-block', width: '100px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', verticalAlign: 'middle' } }); let item = $('<div>', { css: { marginBottom: '10px' } }); item.append(keyword); let regexpCheckbox = $('<input>', { type: 'checkbox', checked: entry.isRegexp, change: function() { // Update the blacklist when the checkbox is toggled entry.isRegexp = this.checked; GM_setValue('blacklist', JSON.stringify(blacklist)); reblock_blacklist(); } }); let label = $('<label>', { text: '正则表达式', css: { marginLeft: '10px' } }); label.prepend(regexpCheckbox); item.append(label); let removeButton = $('<button>', { text: '➖', css: { marginLeft: '10px' }, click: function() { // Get the keyword of the current item let currentKeyword = entry.keyword; // Filter out the item with the current keyword blacklist = blacklist.filter(function(item) { return item.keyword !== currentKeyword; }); // Save the updated blacklist to GM storage GM_setValue('blacklist', JSON.stringify(blacklist)); // Remove this keyword from the modal item.remove(); reblock_blacklist(); } }); item.append(removeButton); // Add a checkbox for each page type pageTypes.forEach(function(pageType) { let checkbox = $('<input>', { type: 'checkbox', checked: entry[pageType], change: function() { // Update the blacklist when a checkbox is toggled entry[pageType] = this.checked; GM_setValue('blacklist', JSON.stringify(blacklist)); reblock_blacklist(); } }); let label = $('<label>', { text: pageTypesCN[pageType], css: { marginLeft: '10px' } }); label.prepend(checkbox); item.append(label); }); modal.append(item); }); // Add save button let saveButton = $('<button>', { text: '✔️', css: { display: 'block', margin: '0 auto', marginTop: '10px' }, click: function() { modal.remove(); location.reload(); // refresh the page } }); modal.append(saveButton); $('body').append(modal); } }); //define containsRegex $.expr[":"].containsRegex = $.expr.createPseudo(function(arg) { var regexp = new RegExp(arg, 'i'); return function(elem) { return regexp.test($(elem).text()); }; }); let prepArray = prepareRegex(); $('body').append(buttonB); $('body').append(buttonE); // Run the initial blacklist block block_blacklist(prepArray); let running = false; const observer = new MutationObserver(function(mutationsList, observer) { if (!running) { running = true; requestAnimationFrame(function() { block_blacklist(prepArray); running = false; }); } }); observer.observe(document.body, { childList: true, subtree: true }); })();