如何仅用JavaScript屏蔽Facebook动态中的赞助帖与推荐帖?
如何用JavaScript屏蔽Facebook的赞助帖和推荐帖
浏览Facebook动态时,会出现大量「赞助帖(Sponsored)」和「为你推荐帖(Suggested for you)」,能否仅通过JavaScript实现简洁的屏蔽方法?以下是一个可行方案,欢迎使用、修改并提出改进建议。
使用方法
- 登录Facebook,打开浏览器控制台(开发者工具)
- 复制粘贴下方代码并运行
- 输入
adBlocker.start()按回车启动屏蔽,输入adBlocker.stop()按回车停止屏蔽
/* 浏览Facebook动态时,自动隐藏赞助帖和为你推荐帖。 使用方法: 登录Facebook,打开浏览器控制台(开发者工具),复制粘贴以下代码并运行。然后输入adBlocker.start()并按回车启动,输入adBlocker.stop()并按回车停止。 */ const adBlocker = {}; adBlocker.toRemoveDivs = []; // 带有role="feed"属性的div的直接子div是动态帖的主要父容器 adBlocker.postsContainerDIV = document.querySelector('div[role="feed"]>div'); // 查找元素的最近祖先节点(兼容旧浏览器的closest方法替代实现) adBlocker.findAncestor = function (el, sel) { while ((el = el.parentElement) && !((el.matches || el.matchesSelector).call(el, sel))); return el; } // 扫描页面中所有赞助帖的容器 adBlocker.scanForSponsoredDivs = function() { document.querySelectorAll('a[aria-label="Sponsored"]') .forEach( aHrefElement => adBlocker.toRemoveDivs.push( adBlocker.findAncestor( aHrefElement, 'div[data-pagelet^="FeedUnit_"]' ) ) ) } // 扫描页面中所有"为你推荐"帖的容器 adBlocker.scanForSuggestedDivs = function() { document.querySelectorAll('span.x193iq5w.xeuugli.x13faqbe.x1vvkbs.x10flsy6.x1lliihq.x1s928wv.xhkezso.x1gmr53x.x1cpjm7i.x1fgarty.x1943h6x.x4zkp8e.x41vudc.x6prxxf.xvq8zen.xo1l8bm.xi81zsa[dir="auto"]') .forEach( function( span ) { if (span.innerHTML === "Suggested for you") adBlocker.toRemoveDivs.push( adBlocker.findAncestor( span, 'div[data-pagelet^="FeedUnit_"]' ) ) }) } // 判断某个容器是否是"为你推荐"帖 adBlocker.isItASuggestedDiv = function(div) { const span = div.querySelectorAll('span.x193iq5w.xeuugli.x13faqbe.x1vvkbs.x10flsy6.x1lliihq.x1s928wv.xhkezso.x1gmr53x.x1cpjm7i.x1fgarty.x1943h6x.x4zkp8e.x41vudc.x6prxxf.xvq8zen.xo1l8bm.xi81zsa[dir="auto"]')[0]; return (span && span.innerHTML && span.innerHTML === "Suggested for you"); } // 判断某个容器是否是赞助帖 adBlocker.isItASponsoredDiv = function(div) { const aHref = div.querySelectorAll('a[aria-label="Sponsored"]')[0]; return !!aHref; } // 隐藏指定元素 adBlocker.hide = function( div ) { if ( div && div.style ) div.style.display = "none"; } // 批量隐藏待移除的帖子容器 adBlocker.removeDivs = function() { for (const div of adBlocker.toRemoveDivs) { // 从Facebook动态中隐藏赞助帖容器 // adBlocker.postsContainerDIV.removeChild( div ); // 这会再次触发MutationObserver,导致循环 // 为避免触发MutationObserver,仅隐藏该容器 adBlocker.hide( div ); // 从待移除数组中删除该容器 const index = adBlocker.toRemoveDivs.indexOf( div ); adBlocker.toRemoveDivs.splice( index, 1 ); } } // 扫描并移除已加载的广告帖 adBlocker.searchAndRemoveDivs = function() { adBlocker.scanForSponsoredDivs(); adBlocker.scanForSuggestedDivs(); adBlocker.removeDivs(); } // MutationObserver配置:监听子节点变化 adBlocker.observer_config = { childList: true }; // 节点变化回调:处理新加载的广告帖 adBlocker.observerCallback = (mutationList, observer) => { for (const mutation of mutationList) { if (mutation.addedNodes.length > 0) { for (const div of mutation.addedNodes) { if ( adBlocker.isItASuggestedDiv( div ) || adBlocker.isItASponsoredDiv( div ) ) adBlocker.hide( div ); } } } }; // 创建关联回调函数的观察者实例 adBlocker.observer = new MutationObserver( adBlocker.observerCallback ); // 启动广告屏蔽服务 adBlocker.start = function() { console.log("adBlocker: 启动中..."); // 先移除已加载到动态中的赞助帖和推荐帖 console.log("adBlocker: 移除已加载的广告帖..."); adBlocker.searchAndRemoveDivs(); // 监听帖子容器的变化,处理滚动加载的新广告帖 console.log("adBlocker: 设置动态加载监听,拦截后续广告帖..."); adBlocker.observer.observe( adBlocker.postsContainerDIV, adBlocker.observer_config ); console.log("adBlocker: 启动完成!享受无广告的动态浏览吧~"); } // 停止广告屏蔽服务 adBlocker.stop = function() { adBlocker.observer.disconnect(); console.log("adBlocker: 已停止服务!(输入adBlocker.start()可重新启动)"); }
改进建议
- 避免依赖动态类名:原代码中使用的
x193iq5w这类CSS类是Facebook动态生成的,容易随网站更新失效。建议改用更稳定的匹配方式,比如直接查找包含"Sponsored"或"为你推荐"文本的节点,而非依赖这些随机类名。 - 简化祖先节点查找:现代浏览器均支持原生
Element.closest()方法,可以直接替换自定义的findAncestor函数,简化代码逻辑。 - 优化变量声明:使用
const/let替代全局变量声明,避免变量污染,比如将adBlocker声明为const,内部变量如span、aHref等也用const声明。 - 添加容错处理:增加对
postsContainerDIV不存在的情况处理,避免页面结构变化导致脚本报错。 - 定时扫描补充:除了MutationObserver监听,可添加定时扫描机制,防止漏掉部分动态加载的内容。
内容的提问来源于stack exchange,提问作者Atti
相关产品推荐
相关产品推荐

