您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
隐藏/删除推特时间线中的推荐内容和侧边栏推荐
// ==UserScript== // @name 推特(x.com)网页端清理脚本 // @namespace http://tampermonkey.net/ // @version 1.0 // @description 隐藏/删除推特时间线中的推荐内容和侧边栏推荐 // @author You // @match https://x.com/* // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; let isExecuting = false; let processedElements = new Set(); let lastScrollTop = 0; let scrollCheckInterval = null; //匹配 x.com/abc123 个人主页,也匹配了平台主页 x.com/home let userPattern = /^\/([^\/?#]+)$/; //匹配 x.com/abc123/1234567890 ,不匹配 x.com/abc123/with_replies let statusPattern = /^\/[^\/?#]+\/status\/\d+$/; function 隐藏status发现更多之后的推荐() { console.log('执行/status/页清理操作,隐藏"发现更多"之后的推荐'); const targetSpan = Array.from(document.querySelectorAll('span')) .find(span => span.textContent.includes('发现更多')); if (!targetSpan) return false; const outerDiv = targetSpan.closest('div[style*="translateY"]'); if (!outerDiv) return false; // 获取目标元素的translateY值作为参考点 const style = outerDiv.getAttribute('style'); const translateYMatch = style.match(/translateY\(([^)]+)\)/); if (!translateYMatch) return false; const targetTranslateY = parseFloat(translateYMatch[1].replace('px', '')); // 查找并隐藏所有translateY值大于目标值的div中的推荐内容 let 隐藏计数 = 0; const allDivs = document.querySelectorAll('div[style*="translateY"]'); allDivs.forEach(div => { const divStyle = div.getAttribute('style'); const divTranslateYMatch = divStyle.match(/translateY\(([^)]+)\)/); if (divTranslateYMatch) { const divTranslateY = parseFloat(divTranslateYMatch[1].replace('px', '')); if (divTranslateY > targetTranslateY) { const targetChild = div.querySelector('div > div > article > div > div > div:nth-child(2)'); if (targetChild && targetChild.offsetParent !== null) { // 检查元素是否可见 targetChild.style.display = 'none'; 隐藏计数++; } } } }); if (隐藏计数 > 0) { console.log(`已隐藏 ${隐藏计数} 个推荐内容`); return true; } return false; } function 隐藏主页时间线中的转发(用户名){ const tweetContainers = document.querySelectorAll('div[data-testid="cellInnerDiv"]'); let hiddenCount = 0; tweetContainers.forEach(container => { const isRetweet = container.querySelector('[data-testid="socialContext"]'); if (!isRetweet) return; const userAvatar = container.querySelector(`[data-testid="UserAvatar-Container-${用户名}"]`); if (!userAvatar) { // 隐藏而不是删除,避免破坏布局 container.style.display = 'none'; container.setAttribute('data-hidden', 'true'); hiddenCount++; } }); if (hiddenCount > 0) { console.log(`隐藏了 ${hiddenCount} 个非目标用户转发`); } } function 删除主页时间线中的推荐(){ const buttons = document.querySelectorAll('button.css-175oi2r.r-1mmae3n.r-3pj75a.r-1loqt21.r-o7ynqc.r-6416eg.r-1ny4l3l'); let modifiedCount = 0; buttons.forEach(button => { if (processedElements.has(button)) return; button.innerHTML = ''; const span = document.createElement('span'); span.textContent = '不值得关注'; button.appendChild(span); processedElements.add(button); modifiedCount++; }); if (modifiedCount > 0) { console.log(`修改了 ${modifiedCount} 个推荐按钮`); } } function 删除主页时间线中的引用() { const parentDivs = document.querySelectorAll('div.css-175oi2r.r-9aw3ui.r-1s2bzr4'); let modifiedCount = 0; parentDivs.forEach(parentDiv => { if (processedElements.has(parentDiv)) return; // 直接操作父div的子节点,避免层级过深的选择器 // 清空所有子节点 parentDiv.innerHTML = ''; // 创建新的提示信息 const newSpan = document.createElement('span'); newSpan.textContent = '引用已删除'; newSpan.style.cssText = 'color: #666; font-style: italic; padding: 8px; display: block;'; parentDiv.appendChild(newSpan); modifiedCount++; processedElements.add(parentDiv); }); if (modifiedCount > 0) { console.log(`修改了 ${modifiedCount} 个引用节点`); } } function 隐藏主页侧边栏你可能会喜欢() { const aside = document.querySelector('aside[aria-label="推荐关注"][role="complementary"]'); if (aside && !processedElements.has(aside)) { // 隐藏而不是删除,避免布局抖动和重新渲染 //aside.style.opacity = '0.5'; //aside.style.pointerEvents = 'none'; // 或者完全隐藏 aside.style.display = 'none'; processedElements.add(aside); console.log('已隐藏主页侧边栏推荐内容'); } } function 执行主页清理操作(用户名) { console.log('执行主页清理操作'); 隐藏主页侧边栏你可能会喜欢(); 隐藏主页时间线中的转发(用户名); 删除主页时间线中的推荐(); 删除主页时间线中的引用(); } function 执行主逻辑() { if (isExecuting) return; isExecuting = true; const currentPath = window.location.pathname; console.log('执行主逻辑,当前路径:', currentPath); let match; if (statusPattern.test(currentPath)) { console.log('检测到status路径'); setTimeout(() => { 隐藏status发现更多之后的推荐; isExecuting = false; }, 1000); } else if ((match = currentPath.match(userPattern))) { console.log('检测到主页路径'); const 用户名 = match[1]; console.log('用户名:', 用户名); setTimeout(() => { 执行主页清理操作(用户名); isExecuting = false; }, 1000); } else { console.log('检测到普通路径,无动作'); isExecuting = false; } } function 处理URL变化() { console.log('URL发生变化,重新执行主逻辑'); processedElements.clear(); 执行主逻辑(); } function setup监听URL变化() { const originalPushState = history.pushState; const originalReplaceState = history.replaceState; history.pushState = function(...args) { originalPushState.apply(this, args); setTimeout(处理URL变化, 100); }; history.replaceState = function(...args) { originalReplaceState.apply(this, args); setTimeout(处理URL变化, 100); }; window.addEventListener('popstate', () => setTimeout(处理URL变化, 100)); window.addEventListener('hashchange', () => setTimeout(处理URL变化, 100)); } // 新增:滚动检测函数 function 启动滚动检测() { if (scrollCheckInterval) clearInterval(scrollCheckInterval); scrollCheckInterval = setInterval(() => { const currentScrollTop = window.pageYOffset || document.documentElement.scrollTop; // 检测到用户滚动并且滚动距离变化较大 if (Math.abs(currentScrollTop - lastScrollTop) > 100) { lastScrollTop = currentScrollTop; const currentPath = window.location.pathname; const userPattern = /^\/([^\/?#]+)$/; if (userPattern.test(currentPath)) { console.log('检测到滚动,执行清理操作'); 执行主页清理操作(); } } }, 1000); // 每秒检查一次 } function init() { setup监听URL变化(); setTimeout(() => { 执行主逻辑(); 启动滚动检测(); // 启动滚动检测 }, 2000); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } // 简化MutationObserver,只用于检测主要结构变化 const observer = new MutationObserver((mutations) => { const hasSignificantChanges = mutations.some(mutation => { return mutation.addedNodes.length > 0 && Array.from(mutation.addedNodes).some(node => node.nodeType === 1 && ( node.querySelector('article') || node.querySelector('[data-testid="tweet"]') ) ); }); if (hasSignificantChanges) { console.log('检测到DOM重大变化,执行清理操作'); const currentPath = window.location.pathname; const userPattern = /^\/([^\/?#]+)$/; if (userPattern.test(currentPath)) { 执行主页清理操作(); }else if(statusPattern.test(currentPath)){ 隐藏status发现更多之后的推荐(); }else{console.log(currentPath)} } }); observer.observe(document.body, { childList: true, subtree: true }); })();