您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
Hide specified Bilibili elements using MutationObserver
当前为
// ==UserScript== // @name 隐藏b站视频详情页右侧的"活动推广"和"大家围观的直播" // @name:en Hide promotions on Bilibili's video details page // @namespace http://tampermonkey.net/ // @version 0.1.14 // @description Hide specified Bilibili elements using MutationObserver // @description:en Hide specified Bilibili elements using MutationObserver // @author aspen138 // @match *://www.bilibili.com/video/* // @match *://www.bilibili.com/ // @icon https://www.bilibili.com/favicon.ico // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; // Enhanced function to thoroughly hide elements function hideElement(element) { if (!element) return; // Apply more aggressive hiding styles const hideStyles = { 'display': 'none !important', 'visibility': 'hidden !important', 'opacity': '0 !important', 'background': 'white !important', 'color': 'white !important', 'pointer-events': 'none !important', 'height': '0 !important', 'width': '0 !important', 'overflow': 'hidden !important', 'position': 'absolute !important', 'z-index': '-9999 !important', 'clip': 'rect(0, 0, 0, 0) !important' }; // Apply styles using both direct style and cssText for maximum effectiveness Object.entries(hideStyles).forEach(([property, value]) => { element.style.setProperty(property, value.replace(' !important', ''), 'important'); }); // Hide all child elements recursively Array.from(element.children).forEach(child => { hideElement(child); }); // Remove any inline event listeners element.onclick = null; element.onmouseover = null; element.onmouseenter = null; element.onmouseleave = null; } // Function to handle all target elements function hideAllTargetElements() { const targetElements = [ '#slide_ad', '#right-bottom-banner', '.pop-live-small-mode.part-1', '.ad-floor-cover.b-img', '#bannerAd', '.vcd', 'a[data-loc-id="4331"]', '#activity_vote', '.ad-report.video-card-ad-small', '.ad-report.ad-floor-exp', '.slide-ad-exp', '.activity-m-v1.act-now', '.video-page-special-card-small', '.btn-ad', // New homepage ad element 'div[data-v-2ce37bb8].btn-ad' // More specific selector for the homepage ad ]; targetElements.forEach(selector => { const elements = document.querySelectorAll(selector); elements.forEach(hideElement); }); } // Create a more specific MutationObserver const observer = new MutationObserver((mutations) => { mutations.forEach(mutation => { // Check for added nodes if (mutation.addedNodes.length) { mutation.addedNodes.forEach(node => { if (node.nodeType === 1) { // Element node // Check if the added node is a target element if (node.id === 'slide_ad' || node.classList.contains('slide-ad-exp') || node.classList.contains('ad-report') || node.classList.contains('activity-m-v1') || node.classList.contains('video-page-special-card-small') || node.classList.contains('btn-ad')) { // Added new class check hideElement(node); } // Also check children of added nodes const targetElements = node.querySelectorAll('#slide_ad, .slide-ad-exp, .ad-report, .activity-m-v1, .video-page-special-card-small, .btn-ad'); targetElements.forEach(hideElement); } }); } // Check for attribute changes if (mutation.type === 'attributes') { const element = mutation.target; if (element.id === 'slide_ad' || element.classList.contains('slide-ad-exp') || element.classList.contains('ad-report') || element.classList.contains('activity-m-v1') || element.classList.contains('video-page-special-card-small') || element.classList.contains('btn-ad')) { // Added new class check hideElement(element); } } }); }); // Configure the observer to watch for everything const observerConfig = { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }; // Initial hiding hideAllTargetElements(); // Start observing observer.observe(document.body, observerConfig); // Set up periodic checks just in case const checkInterval = setInterval(hideAllTargetElements, 1000); // Cleanup after 30 seconds setTimeout(() => { clearInterval(checkInterval); observer.disconnect(); // Optionally disconnect the observer after cleanup }, 30000); })();