如何通过用户脚本方便地隐藏使用广告拦截器选择的元素?

How to conveniently hide elements selected using an adblocker via a userscript?

要阻止元素,可以使用:

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

但那是针对 one 特定元素,针对 one 特定站点。要在多个站点中阻止多个元素,用户脚本必须多次 @include,并且在每个站点中它应该多次列出元素。假设我有一个广告拦截器过滤器列表,如何方便地将其转换为单个用户脚本?

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 中的行添加到列表中即可。

您可以通过创建在所有域上运行的用户脚本来执行此操作,解析从域和查询选择器的广告拦截器获得的字符串列表,查看它是否与 window 的域匹配,并且如果元素存在,则删除它们。我在下面提供了一种方法:

// ==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);
            }
        }
    }
})();

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