免责声明:这个故事的重点是我如何识别和删除赞助的帖子,而不是我为什么删除它们。 这是一个了解DOM的机会。
今天,我打开了Facebook ,发现有什么问题,我的adblocker无法正常工作。
作为开发人员,我决定进行调查,首先我要检查这些赞助帖子的结构 ,以查看是否有办法识别它们,以便可以使用脚本将其删除。
结构看起来非常简单,我们有一个角色为“ 文章 ”的元素,其中包含一个以“ feed_subtitle ”开头的类的div,在最后一个div内,类似于无数跨度的随机单词。
杜德,认真的,WTF?
他们使用技巧来显示“赞助”一词:一些跨度可见,有些则不可见。
为了简化起见,有时父母是可见的,但孩子却不可见,反之亦然。
是时候开始构建脚本来摆脱这些无用的东西了。
我离开了在chrome检查器中选择的字幕div,并在控制台“ $ 0.textContent”中运行:
好吧,这是意料之中的,如果我们要删除这些广告,我们需要一个函数来查找真实文本。
为此,我们需要一个递归函数。 该函数将获得该元素的子节点的列表,并删除隐藏的子节点。
DOM是一棵大的节点树,组成页面的元素通常是“元素”和“文本”类型,请注意每个不同的节点类型都允许有不同的子节点集,这一点很重要。 例如,文档节点(根)可以将DocumentType节点作为子节点,而其他节点则不能。
组成帖子的元素都在Element类型的节点下,这意味着我们只能找到以下类型的节点:Element,Text,ProcessingInstruction和Comment。 [规格]
我们对Comment和ProcessingInstructions毫无兴趣,因为它们不是由浏览器呈现的。 因此,我们将其过滤掉。
返回以从列表中删除隐藏的节点。 只有Element类型的节点可以具有样式,因此,这是唯一可以隐藏的样式(及其子项)。 其他节点类型没有样式,因此我们无法在其上使用“ getComputedStyle”。 这意味着我们只需要在Element节点上检查样式:
然后,使用这些可见节点,我们收集它们内部可见的节点。
但是,如果递归地获取元素的节点,就会遇到问题。 末尾的(叶子)将没有任何节点。
当我们到达仅包含文本的元素并返回我们感兴趣的文本内容时,我们需要停止。
完善! 现在我们有了递归函数,递归循环和停止条件的所有内容,让我们合并所有部分。
是时候在所选元素上尝试该功能了:
完善! 有用!
现在,我们需要一个函数,当我们问这是否是赞助帖子的副标题时,说“是”或“否”。
为了安全起见,即使缺少字幕也可以使用。
现在,我们可以知道何时赞助了,我们只需要获取页面上所有赞助的帖子。
让我们从简单的部分开始,让我们获得所有帖子,并仅保留那些赞助的帖子
现在我们需要一个函数来知道帖子是否被赞助,我们已经有一个函数来识别字幕是否是赞助帖子之一,我们所需要的只是将帖子的字幕传递给该功能。
所有的碎片都聚集在一起!
现在我们需要一个函数来删除这些文章。
试试吧!
有用!
现在它只缺少一件,在我看到它们之前将其删除。
确实有很多聪明的方法可以做到这一点,但是我很懒,因此我将简单地使用一个函数来观察添加到提要中的所有新DOM元素。
为此,我可以使用MutationObserver ,此有用的功能可以在每次从特定元素的子树中添加或删除元素时执行回调。
当我们创建一个新的MutationObserver时,我们将向回调函数传递一个回调,该回调将在我们观察的元素发生更改时执行。 我们可以得到通知的更改是在稍后将看到的观察方法上选择的。
我们将通过mutationList收到这些更改的通知,mutationList是在该元素上发生的MutationRecord的列表,我们可以通知三种类型的突变:“属性”,“ characterData”和“ childList”; 这些突变中的每一个都描述了更改的内容,例如,如果某个Element的一个或多个属性已更改,则MutationRecord的类型将为“属性”。
创建一个MutationObserver是不够的,我们还需要使它观察一个元素,创建它之后,我们可以使用“观察”方法,该方法将要观察的元素和观察对象作为参数。 我们可以观察到元素属性的变化,和/或元素层次结构的变化(添加或删除元素下的新节点)。
当Facebook添加新帖子时,它始终是ID以“ u_fetchstream”开头的元素
我将其分解,因为它似乎有点复杂:
- 我们只对类型为“ childList”的突变感兴趣(添加或删除了孩子),我们只希望在列表中添加一个孩子。
- 在这些突变中,我们仅对添加的节点感兴趣,因此我将其提取出来。
- 在添加的节点中,我们仅对帖子感兴趣。
- 最后,我调用observe方法来检查childList上的更改,并且我对整个子树(不仅是Element的直接子代)感兴趣。
太好了,现在我们有一个添加到页面的所有帖子的列表!
我们只需要使用旧功能来检测这些帖子中的哪些被赞助并删除。 是时候看到最终结果了:
现在剩下的唯一事情就是,每次我打开facebook时,都会自动将此代码投入使用。
为此,我将使用Greasemonkey(或Chrome中的Tampermonkey)
您可以在此处找到用户脚本: https : //gist.github.com/maury91/d054d9f38650d70b64ec583845231f20/raw/00af0da1d5f8de4934fb0874effda6dce9e11daf/removeFacebookAdsNew.user.js
尽情摆脱新的Facebook广告吧! (我知道它不会长期有效)
From: https://hackernoon.com/how-i-get-rid-of-the-new-sponsored-facebook-posts-138d013f4bbe