隐藏b站视频详情页右侧的"活动推广"和"大家围观的直播"

Hide specified Bilibili elements using MutationObserver

Versione datata 27/10/2024. Vedi la nuova versione l'ultima versione.

// ==UserScript==
// @name         隐藏b站视频详情页右侧的"活动推广"和"大家围观的直播"
// @name:en      Hide the promotion on the right side of Bilibili's video details page
// @namespace    http://tampermonkey.net/
// @version      0.1.12
// @description  Hide specified Bilibili elements using MutationObserver
// @description:en  Hide specified Bilibili elements using MutationObserver
// @author       aspen138
// @match        *://www.bilibili.com/video/*
// @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'
        ];

        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')) {
                            hideElement(node);
                        }
                        // Also check children of added nodes
                        const targetElements = node.querySelectorAll('#slide_ad, .slide-ad-exp, .ad-report');
                        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')) {
                    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);
    }, 30000);
})();