增强版广告屏蔽框架,支持多种选择器和调试功能
// ==UserScript==
// @name 广告屏蔽框架
// @namespace http://tampermonkey.net/
// @version 1.03
// @description 增强版广告屏蔽框架,支持多种选择器和调试功能
// @author veip007
// @match *://*/*
// @grant GM_log
// @grant GM_notification
// @run-at document-end
// @license LGPL-2.0-or-later
// ==/UserScript==
(function() {
'use strict';
// ========== 配置区域 ==========
// 在这里填入您要屏蔽的广告选择器
const AD_SELECTORS = [
// ID选择器
'#footer',
// 类选择器
'.sptable_do_not_remove',
'.xqbj-list-rows-placard',
'.ftad-ct',
'.sptable_do_not_remove.f_one',
// 属性选择器
'[data-ad]',
'[class="ad"]',
// 复合选择器
'div.ad-container',
'div[class="banner"]',
// 在此处添加更多广告选择器...
];
// 需要隐藏而不是移除的元素选择器
const HIDE_SELECTORS = [
'.topRedirectTipsFloat'
];
// 高级配置选项
const CONFIG = {
// 是否显示移除通知 true 或者 false
showNotifications: false,
// 是否记录详细日志到控制台
enableLogging: false,
// 是否监控动态加载的内容
monitorDynamicContent: true,
// 检查间隔(毫秒)
checkInterval: 2000,
// 是否移除父级容器(如果广告容器有父级包装)
removeParentContainers: true,
// 父级选择器(如果知道特定的父级容器)
parentSelectors: [
'.ad-wrapper',
'.banner-container'
],
// 白名单域名
whitelistDomains: [
'google.com',
/c\w.\w{5,6}.\w{3}/ , //正则表示法
'github.com'
]
};
// ========== 配置结束 ==========
// 统计信息
const stats = {
totalRemoved: 0,
lastCheck: 0
};
// 设定hideElements函数
function hideElements() {
let hiddenCount = 0;
HIDE_SELECTORS.forEach(selector => {
const elements = document.querySelectorAll(selector);
elements.forEach(element => {
if (document.body.contains(element)) {
element.style.display = 'none';
element.style.visibility = 'hidden';
element.style.opacity = '0';
hiddenCount++;
}
});
});
return hiddenCount;
}
// 隐藏特定元素
const hiddenCount = hideElements();
removedCount += hiddenCount; // 注意:这里我们把隐藏也算作移除,因为都是从视觉上移除
// 添加强力移除函数
function forceRemoveStubbornElements() {
const stubbornElements = [
'.topRedirectTipsFloat'
];
let removedCount = 0;
stubbornElements.forEach(selector => {
// 方法1: 标准移除
document.querySelectorAll(selector).forEach(el => {
if (el && el.parentNode) {
try {
el.remove();
removedCount++;
} catch (e) {
try {
el.parentNode.removeChild(el);
removedCount++;
} catch (e2) {
// 最终手段:隐藏
el.style.display = 'none';
el.style.visibility = 'hidden';
el.style.opacity = '0';
el.style.height = '0';
el.style.width = '0';
el.style.overflow = 'hidden';
}
}
}
});
});
return removedCount;
}
// 修改主屏蔽函数
function removeAdContainers() {
let removedCount = 0;
const currentTime = Date.now();
if (currentTime - stats.lastCheck < 500) {
return removedCount;
}
stats.lastCheck = currentTime;
// 原有移除逻辑
AD_SELECTORS.forEach(selector => {
try {
const elements = document.querySelectorAll(selector);
elements.forEach(element => {
if (document.body.contains(element) && isElementVisible(element)) {
element.remove();
removedCount++;
}
});
} catch (error) {
if (CONFIG.enableLogging) {
console.error(`处理选择器 "${selector}" 时出错:`, error);
}
}
});
// 强力移除顽固元素
const stubbornRemoved = forceRemoveStubbornElements();
removedCount += stubbornRemoved;
return removedCount;
}
// 检查元素是否可见
function isElementVisible(element) {
const style = window.getComputedStyle(element);
return style.display !== 'none' &&
style.visibility !== 'hidden' &&
style.opacity !== '0' &&
element.offsetWidth > 0 &&
element.offsetHeight > 0;
}
// 移除父级容器
function removeParentContainers(element, originalSelector) {
let currentElement = element.parentElement;
let levelsChecked = 0;
const maxLevels = 5; // 最多向上检查5层
while (currentElement && levelsChecked < maxLevels) {
// 检查父级是否包含广告特征
const parentHtml = currentElement.innerHTML.toLowerCase();
const isAdParent = parentHtml.includes('ad') ||
parentHtml.includes('banner') ||
parentHtml.includes('sponsor') ||
currentElement.id.includes('ad') ||
currentElement.className.includes('ad');
if (isAdParent && document.body.contains(currentElement)) {
currentElement.remove();
if (CONFIG.enableLogging) {
console.log(`已移除广告父级容器 (${originalSelector} 的父级)`, currentElement);
}
break;
}
currentElement = currentElement.parentElement;
levelsChecked++;
}
}
// 显示通知
function showNotification(message) {
// 移除之前的通知
const existingNote = document.getElementById('adblocker-notification');
if (existingNote) existingNote.remove();
const notification = document.createElement('div');
notification.id = 'adblocker-notification';
notification.innerHTML = `
<div style="
position: fixed;
top: 20px;
right: 20px;
background: #4CAF50;
color: white;
padding: 12px 16px;
border-radius: 6px;
font-size: 14px;
z-index: 10000;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
max-width: 300px;
animation: slideIn 0.3s ease-out;
font-family: Arial, sans-serif;
cursor: pointer;
">
<div style="display: flex; align-items: center; gap: 8px;">
<span style="font-size: 16px;">🛡️</span>
<span>${message}</span>
</div>
</div>
<style>
@keyframes slideIn {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
</style>
`;
notification.addEventListener('click', () => {
notification.remove();
});
document.body.appendChild(notification);
// 5秒后自动隐藏
setTimeout(() => {
if (document.body.contains(notification)) {
notification.style.opacity = '0';
notification.style.transform = 'translateX(100%)';
setTimeout(() => {
if (document.body.contains(notification)) {
notification.remove();
}
}, 300);
}
}, 5000);
}
// 添加调试面板
function createDebugPanel() {
const panel = document.createElement('div');
panel.id = 'adblock-debug-panel';
panel.innerHTML = `
<div style="
position: fixed;
bottom: 20px;
right: 20px;
background: #333;
color: white;
padding: 15px;
border-radius: 8px;
font-size: 12px;
z-index: 9999;
font-family: Arial, sans-serif;
max-width: 300px;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
<strong>广告屏蔽调试面板</strong>
<button id="adblock-close-panel" style="background: none; border: none; color: white; cursor: pointer;">×</button>
</div>
<div>已屏蔽: <span id="adblock-counter">0</span> 个元素</div>
<div style="margin-top: 10px;">
<button id="adblock-manual-check" style="background: #4CAF50; color: white; border: none; padding: 5px 10px; border-radius: 3px; cursor: pointer; margin-right: 5px;">手动检查</button>
<button id="adblock-test-selectors" style="background: #2196F3; color: white; border: none; padding: 5px 10px; border-radius: 3px; cursor: pointer;">测试选择器</button>
</div>
</div>
`;
document.body.appendChild(panel);
// 更新计数器
const updateCounter = () => {
const counter = document.getElementById('adblock-counter');
if (counter) {
counter.textContent = stats.totalRemoved;
}
};
// 关闭面板
document.getElementById('adblock-close-panel').addEventListener('click', () => {
panel.remove();
});
// 手动检查
document.getElementById('adblock-manual-check').addEventListener('click', () => {
const count = removeAdContainers();
updateCounter();
showNotification(`手动检查完成,屏蔽了 ${count} 个元素`);
});
// 测试选择器
document.getElementById('adblock-test-selectors').addEventListener('click', () => {
testSelectors();
});
// 初始更新计数器
updateCounter();
return panel;
}
// 测试选择器功能
function testSelectors() {
console.group('广告选择器测试');
AD_SELECTORS.forEach(selector => {
const elements = document.querySelectorAll(selector);
console.log(`选择器 "${selector}": 找到 ${elements.length} 个元素`);
elements.forEach((element, index) => {
console.log(` [${index}]`, element);
});
});
console.groupEnd();
showNotification(`选择器测试完成,查看控制台了解详情`);
}
// 检查是否在白名单域名上
function isWhitelisted() {
const currentDomain = window.location.hostname;
return CONFIG.whitelistDomains.some(domain =>
currentDomain.includes(domain)
);
}
// 初始化脚本
function init() {
// 如果在白名单域名上,不运行脚本
if (isWhitelisted()) {
if (CONFIG.enableLogging) {
console.log('当前域名在白名单中,广告屏蔽已跳过');
}
return;
}
if (CONFIG.enableLogging) {
console.log('广告屏蔽框架已启动');
console.log('监控的广告选择器:', AD_SELECTORS);
}
// 创建调试面板
if (CONFIG.enableLogging) {
setTimeout(() => {
createDebugPanel();
}, 2000);
}
// 页面加载后立即执行一次
setTimeout(() => {
const count = removeAdContainers();
if (count > 0 && CONFIG.enableLogging) {
console.log(`初始扫描移除了 ${count} 个广告元素`);
}
}, 1000);
// 监听DOM变化,处理动态加载的广告
if (CONFIG.monitorDynamicContent) {
const observer = new MutationObserver(function(mutations) {
let shouldCheck = false;
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (node.nodeType === 1) { // Element node
// 检查新增的元素是否匹配任何选择器
AD_SELECTORS.forEach(selector => {
try {
if (node.matches && node.matches(selector)) {
shouldCheck = true;
}
// 检查子元素
if (node.querySelectorAll && node.querySelectorAll(selector).length > 0) {
shouldCheck = true;
}
} catch (e) {
// 忽略选择器语法错误
}
});
}
});
});
if (shouldCheck) {
setTimeout(removeAdContainers, 100);
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
}
// 设置定时检查(针对可能延迟加载的广告)
setInterval(removeAdContainers, CONFIG.checkInterval);
}
// 等待DOM加载完成后初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
// 暴露函数到全局,方便调试
window.adBlock = {
removeAds: removeAdContainers,
testSelectors: testSelectors,
stats: stats
};
})();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址