Hide Twitter Ads

Hide ads on Twitter

// ==UserScript==
// @name         Hide Twitter Ads
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Hide ads on Twitter
// @author       Yeky
// @match        https://x.com/*
// @grant        none
// @name:en    Hide Twitter Ads
// @name:zh    隐藏推特广告
// @description  这个油猴脚本隐藏Twitter上的广告、趋势和用户推荐,提供更干净的浏览体验。
// @description:en  This Tampermonkey script hides ads, trends, and user recommendations on Twitter for a cleaner browsing experience.
// @icon    https://lh3.googleusercontent.com/RhFY2tkBB9MSrgCTDW0JdYnB51bJ_QmEPZRHVISanz34PWFA4CSCwW75m34sR7Oynl38odzKabuCIrWHB44akhHU=s60
// @license    All Rights Reserved
// ==/UserScript==

(function() {
    'use strict';

    var adsHidden = 0;
    var adSelector = "div[data-testid=placementTracking]";
    var trendSelector = "div[data-testid=trend]";
    var userSelector = "div[data-testid=UserCell]";
    var articleSelector = "article[data-testid=tweet]";

    var sponsoredSvgPath = 'M20.75 2H3.25C2.007 2 1 3.007 1 4.25v15.5C1 20.993 2.007 22 3.25 22h17.5c1.243 0 2.25-1.007 2.25-2.25V4.25C23 3.007 21.993 2 20.75 2zM17.5 13.504c0 .483-.392.875-.875.875s-.875-.393-.875-.876V9.967l-7.547 7.546c-.17.17-.395.256-.62.256s-.447-.086-.618-.257c-.342-.342-.342-.896 0-1.237l7.547-7.547h-3.54c-.482 0-.874-.393-.874-.876s.392-.875.875-.875h5.65c.483 0 .875.39.875.874v5.65z';
    var sponsoredBySvgPath = 'M19.498 3h-15c-1.381 0-2.5 1.12-2.5 2.5v13c0 1.38 1.119 2.5 2.5 2.5h15c1.381 0 2.5-1.12 2.5-2.5v-13c0-1.38-1.119-2.5-2.5-2.5zm-3.502 12h-2v-3.59l-5.293 5.3-1.414-1.42L12.581 10H8.996V8h7v7z';
    var youMightLikeSvgPath = 'M12 1.75c-5.11 0-9.25 4.14-9.25 9.25 0 4.77 3.61 8.7 8.25 9.2v2.96l1.15-.17c1.88-.29 4.11-1.56 5.87-3.5 1.79-1.96 3.17-4.69 3.23-7.97.09-5.54-4.14-9.77-9.25-9.77zM13 14H9v-2h4v2zm2-4H9V8h6v2z';
    var adsSvgPath = 'M19.498 3h-15c-1.381 0-2.5 1.12-2.5 2.5v13c0 1.38 1.119 2.5 2.5 2.5h15c1.381 0 2.5-1.12 2.5-2.5v-13c0-1.38-1.119-2.5-2.5-2.5zm-3.502 12h-2v-3.59l-5.293 5.3-1.414-1.42L12.581 10H8.996V8h7v7z';
    var peopleFollowSvgPath = 'M17.863 13.44c1.477 1.58 2.366 3.8 2.632 6.46l.11 1.1H3.395l.11-1.1c.266-2.66 1.155-4.88 2.632-6.46C7.627 11.85 9.648 11 12 11s4.373.85 5.863 2.44zM12 2C9.791 2 8 3.79 8 6s1.791 4 4 4 4-1.79 4-4-1.791-4-4-4z';
    var xAd = '>Ad<'; // TODO: add more languages; appears to only be used for English accounts as of 2023-08-03
    var removePeopleToFollow = false; // set to 'true' if you want these suggestions removed, however note this also deletes some tweet replies
    const promotedTweetTextSet = new Set(['Promoted Tweet', 'プロモツイート']);

    function getAds() {
      return Array.from(document.querySelectorAll('div')).filter(function(el) {
        var filteredAd;

        if (el.innerHTML.includes(sponsoredSvgPath)) {
          filteredAd = el;
        } else if (el.innerHTML.includes(sponsoredBySvgPath)) {
          filteredAd = el;
        } else if (el.innerHTML.includes(youMightLikeSvgPath)) {
          filteredAd = el;
        } else if (el.innerHTML.includes(adsSvgPath)) {
          filteredAd = el;
        } else if (removePeopleToFollow && el.innerHTML.includes(peopleFollowSvgPath)) {
          filteredAd = el;
        } else if (el.innerHTML.includes(xAd)) {
          filteredAd = el;
        } else if (promotedTweetTextSet.has(el.innerText)) { // TODO: bring back multi-lingual support from git history
          filteredAd = el;
        }

        return filteredAd;
      })
    }

    function hideAd(ad) {
      if (ad.closest(adSelector) !== null) { // Promoted tweets
        ad.closest(adSelector).remove();
        adsHidden += 1;
      } else if (ad.closest(trendSelector) !== null) {
        ad.closest(trendSelector).remove();
        adsHidden += 1;
      } else if (ad.closest(userSelector) !== null) {
        ad.closest(userSelector).remove();
        adsHidden += 1;
      } else if (ad.closest(articleSelector) !== null) {
        ad.closest(articleSelector).remove();
        adsHidden += 1;
      } else if (promotedTweetTextSet.has(ad.innerText)) {
        ad.remove();
        adsHidden += 1;
      }

      console.log('X ads hidden: ', adsHidden.toString());
    }

    function getAndHideAds() {
      getAds().forEach(hideAd)
    }

    // hide ads on page load
    window.addEventListener('load', () => getAndHideAds());

    // oftentimes, tweets render after onload. LCP should catch them.
    new PerformanceObserver((entryList) => {
      getAndHideAds();
    }).observe({type: 'largest-contentful-paint', buffered: true});

    // re-check as user scrolls
    window.addEventListener('scroll', () => getAndHideAds());

    // re-check as user scrolls tweet sidebar (exists when image is opened)
    var sidebarExists = setInterval(function() {
      let timelines = document.querySelectorAll("[aria-label='Timeline: Conversation']");

      if (timelines.length == 2) {
        let tweetSidebar = document.querySelectorAll("[aria-label='Timeline: Conversation']")[0].parentElement.parentElement;
        tweetSidebar.addEventListener('scroll', () => getAndHideAds());
      }
    }, 500);
})();

QingJ © 2025

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