如何通过用户脚本方便地隐藏使用adblocker选择的元素?

时间:2017-06-05 12:12:32

标签: javascript filter greasemonkey adblock

要阻止元素,可以使用:

var adSidebar = document.getElementById('ads');
if (adSidebar) {
    adSidebar.parentNode.removeChild(adSidebar);
}

但对于一个特定网站,一个具体元素。要阻止多个站点中的多个元素,用户脚本必须多次@include,并且在每个站点中应多次列出元素。假设我有一个adblocker过滤器列表,如何方便地将其转换为单个用户脚本?

www.youtube.com###watch7-sidebar-contents
www.youtube.com##.yt-masthead-logo-container
www.facebook.com##._1uh-:nth-of-type(2)
www.facebook.com##._2t-e > ._4kny:nth-of-type(1)
www.facebook.com##._1uh-:nth-of-type(1)
www.facebook.com##._50tj._2t-a
www.facebook.com##._50ti._2s1y._5rmj._26aw._2t-a
www.facebook.com###u_0_0
www.facebook.com###fbDockChatBuddylistNub > .fbNubButton

我想将该列表保存在一个位置,因此如果需要阻止新网站中的新元素,我只需将uBlock中的行添加到列表中。

1 个答案:

答案 0 :(得分:1)

您可以通过创建在所有域上运行的用户脚本,解析从域和查询选择器的广告拦截器获取的字符串列表,查看它是否与窗口的域匹配以及是否与元素( s)存在,然后删除它们。我在下面提供了一种方法:

// ==UserScript==
// @name         Custom element hider
// @namespace    https://zachsaucier.com/
// @version      0.1
// @description  To show how one can hide elements like an ad blocker using userscripts
// @author       Zach Saucier
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Set our list of sites and elements to block
    var blockList = [
        "www.youtube.com###watch7-sidebar-contents",
        "www.youtube.com##.yt-masthead-logo-container",
        "www.facebook.com##._1uh-:nth-of-type(2)",
        "www.facebook.com##._2t-e > ._4kny:nth-of-type(1)",
        "www.facebook.com##._1uh-:nth-of-type(1)",
        "www.facebook.com##._50tj._2t-a",
        "www.facebook.com##._50ti._2s1y._5rmj._26aw._2t-a",
        "www.facebook.com###u_0_0",
        "www.facebook.com###fbDockChatBuddylistNub > .fbNubButton"
    ];

    // Get the window's hostname
    var windowHostname = window.location.hostname;

    // Iterate through the blocklist, hiding elements as needed
    for(var i = 0; i < blockList.length; i++) {
        var entryParts = blockList[i].split('##');

        // Compare the hostnames; Only remove elements if they match
        if(windowHostname === entryParts[0]) {
            // Find the elements if they exists
            var matchedElements = document.querySelectorAll(entryParts[1]);

            // Actually remove the element(s) that match
            for(var j = 0; j < matchedElements.length; j++) {
                var matchedElem = matchedElements[j];

                matchedElem.parentNode.removeChild(matchedElem);
            }
        }
    }
})();

虽然我不确定为什么当广告拦截器本身可以执行此操作时您想要编写用户脚本...