您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Remove annoying crap from Twitter
// ==UserScript== // @name FixAnnoyingTwitterCrap // @version 0.1.8 // @description Remove annoying crap from Twitter // @author Jeremy Bornstein <[email protected]> // @match https://*.twitter.com/* // @grant none // @namespace https://gf.qytechs.cn/users/414927 // ==/UserScript== (function() { 'use strict'; function debugSearch(selector, text) { const nodes = document.body.querySelectorAll(selector); for (let i = 0; i < nodes.length; i++) { const node = nodes[i]; if (node.innerText.startsWith(text)) { const offendingNode = node; console.debug("found", node); offendingNode.style.backgroundColor = 'green'; offendingNode.style.color = 'orange'; } } } function findNewsfeed() { const nodes = document.querySelectorAll('section'); for (let i = 0; i < nodes.length; i++) { const node = nodes[i]; if (node.querySelector('h2') == null) { return node; } } return null; } function findNamedSection(parent, predicate) { const nodes = parent.querySelectorAll('h2'); for (let i = 0; i < nodes.length; i++) { const node = nodes[i]; if (predicate(node)) { let container = node.parentElement; // first, find the first element which has more than a single child while (container.childElementCount <= 1 && container.parentElement != null) { container = container.parentElement; } // then, go up the tree as long as we only have a single child. while (container.parentElement != null && container.parentElement.childElementCount == 1) { container = container.parentElement; } return container; } } return null; } function findTrendingSection(parent) { function isTargetNode(n) { const text = n.innerText; // TODO: clearly need more examples return text.startsWith("Tendances : ") || text == "Ce qui se passe" || text == "Trends" || text == "Trends for you" } return findNamedSection(parent, isTargetNode); } function findSponsoredSection(parent) { function isTargetNode(n) { const text = n.innerText; // TODO: clearly need more examples return text.startsWith("Tendances : ") || text == "Tweet sponsorisé" || text == "Sponsored Tweet" // have yet to observe in practice } return findNamedSection(parent, isTargetNode); } function findSuggestionsSection(parent) { function isTargetNode(n) { const text = n.innerText; // TODO: clearly need more examples return text == "Suggestions" } return findNamedSection(parent, isTargetNode); } function removeMatchingNodes(parent, selector, predicate, findParent, debugBGColor, debugTextColor, removeIt) { const nodes = parent.querySelectorAll(selector); for (let i = 0; i < nodes.length; i++) { const node = nodes[i]; if (predicate(node)) { const offendingNode = findParent(node); if (debugBGColor && debugTextColor) { console.debug("found", node, "with text:", node.innerText); offendingNode.style.backgroundColor = debugBGColor; offendingNode.style.color = debugTextColor; console.debug("TARGET", offendingNode); } if (removeIt) { //offendingNode.parentNode.removeChild(offendingNode); offendingNode.hidden = true; offendingNode.style.display = "none"; } } } } function removeAds(parent) { if (!parent) return; function isTargetNode(n) { const nodeText = n.innerText; return nodeText == "Sponsorisé" || nodeText == "Sponsored" || nodeText == "Promoted" } removeMatchingNodes(parent, 'span', isTargetNode, n => n.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode /*.parentNode.parentNode*/, 'black', 'black', true); } function removeSuggestionsAds(parent) { // TK } function removeTrendAds(parent) { if (!parent) return; function isTargetNode(n) { const nodeText = n.innerText; return nodeText.startsWith("Promoted by ") || nodeText.startsWith("Sponsored by ") || nodeText.startsWith("Sponsorisé par ") } function findParentNode(n) { let parent = n.parentElement; while (parent.childElementCount <= 2 && parent.parentElement != null) { parent = parent.parentElement; } if (parent) { while (parent.childElementCount == 1 && parent.parentElement != null) { parent = parent.parentElement; } } return parent; } removeMatchingNodes(parent, 'span', isTargetNode, findParentNode, '#701625', 'pink', true); } function removeFollowedBy(parent) { if (!parent) return; function isTargetNode(n) { const nodeText = n.innerText; return nodeText.endsWith(" suivent") || nodeText.endsWith(" suit") || nodeText.endsWith(" follow"); } removeMatchingNodes(parent, 'a', isTargetNode, n => n.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode, '#0f3d82', 'lightblue', false); } function removeLikedBy(parent) { if (!parent) return; function isTargetNode(n) { const nodeText = n.innerText; return nodeText.endsWith(" a aimé") || nodeText.endsWith(" ont aimé") || nodeText.endsWith(" liked"); } removeMatchingNodes(parent, 'a', isTargetNode, n => n.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode, '#49491c', 'black', true); } function removeSponsoredSection(section) { section.hidden = true; section.style.display = "none"; } const observer = new MutationObserver(function(mutationsList, observer) { // we just look at the whole page each time; it's fast enough and seems to work. removeTrendAds(findTrendingSection(document)); // trends are only loaded once (and always dynamically) so theoretically we could disable this after it finds any once. removeSuggestionsAds(findSuggestionsSection(document)); // probably same removeSponsoredSection(findSponsoredSection(document)); const newsfeed = findNewsfeed(); removeAds(newsfeed); removeLikedBy(newsfeed); removeFollowedBy(newsfeed); }); observer.observe(document.body, { childList: true, subtree: true }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址