Facebook no ads

Makes sponsored feeds invisible on facebook.com

目前為 2020-09-23 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Facebook no ads
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Makes sponsored feeds invisible on facebook.com
// @author       Darmikon
// @match        https://www.facebook.com/*
// @grant        none
// ==/UserScript==

(function() {
    let rootEl = null;

    const throttle = (func, limit) => {
        let inThrottle;
        return function() {
            const args = arguments;
            const context = this;
            if (!inThrottle) {
                func.apply(context, args);
                inThrottle = true;
                setTimeout(() => {
                    inThrottle = false;
                }, limit);
            }
        }
    }

    const doHack = (feed) => {
        // 1. Find this unique block inside the feed
        const spanWithId = feed.querySelector('span[id]');

        if(!spanWithId) return;

        const spanChildren = spanWithId.children;

        // 2. Check if the second child of spanWithId is not a DIV element
        if(spanChildren && spanChildren.length) {
            if(spanChildren[1]) {
                // if(spanChildren[1].nodeName !== 'SPAN'){
                //    console.log(spanChildren[1].nodeName);
                // }
                return spanChildren[1].nodeName !== 'SPAN';
            }
        }
    }

    const findRoot = (cb) => {
        const intervalId = setInterval(() => {
            if(!rootEl) {
                rootEl = document.querySelector('[role="feed"]');
            } else {
                clearInterval(intervalId);
                cb();
            }
        }, 50);
    }

    const trimAds = () => {
        const feeds = [].slice.call(rootEl.children || []).filter(child => {
            return child.hasAttribute('data-pagelet');
        });
        feeds.forEach((feed, i) => {
            try {
                if(doHack(feed)) {
                    // console.log('killed', feed.querySelector('h4 span'));
                    feed.style.display = "none";
                }
            } catch (e) {}
        });
    }

    const runAdsKiller = () => {
        const throttleKill = throttle(trimAds, 50);
        throttleKill();
        window.addEventListener('scroll', throttleKill);
        window.addEventListener('resize', throttleKill);
    }

    const init = () => {
        findRoot(runAdsKiller);
    }

    init();
})();