// ==UserScript== // @name 4khd 广告屏蔽 // @namespace https://viayoo.com // @version 0.45 // @description 移除4khd广告 // @author Via // @license MIT // @match *://*.4khd.com/* // @match *://*.xxtt.ink/* // @match *://*.uuss.uk/* // @run-at document-start // @grant none // ==/UserScript== (function() { 'use strict'; const CONFIG = { AD_SELECTORS: '.exo_wrapper,.popup,.centbtd,.exo-native-widget,.exo-native-widget-outer-container,ins[data-processed="true"],.popup-iframe,ins.adsbynetwork', BLOCK_URL_PATTERNS: [/magsrv|pemsrv|ad-provider|exoclick|ads?[0-9]*\./i], BLOCK_CONTENT_PATTERNS: [/magsrv|pemsrv|ad-provider|exoclick|ads?[0-9]*\./i, /ad-provider\.js/i, /AdProvider/i, /RocketBrowser/i, /data-rocketlazyloadscript/i], STORAGE_KEYS: ['storedResult', 'inData', 'extranks', 'contentSize', 'Better', 'inData2', 'BetterJsPop_lastOpenedAt'], DEBOUNCE_DELAY: 50, CLEAR_INTERVAL: 2000 }; const blockedGlobals = ['AdProvider', 'adConfig', 'popMagic', 'RocketBrowser', 'exoclick']; blockedGlobals.forEach(prop => { Object.defineProperty(window, prop, { value: [], writable: false, configurable: false }); }); location.reload = () => false; if (navigator.serviceWorker?.controller) { navigator.serviceWorker.controller.postMessage = () => {}; navigator.serviceWorker.register = () => Promise.reject(); } const originalFetch = window.fetch; window.fetch = function(...args) { const url = typeof args[0] === 'string' ? args[0] : args[0]?.url || ''; if (CONFIG.BLOCK_URL_PATTERNS.some(p => p.test(url)) || url.includes('venor.php') || url.includes('popunder1000.js') || url.includes('popup')) { return Promise.resolve(new Response('', { status: 200 })); } return originalFetch.apply(this, args); }; const origOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(method, url) { if (typeof url === 'string' && (CONFIG.BLOCK_URL_PATTERNS.some(p => p.test(url)) || url.includes('venor.php') || url.includes('popup'))) { this._blocked = true; return; } return origOpen.apply(this, arguments); }; const origOpenWin = window.open; window.open = function(url = '', target = '') { if (/magsrv|ads?|pop|splash\.php|syndication/i.test(url) || ['_blank', '_self'].includes(target) || url === document.URL || url === document.referrer) { return null; } return origOpenWin.apply(this, arguments); }; const origCreateElement = document.createElement; document.createElement = function(tagName) { const element = origCreateElement.call(this, tagName); if (tagName.toLowerCase() === 'iframe') { return new Proxy(element, { set: function(target, prop, value) { if ((prop === 'src' || prop === 'className') && typeof value === 'string' && (value.includes('pop') || value.includes('ad') || CONFIG.BLOCK_URL_PATTERNS.some(p => p.test(value)) || value.includes('popup-iframe'))) { return true; } target[prop] = value; return true; }, get: function(target, prop) { if (prop === 'style') { return new Proxy(target.style, { set: function(styleTarget, styleProp, styleValue) { if ((styleProp === 'position' && styleValue === 'fixed') || (styleProp === 'zIndex' && styleValue > 9999) || (styleProp === 'width' && (styleValue === '100%' || styleValue === '100vw')) || (styleProp === 'height' && (styleValue === '100%' || styleValue === '100vh'))) { return true; } styleTarget[styleProp] = styleValue; return true; } }); } return target[prop]; } }); } if (tagName.toLowerCase() === 'a') { element.click = () => {}; element.dispatchEvent = () => false; } return element; }; document.addEventListener('click', e => { if (!e.isTrusted) { e.stopImmediatePropagation(); e.preventDefault(); return false; } }, true); const blockScript = node => { if (node.tagName !== 'SCRIPT') return false; const src = node.src || ''; const txt = node.textContent || ''; const shouldBlock = CONFIG.BLOCK_CONTENT_PATTERNS.some(re => re.test(src) || re.test(txt)) || node.hasAttribute?.('data-rocketlazyloadscript') || /popMagic|popunder1000\.js|venor\.php|ad-provider\.js|adConfig|popup/i.test(txt); if (shouldBlock) { node.textContent = ''; node.remove?.(); return true; } return false; }; const removeFullScreenIframes = () => { document.querySelectorAll('iframe').forEach(iframe => { const style = getComputedStyle(iframe); const src = iframe.src || ''; const className = iframe.className || ''; const isFullScreen = (style.position === 'fixed' && (style.top === '0px' || style.top === '0') && (style.left === '0px' || style.left === '0') && (style.width === '100%' || style.width === '100vw' || parseInt(style.width) >= window.innerWidth) && (style.height === '100%' || style.height === '100vh' || parseInt(style.height) >= window.innerHeight) && parseInt(style.zIndex) > 9999); const isPopupIframe = (className.includes('popup-iframe') || src.includes('pop') || CONFIG.BLOCK_URL_PATTERNS.some(p => p.test(src))); if (isFullScreen || isPopupIframe) iframe.remove(); }); }; const clearStorage = () => { CONFIG.STORAGE_KEYS.forEach(key => localStorage.removeItem(key)); document.cookie.split(';').forEach(cookie => { const name = cookie.split('=')[0].trim(); if (name.startsWith('zone-cap-') || /ad|track|pop/i.test(name)) { document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=.${location.hostname}`; document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`; } }); }; const removeAds = () => { document.querySelectorAll(CONFIG.AD_SELECTORS).forEach(el => el.remove?.()); removeFullScreenIframes(); document.querySelectorAll('*').forEach(el => { if (el.tagName === 'DIV' || el.tagName === 'IFRAME') { const style = getComputedStyle(el); if (style.position === 'fixed' && style.zIndex > 9999 && (el.className.includes('popup') || el.id.includes('popup'))) { el.remove(); } } }); clearStorage(); }; let removeTimer = 0; const debouncedRemoveAds = () => { clearTimeout(removeTimer); removeTimer = setTimeout(removeAds, CONFIG.DEBOUNCE_DELAY); }; const observer = new MutationObserver(mutations => { let shouldRemoveAds = false; for (const mutation of mutations) { for (const node of mutation.addedNodes) { if (node.nodeType !== 1) continue; if (blockScript(node)) { shouldRemoveAds = true; continue; } if (node.tagName === 'IFRAME') { const src = node.src || ''; const className = node.className || ''; if (className.includes('popup-iframe') || CONFIG.BLOCK_URL_PATTERNS.some(p => p.test(src))) { node.remove(); shouldRemoveAds = true; continue; } } const scripts = node.querySelectorAll?.('script') || []; for (const script of scripts) { if (blockScript(script)) shouldRemoveAds = true; } const iframes = node.querySelectorAll?.('iframe') || []; for (const iframe of iframes) { const src = iframe.src || ''; const className = iframe.className || ''; if (className.includes('popup-iframe') || CONFIG.BLOCK_URL_PATTERNS.some(p => p.test(src))) { iframe.remove(); shouldRemoveAds = true; } } if (node.matches?.(CONFIG.AD_SELECTORS) || node.querySelector?.(CONFIG.AD_SELECTORS)) shouldRemoveAds = true; } if (mutation.type === 'attributes') { const target = mutation.target; if (target.tagName === 'IFRAME' && (mutation.attributeName === 'style' || mutation.attributeName === 'class')) { const style = getComputedStyle(target); if (style.position === 'fixed' && style.zIndex > 9999) { target.remove(); shouldRemoveAds = true; } } } } if (shouldRemoveAds) debouncedRemoveAds(); }); const init = () => { if (document.body) { observer.observe(document, { childList: true, subtree: true, attributes: true, attributeFilter: ['class', 'id', 'style', 'src'] }); removeAds(); clearStorage(); setInterval(() => { removeAds(); clearStorage(); }, CONFIG.CLEAR_INTERVAL); window.addEventListener('resize', debouncedRemoveAds); } else setTimeout(init, 10); }; const origAppendChild = Node.prototype.appendChild; Node.prototype.appendChild = function(node) { if ((node.tagName === 'SCRIPT' && blockScript(node)) || (node.tagName === 'IFRAME' && ((node.className || '').includes('popup-iframe') || CONFIG.BLOCK_URL_PATTERNS.some(p => p.test(node.src || ''))))) return node; return origAppendChild.call(this, node); }; const origInsertBefore = Node.prototype.insertBefore; Node.prototype.insertBefore = function(newNode, referenceNode) { if ((newNode.tagName === 'SCRIPT' && blockScript(newNode)) || (newNode.tagName === 'IFRAME' && ((newNode.className || '').includes('popup-iframe') || CONFIG.BLOCK_URL_PATTERNS.some(p => p.test(newNode.src || ''))))) return newNode; return origInsertBefore.call(this, newNode, referenceNode); }; if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init); else init(); })();