Removes the promotion element from the page
当前为
// ==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();
});
})();