Nextdoor - Hide all annoying content in the Nextdoor News Feed

Hide all annoying content in the Nextdoor News Feed. Customizable with flags and key phrases. About 99% of the content on Nextdoor is garbage but that 1% of useful posts are gold. This script helps improve the ratio of garbage.

目前為 2020-01-04 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Nextdoor - Hide all annoying content in the Nextdoor News Feed
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Hide all annoying content in the Nextdoor News Feed. Customizable with flags and key phrases. About 99% of the content on Nextdoor is garbage but that 1% of useful posts are gold. This script helps improve the ratio of garbage.
// @author       You
// @match        https://nextdoor.com/news_feed/
// @grant        none
// jshint esversion: 6
// ==/UserScript==

(function() {
    'use strict';

    // --- Configurations start
    const fixInterval = 500; // time in milliseconds

    const enableHidePaidAds = true;
    const enableHideSponsoredAds = true;
    const enableHideNewNeighborAnnouncements = true;
    const enableHideNonFreeClassifiedAds = true;

    const hideKeyPhrases = ["lost dog", "found dog", "lost cat", "found cat", "coyote", "handyman"]; // Hide any posts that have titles that contain any of these key phrases. Must be all lower-case.
    const hideAuthorsNames = ["The San Diego Union-Tribune"]; // Hide any posts with any of these author names. Name match exactly, including case. Useful for those sneaky "pay to read" news sites like San Diego Union-Tribune that otherwise look like legitimate posts.
    // --- Configurations end

    const $ = window.jQuery; // Use jQuery object provided by the site

    const hideNewNeighborAnnouncements = () => {
        // Bulk announcements
        const potentialNewNeighborAnnouncements = $("h5.content-title");
        potentialNewNeighborAnnouncements.each((index, el) => {
            const potentialNewNeighborAnnouncement = $(el);
            if (potentialNewNeighborAnnouncement.text().includes(" new neighbors joined ")) {
                const container = potentialNewNeighborAnnouncement.parent().parent().parent().parent().parent();
                if (container[0].className === "post-container") {
                    container.remove();
                }
            }
        });

        // Single announcements
        const allPosts = $("article.post-container");
        allPosts.each((index, el) => {
            const post = $(el);
            const postTitle = post.attr("aria-label").toLowerCase();
            if (postTitle.includes(" joined ")) {
                const reactionText = post.find("span[data-testid='reaction-button-text']").text().toLowerCase();
                if (reactionText === "welcome") {
                    post.remove();
                }
            }
        });
    }

    const hideNonFreeClassifiedAds = () => {
        // Single ads
        let classifiedAds = $("div.classifieds-single-item-content");
        classifiedAds.each((index, el) => {
            const classifiedAd = $(el);
            const price = classifiedAd.find("span.classified-single-item-content-price").text().toLowerCase();
            if (price === "free") {
                return;
            }

            const container = classifiedAd.parent();
            container.remove();
        });

        // Rollup ads
        classifiedAds = $("div.classified-author-rollup-slider");
        classifiedAds.each((index, el) => {
            const classifiedAd = $(el);
            const price = classifiedAd.find("span.classified-rollup-card-price").text().toLowerCase();
            if (price === "free") {
                return;
            }

            const container = classifiedAd.parent();
            container.remove();
        });
    }

    const hidePostsWithKeyPhrases = (phrases) => {
        const allPosts = $("article.post-container");
        allPosts.each((index, el) => {
            const post = $(el);
            const postTitle = post.attr("aria-label").toLowerCase();
            for (let i = 0; i < phrases.length; i++) {
                const phrase = phrases[i];
                if (postTitle.includes(phrase)) {
                    post.remove();
                }
            }
        });
    }

    const hidePostsByAuthors = (authors) => {
        const allAuthors = $("a.author-name");
        allAuthors.each((index, el) => {
            const authorLink = $(el);
            const authorName = authorLink.text();
            for (let i = 0; i < authors.length; i++) {
                const author = authors[i];
                if (author === authorName) {
                    const container = authorLink.parent().parent().parent().parent().parent().parent().parent().parent().parent().parent().parent().parent();
                    container.remove();
                }
            }
         });
    }

    let styleTag = "";
    if (enableHidePaidAds) {
        styleTag += " article.gam-ad-outer-container { display: none !important; } ";
    }

    if (enableHideSponsoredAds) {
        styleTag += " div.ad-wrapper, div.programmatic-promo-container { display: none !important; } ";
    }

    if (styleTag) {
        styleTag = `<style>${styleTag}</style>`;
        $("html > head").append($(styleTag));
    }

    const fixNextDoor = () => {
        if (enableHideNewNeighborAnnouncements) {
            hideNewNeighborAnnouncements();
        }

        if (enableHideNonFreeClassifiedAds) {
            hideNonFreeClassifiedAds();
        }

        if (hideKeyPhrases && hideKeyPhrases.length > 0) {
            hidePostsWithKeyPhrases(hideKeyPhrases);
        }

        if (hideAuthorsNames && hideAuthorsNames.length > 0) {
            hidePostsByAuthors(hideAuthorsNames);
        }
    }

    const timer = setTimeout(fixNextDoor, 250); // Force a single initial fix after a short wait
    const interval = setInterval(fixNextDoor, fixInterval); // Keep calling fixNextDoor to fix content shortly after it loads
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址