Skip to content

Instantly share code, notes, and snippets.

@rena2019
Last active October 30, 2025 10:00
Show Gist options
  • Select an option

  • Save rena2019/0abd94028b886e033009a48d55fe2838 to your computer and use it in GitHub Desktop.

Select an option

Save rena2019/0abd94028b886e033009a48d55fe2838 to your computer and use it in GitHub Desktop.
tampermonkey script to hide threads ghost posts
// ==UserScript==
// @name ThreadsByeByeGhostPosts
// @namespace http://tampermonkey.net/
// @version 2025-10-30
// @description bye bye ghost posst @ Threads
// @author rena2019
// @match https://www.threads.com/
// @icon https://www.google.com/s2/favicons?sz=64&domain=threads.com
// @run-at document-idle
// @noframes
// @grant unsafeWindow
// ==/UserScript==
(function() {
'use strict';
window.console.log("bye bye threads ghost posts");
// --- CSS selector for target elements ---
const targetSelector = ".x6s0dn4.x1rl75mt.x19t5iym.xz7t8uv.x13xmedi.x78zum5.x1q0g3np.xl56j7k.x193iq5w.x4p5aij.x1ccui7m.x1j85h84.x18pi947.x1n2onr6";
function p5(node, depth = 0) {
// If node is null → no further parentElement exists
if (!node || !node.parentElement) return null;
// If we have reached 5 levels → return the current node
if (depth === 5) return node;
// Recursive call with the parentElement and increased depth
return p5(node.parentElement, depth + 1);
}
function hideNode(el) {
el = p5(el);
//console.log("hideNode");
// Sicherstellen, dass das Element sichtbar ist
el.style.transition = "opacity 2s ease";
el.style.opacity = "1";
// Trigger fade-out
requestAnimationFrame(() => {
el.style.opacity = "0";
});
// Nach 2 Sekunden Fade-Out: Height-Transition starten
setTimeout(() => {
const currentHeight = el.offsetHeight + "px";
el.style.transition = "height 0.3s ease, margin 0.3s ease, padding 0.3s ease";
el.style.height = currentHeight;
el.style.overflow = "hidden";
// Force reflow damit Transition greift
el.offsetHeight;
// Dann Höhe, padding und margin auf 0 setzen
el.style.height = "0";
el.style.paddingTop = "0";
el.style.paddingBottom = "0";
el.style.marginTop = "0";
el.style.marginBottom = "0";
// Nach 300ms endgültig display:none setzen
setTimeout(() => {
el.style.display = "none";
console.log("Collapsed and hidden element:", el);
}, 300);
}, 2000); // 2000ms = Fade-Out-Dauer
}
// --- IntersectionObserver: triggers when ≥10% visible ---
const intersectionObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting && entry.intersectionRatio >= 0.1) {
hideNode(entry.target);
intersectionObserver.unobserve(entry.target);
}
});
}, {
threshold: [0.1] // Trigger at 10% visibility
});
// --- Function to add matching elements to observer ---
function observeMatchingElements(root) {
const matches = root.querySelectorAll(targetSelector);
matches.forEach(el => intersectionObserver.observe(el));
}
// --- Observe existing elements at script start ---
observeMatchingElements(document);
// --- MutationObserver to detect newly added nodes ---
const mutationObserver = new MutationObserver(mutations => {
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (node.nodeType === 1) {
if (node.matches(targetSelector)) {
intersectionObserver.observe(node);
} else {
observeMatchingElements(node);
}
}
}
}
});
// --- Start observing the DOM for added elements ---
mutationObserver.observe(document.body, { childList: true, subtree: true });
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment