实战:JS 注入去广告——三种常见广告类型的处理方案
问题背景
过滤元素页面讲了用 CSS selector 隐藏静态广告。但实际网站的广告花样很多:
| 广告类型 | 过滤元素能处理吗 | 特点 |
|---|---|---|
| 静态 DOM 广告 | ✅ 能 | HTML 里直接有广告元素 |
| React/Vue 动态渲染 | ❌ 不能 | DOM 在 JS 执行后才出现 |
| 滚动触发广告 | ⚠️ 部分能 | 滚动到某位置才加载 |
| iframe 嵌套广告 | ⚠️ 部分能 | iframe 内部 DOM 无法直接操作 |
这时候 JS 注入就派上用场了。
方案一:MutationObserver 持续监听
适合所有"后来才出现"的广告——无论什么时候加载进 DOM,都能被即时移除。
// remove-ads.js
// 先隐藏初始页面里的广告
const hideAds = () => {
const selectors = [
'.ad-banner',
'.sidebar-ads',
'[class*="popup"]',
'[id*="advertisement"]',
'iframe[src*="ads"]',
];
document.querySelectorAll(selectors.join(',')).forEach(el => {
el.style.display = 'none';
// 也可以直接从 DOM 移除:el.remove();
});
};
hideAds();
// 持续监听,新出现的广告也立即处理
const observer = new MutationObserver(() => hideAds());
observer.observe(document.body, {
childList: true,
subtree: true,
});
怎么写准确的 selector
关键是精准——不要用 div[class*="ad"] 这种宽泛的 selector,可能误杀有用的元素(比如 class 里碰巧带 "ad" 字样的产品卡片)。
推荐方法:
- PakePlus 预览窗口 F12 打开 DevTools
- 找到广告元素的精确 class 或 id
- 复制 selector 到过滤元素或 JS 里
方案二:iframe 嵌套广告
很多网站用 iframe 嵌入第三方广告(比如 Google Ads、腾讯广告)。过滤元素和普通 JS 都无法跨 iframe 操作 DOM——浏览器安全策略禁止。
解法一:拦截 iframe 创建
// 拦截后续所有 iframe 创建请求
const originalCreateElement = document.createElement.bind(document);
document.createElement = function(tag) {
const el = originalCreateElement(tag);
if (tag === 'iframe') {
// 延迟检查 src 属性(src 可能在 append 后才设置)
const observer = new MutationObserver(() => {
const src = el.getAttribute('src') || '';
if (/ad|ads|doubleclick|googlesyndication/i.test(src)) {
el.remove();
observer.disconnect();
}
});
observer.observe(el, { attributes: true });
}
return el;
};
解法二:用 CSP 头直接屏蔽
如果目标网站是你自己的(有权限修改 HTTP 响应头),可以加 Content-Security-Policy:
Content-Security-Policy: frame-src 'self' 允许的域名白列表
这从根源上不让广告 iframe 加载。但如果目标网站是别人的,你没权限改响应头。
方案三:滚动触发的广告
某些网站在用户滚动到页面中部或底部时才弹广告。MutationObserver 能处理——广告 DOM 一出现就被移除。但如果广告有"延迟渲染"策略(等滚动事件触发后的几秒才创建),MutationObserver 依然有效。
额外保险:阻止滚动事件
// 有些广告是滚动事件触发的——可以拦截滚动事件传播
const originalScroll = window.onscroll;
window.addEventListener('scroll', (e) => {
// 执行正常的滚动逻辑
if (originalScroll) originalScroll();
// 同时扫描一次广告(滚动时 DOM 可能更新)
hideAds();
}, { passive: true });
实战:YouTube 无广告桌面版
假设打包 YouTube 网页版,目标:去掉推荐视频弹窗、直播聊天、部分前置广告。
脚本文件:youtube-ads.js
// YouTube 无广告脚本
const hide = () => {
const selectors = [
'.ytd-popup-container', // 弹窗容器
'.ytd-live-chat-frame', // 直播聊天
'#chat-container', // 聊天区域
'.ytd-comments', // 评论区(可选)
'[class*="video-ads"]', // 视频广告
'.ytp-ad-overlay-slot', // 覆盖广告
'.ytp-ad-player-overlay', // 播放器内广告
];
document.querySelectorAll(selectors.join(',')).forEach(el => {
el.style.display = 'none';
});
};
hide();
new MutationObserver(hide).observe(document.body, {
childList: true,
subtree: true,
});
配合过滤元素
在配置页面的"过滤元素"字段里填:
.ytd-popup-container, .ytd-live-chat-frame, #chat-container
(过滤元素先处理一轮静态 DOM,JS 注入 + MutationObserver 处理后续动态加载的)
实战:小红书去推荐流
假设打包小红书网页版,目标:去掉右侧推荐列表和底部无关内容。
脚本文件:xiaohongshu.js
const hide = () => {
const selectors = [
'.side-bar', // 右侧侧边栏(含推荐)
'.note-list .recommend', // 笔记推荐卡片
'.bottom-recommend', // 底部推荐
];
document.querySelectorAll(selectors.join(',')).forEach(el => {
el.remove(); // 这里直接 remove,因为是你自己决定不看的
});
};
hide();
new MutationObserver(hide).observe(document.body, {
childList: true,
subtree: true,
});
关于"去广告"的边界
PakePlus 打包自己有权限的网站(比如你自建的网站、你自己运营的服务),用 JS 注入去掉不需要的组件完全没问题。但如果是第三方网站:
- Google Ads、腾讯广告等是第三方嵌入的——用户自己在客户端去掉,属于合理的用户定制行为
- 如果目标网站是订阅制服务(比如付费内容站),去广告可能违反其服务条款
- PakePlus 文档明确声明"打包仅限个人使用"——不要分发带去广告脚本的打包产物