Hide Text on Twitter

Hide text from your TL to make viewing illustrations more comfortable

  1. // ==UserScript==
  2. // @name Hide Text on Twitter
  3. // @name:ja Twitter TLからテキストを消すやつ
  4. // @namespace http://tampermonkey.net/
  5. // @version 1.1.2
  6. // @description Hide text from your TL to make viewing illustrations more comfortable
  7. // @description:ja タイムラインからテキストをすべて非表示します。イラスト閲覧が快適になります。
  8. // @author Nogaccho
  9. // @match https://twitter.com/*
  10. // @match https://x.com/*
  11. // @grant none
  12. // @license MIT
  13. // ==/UserScript==
  14.  
  15. (function () {
  16. 'use strict';
  17.  
  18. let filterEnabled = true;
  19. let scrollTimeout;// スクロールイベントのタイムアウトを制御する変数
  20.  
  21. // 要素が画面内にあるかどうかを判定する関数
  22. const isVisible = (elem) => {
  23. const rect = elem.getBoundingClientRect();
  24. const viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
  25. return !(rect.bottom < 0 || rect.top - viewHeight >= 0);
  26. };
  27.  
  28. const updateVisibleTweets = () => {
  29. document.querySelectorAll('article').forEach(tweet => {
  30. if (!isVisible(tweet)) return;
  31.  
  32. if (!filterEnabled) {
  33. tweet.style.display = '';
  34. const textElements = tweet.querySelectorAll('div[dir="auto"]');
  35. textElements.forEach(element => {
  36. element.style.display = '';
  37. });
  38. return;
  39. }
  40.  
  41. const hasMediaLink = tweet.innerHTML.includes('https://pbs.twimg.com/media/');
  42. const textElements = tweet.querySelectorAll('div[dir="auto"]');
  43.  
  44. if (hasMediaLink) {
  45. const hasTextContent = Array.from(textElements).some(element => element.textContent.trim() !== '');
  46. if (hasTextContent) {
  47. textElements.forEach(element => {
  48. element.style.display = 'none';
  49. });
  50. }
  51. } else {
  52. tweet.style.display = 'none';
  53. }
  54. });
  55. };
  56.  
  57. // 更新を遅延させる関数
  58. const delayedUpdate = () => {
  59. clearTimeout(scrollTimeout);
  60. scrollTimeout = setTimeout(updateVisibleTweets, 50);
  61. };
  62.  
  63. // ON/OFF切り替えボタンを作成する関数
  64. const createToggleButton = () => {
  65. const toggleButton = document.createElement('input');
  66. toggleButton.type = 'checkbox';
  67. toggleButton.checked = true;
  68. toggleButton.style.position = 'fixed';
  69. toggleButton.style.top = '10px';
  70. toggleButton.style.right = '10px';
  71. toggleButton.style.zIndex = '1000';
  72. toggleButton.style.width = '20px';
  73. toggleButton.style.height = '20px';
  74. toggleButton.style.borderRadius = '100px'; // 角丸の設定
  75. toggleButton.style.border = '2px solid #555'; // 枠線の色と太さ
  76. toggleButton.style.backgroundColor = '#fff'; // 背景色
  77. toggleButton.style.cursor = 'pointer'; // カーソルをポインターに設定
  78.  
  79. toggleButton.addEventListener('change', () => {
  80. filterEnabled = toggleButton.checked;
  81. updateVisibleTweets();
  82. });
  83.  
  84. document.body.appendChild(toggleButton);
  85. };
  86.  
  87. createToggleButton();
  88.  
  89. window.addEventListener('scroll', delayedUpdate);
  90.  
  91. // DOMの変更を監視するオブザーバー
  92. const observer = new MutationObserver(delayedUpdate);
  93. const config = { childList: true, subtree: true };
  94.  
  95. const targetNode = document.querySelector('div[data-testid="primaryColumn"]') || document.body;
  96.  
  97. setTimeout(() => {
  98. observer.observe(targetNode, config);// Twitterのタイムラインの変化を監視
  99. updateVisibleTweets();
  100. }, 2500);// リロード後、フィルタ機能に2.5秒遅延をかける(ツイートを読み込む前にフィルタをかけるとバグるため)
  101. })();