Ad Hider

Blocks and hides Google advertisements on all websites

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

Advertisement:

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

Advertisement:

// ==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);
    });

})();