Blocks and hides Google advertisements on all websites
// ==UserScript==
// @name Ad Hider
// @namespace BBSmalls
// @version 1.3.1
// @description Blocks and hides Google advertisements on all websites
// @author BBSmalls [3908857]
// @match https://*/*
// @match http://*/*
// @grant GM_addStyle
// @grant GM_xmlhttpRequest
// @run-at document-start
// @exclude https://example.com/*
// ==/UserScript==
(function () {
'use strict';
// ── Ad source domains to block ────────────────────────────────────────────
const BLOCKED_SOURCES = [
'googlesyndication.com',
'doubleclick.net',
'googleadservices.com',
'pagead2.googlesyndication.com',
'adservice.google.com',
];
function isAdSource(src) {
if (!src) return false;
return BLOCKED_SOURCES.some(domain => src.includes(domain));
}
// ── Block ad <script> tags before they execute ────────────────────────────
// Watch for script/iframe elements being added and kill them if they
// point to ad networks. At document-start this runs before AdSense loads.
const scriptObserver = new MutationObserver(mutations => {
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (node.nodeType !== 1) continue;
// Block <script src="...googlesyndication...">
if (node.tagName === 'SCRIPT' && isAdSource(node.src)) {
node.type = 'javascript/blocked';
node.src = '';
node.remove();
}
// Block <iframe src="...doubleclick...">
if (node.tagName === 'IFRAME' && isAdSource(node.src)) {
node.remove();
}
// Also check descendants (e.g. a div wrapper inserted with children)
node.querySelectorAll?.('script, iframe').forEach(child => {
if (isAdSource(child.src)) {
child.type = 'javascript/blocked';
child.src = '';
child.remove();
}
});
}
}
});
scriptObserver.observe(document.documentElement, {
childList: true,
subtree: true,
});
// ── CSS layer — instant hide for anything that still renders ──────────────
GM_addStyle(`
ins.adsbygoogle,
ins[data-anchor-status],
ins[data-side-rail-status],
ins[data-adsbygoogle-status],
ins[data-ad-status],
ins[data-ad-client],
.google-auto-placed,
#ad_unit,
[class*="GoogleCreativeContainerClass"],
[class*="adsbygoogle"],
[id*="aswift_"],
[id*="google_ads"],
[id*="div-gpt-ad"],
iframe[src*="googlesyndication"],
iframe[src*="doubleclick"],
iframe[src*="googleadservices"],
iframe#ad_iframe,
iframe[id*="ad_iframe"] {
display: none !important;
visibility: hidden !important;
height: 0 !important;
max-height: 0 !important;
overflow: hidden !important;
pointer-events: none !important;
}
`);
// ── DOM sweep backstop ────────────────────────────────────────────────────
const AD_SELECTORS = [
'ins.adsbygoogle', 'ins[data-anchor-status]', 'ins[data-side-rail-status]',
'ins[data-adsbygoogle-status]', 'ins[data-ad-status]', 'ins[data-ad-client]',
'.google-auto-placed', '#ad_unit', '[class*="GoogleCreativeContainerClass"]',
'[class*="adsbygoogle"]', '[id*="aswift_"]', '[id*="google_ads"]',
'iframe[src*="googlesyndication"]', 'iframe[src*="doubleclick"]',
'iframe[src*="googleadservices"]', 'iframe#ad_iframe',
].join(', ');
function removeAds() {
document.querySelectorAll(AD_SELECTORS).forEach(el => el.remove());
}
document.addEventListener('DOMContentLoaded', removeAds);
window.addEventListener('load', () => {
removeAds();
let ticks = 0;
const poll = setInterval(() => {
removeAds();
if (++ticks >= 15) clearInterval(poll);
}, 1000);
});
})();