Remove Promotion Element at Reddit Site

Removes the promotion element from the page

目前為 2024-12-24 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Remove Promotion Element at Reddit Site
// @namespace    http://tampermonkey.net/
// @version      1.0.4
// @description  Removes the promotion element from the page
// @author       aspen138
// @match        *://www.reddit.com/*
// @icon         data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAQlBMVEVHcEz/RQD/RQD/QgD/RQD/RQD/RQD/RQD/RQD/RQD/////MgD/OgD/s5//z8P/a0T/5d3/VyH/iGr/qJP/mYD/+vcCA1U1AAAACnRSTlMAJP//y5WUn+ElsgVe0gAAAJFJREFUGJVtT1sOwyAMy0JpIa/C2t3/qjNQaT+zkMAmD5sIqLkwl1zpwcEPjsW3ScxMefv9m7u3WVNXdXJ9Q+BKGYRN+62miXmnMvg7WotT8SzE6ZQHHzkTL+HuIv2SKRTWkHCRC5eiJWOCSJvnNgzFWrtQ4iGuY+0wZt0jHFuWeVhPpmpwsf0PR/TaR/x9xv8CYoYGnu4Mr1kAAAAASUVORK5CYII=
// @grant        none
// @license      MIT
// ==/UserScript==






(function() {
    'use strict';

    /**
     * Recursively searches through regular DOM and Shadow DOM roots for elements
     * matching a given selector.
     * @param {string} selector - The CSS selector to look for.
     * @returns {Element[]} - An array of matching elements.
     */
    function deepQuerySelectorAll(selector) {
        const nodes = [];

        /**
         * Searches a single node (and its children) for matching elements,
         * including Shadow DOM children if present.
         * @param {Node} node
         */
        function searchInNode(node) {
            // If this node has a shadow root, search within it
            if (node.shadowRoot) {
                const matches = node.shadowRoot.querySelectorAll(selector);
                if (matches.length > 0) {
                    nodes.push(...matches);
                }
                Array.from(node.shadowRoot.children).forEach(searchInNode);
            }

            // Continue searching regular child nodes
            Array.from(node.children).forEach(searchInNode);
        }

        // Start the search from the document root
        searchInNode(document);
        return nodes;
    }

    /**
     * Removes the error banner from the DOM if present.
     */
    function removeErrorBanner() {
        const banners = deepQuerySelectorAll('div.banner.error');
        if (banners.length > 0) {
            banners.forEach(banner => banner.remove());
            console.log("Server Error Banner has been removed.");
        }
    }

    /**
     * Sets up a MutationObserver to detect changes in the DOM
     * and trigger the removeErrorBanner function.
     */
    function initErrorBannerObserver() {
        const observer = new MutationObserver(() => {
            removeErrorBanner();
        });

        observer.observe(document, { childList: true, subtree: true });
    }

    /**
     * Removes elements that match any of the given CSS selectors.
     * @param {string[]} selectors - Array of CSS selectors for unwanted elements.
     */
    function removePromoElements(selectors) {
        selectors.forEach(selector => {
            const promoElements = document.querySelectorAll(selector);
            promoElements.forEach(element => {
                element.remove();
                console.log('Promotion element removed:', selector);
            });
        });
    }

    /**
     * Hides all links containing the specific rel attribute.
     * @param {string} relContent - The exact rel string to look for.
     */
    function hideLinksByRel(relContent) {
        const links = document.querySelectorAll('a');
        links.forEach(link => {
            if (link.getAttribute('rel') === relContent) {
                link.style.display = 'none';
                console.log(`Link with rel "${relContent}" hidden`);
            }
        });
    }

    /**
     * Sets up a MutationObserver to detect changes in the document body
     * and re-run the removal/hiding functions for promotional elements.
     */
    function initPromoObserver() {
        const promoObserver = new MutationObserver(() => {
            removePromoElements(promoSelectors);
            hideLinksByRel('noopener nofollow sponsored');
        });

        promoObserver.observe(document.body, {
            childList: true,
            subtree: true
        });
    }

    // ==============================
    //          MAIN EXECUTION
    // ==============================
    // Start observing the document for error banners
    initErrorBannerObserver();

    // Initial removal of the error banner if present
    removeErrorBanner();

    // Wait for the page to load fully before removing promotional elements
    window.addEventListener('load', function() {
        // Define your promotional selectors here
        const promoSelectors = [
            'a.w-100.block.h-100.cursor-pointer',
            'shreddit-ad-post.promotedlink',
            'shreddit-dynamic-ad-link',
            'shreddit-comments-page-ad.promotedlink' // Additional selector
        ];

        // Remove or hide elements matching the promotional selectors or rel attributes
        removePromoElements(promoSelectors);
        hideLinksByRel('noopener nofollow sponsored');

        // Observe for further changes to remove newly inserted promo elements
        initPromoObserver();
    });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址