Last active
July 8, 2025 15:31
-
-
Save jcguu95/41681b9b5deafe1ba6cbd1b7cc1f1af7 to your computer and use it in GitHub Desktop.
Remove Instagram Unfollowed Content
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name Remove Instagram Unfollowed Content | |
| // @version 2024-03-02 | |
| // @author Jin-Cheng Guu | |
| // @match https://www.instagram.com/* | |
| // @description Remove unfollowed content from the instagram main page. | |
| // ==/UserScript== | |
| (function() { | |
| let blacklist = [ | |
| // Remove all unfollowed content. | |
| 'Follow', | |
| // Ban your favorite texts. | |
| 'your.acquaintance.id.1', | |
| 'your.acquaintance.id.2', | |
| ]; | |
| function findsBannedText (element) { | |
| let blacklistedText = ''; | |
| let text = element.textContent.trim(); | |
| let bannedText = blacklist.find (x => (x === text)); | |
| if (bannedText) { | |
| // console.log("Found banned text in node.", bannedText, element) | |
| return bannedText; | |
| } | |
| // No banned text found so far; search through its children recursively. | |
| let children = element.children; | |
| if (children.length > 0) { | |
| for (let i = 0; i < children.length; i++) { | |
| bannedText = findsBannedText(children[i]) | |
| if (bannedText) { | |
| // console.log("Found banned text in node. ", bannedText, children[i]); | |
| return bannedText; | |
| } | |
| } | |
| } else { | |
| return false; | |
| } | |
| }; | |
| function removeChildren (node) { | |
| // Remove all children of node. | |
| console.log("Remove all children of the node: ", node) | |
| let children = node.children; | |
| for (let i = 0; i < children.length; i++) { | |
| children[i].remove(); | |
| } | |
| } | |
| // | |
| function getAll (element, tag) { | |
| let result = []; | |
| if (element.tagName === tag) { | |
| result.push(element); | |
| } | |
| let children = element.children; | |
| for (let i = 0; i < children.length; i++) { | |
| result = result.concat(getAll(children[i], tag)); | |
| } | |
| return result; | |
| } | |
| function cleanAll (tag) { | |
| getAll(document.body, tag).forEach ( | |
| article => { | |
| let bannedtext = findsBannedText(article); | |
| if (bannedtext) { | |
| console.log("handling node because of text: ", article, bannedtext); | |
| // we do not remove the unwelcome node itself as that crashes the page. | |
| removeChildren(article); | |
| }}) | |
| } | |
| // One-time Clean | |
| cleanAll('ARTICLE'); // Remove posts. | |
| cleanAll('LI'); // Remove stories. | |
| // Clean after each click. | |
| let waitLength = 500 | |
| document.onclick = function (event) { | |
| setTimeout(() => { cleanAll('ARTICLE'); // Remove posts. | |
| cleanAll('LI'); // Remove stories. | |
| }, | |
| waitLength); | |
| }; | |
| // | |
| // Make observer that constantly check for new articles. | |
| // | |
| function makeObserver () { | |
| let callback = (mutationList, observer) => { | |
| for (const mutation of mutationList) { | |
| if (mutation.type === "childList" && | |
| mutation.addedNodes.length > 0) { | |
| let addedNode = mutation.addedNodes[0]; | |
| let bannedText = findsBannedText(addedNode); | |
| if (addedNode.tagName === 'ARTICLE' && bannedText) { | |
| console.log("Handling node because of text: ", addedNode, bannedText); | |
| // We do not remove the unwelcome node itself as that crashes the page. | |
| removeChildren(addedNode); | |
| } | |
| } | |
| } | |
| }; | |
| return new MutationObserver(callback); | |
| } | |
| let config = { attributes: true, childList: true, subtree: true }; | |
| let observer = makeObserver(); | |
| observer.observe(document.body, config); | |
| // observer.disconnect(); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Stopped working for me as well. I noticed I still get the 'Follow' text, but the script only seems to detect and remove the related article if I click in its area. I guess this is the 'one time clean' triggered by clicks doing its thing. But just scrolling through the feed the script never triggers on those articles. I do still see it knocking out suggested posts in the console as expected without interaction.