Twitter 隐藏图片

调整 Twitter 图片的透明度。

  1. // ==UserScript==
  2. // @name Twitter: Hide Image
  3. // @name:zh-TW Twitter 隱藏圖片
  4. // @name:zh-CN Twitter 隐藏图片
  5. // @name:ja Twitter 画像を非表示
  6. // @name:ko Twitter 이미지 숨기기
  7. // @name:ru Twitter Скрыть изображение
  8. // @version 1.0.5
  9. // @description Make Twitter Images Opacity Lower.
  10. // @description:zh-TW 調整 Twitter 圖片的透明度。
  11. // @description:zh-CN 调整 Twitter 图片的透明度。
  12. // @description:ja Twitter 画像の不透明度を低くします。
  13. // @description:ko Twitter 이미지 불투명도를 낮추십시오.
  14. // @description:ru Уменьшите непрозрачность изображений в Twitter.
  15. // @author Hayao-Gai
  16. // @namespace https://github.com/HayaoGai
  17. // @icon https://i.imgur.com/M9oO8K9.png
  18. // @match https://twitter.com/*
  19. // @grant GM_getValue
  20. // @grant GM_setValue
  21. // ==/UserScript==
  22.  
  23. /* jshint esversion: 6 */
  24.  
  25. (function() {
  26. 'use strict';
  27.  
  28. // icons made by https://www.flaticon.com/authors/pixel-perfect
  29. const iconOn = `<svg width="35" height="35" viewBox="0 -107 512 512"><path d="m362.667969 298.667969h-213.335938c-82.34375 0-149.332031-67.007813-149.332031-149.335938 0-82.324219 66.988281-149.332031 149.332031-149.332031h213.335938c82.34375 0 149.332031 67.007812 149.332031 149.332031 0 82.328125-66.988281 149.335938-149.332031 149.335938zm-213.335938-266.667969c-64.703125 0-117.332031 52.652344-117.332031 117.332031 0 64.683594 52.628906 117.335938 117.332031 117.335938h213.335938c64.703125 0 117.332031-52.652344 117.332031-117.335938 0-64.679687-52.628906-117.332031-117.332031-117.332031zm0 0"/><path d="m362.667969 234.667969c-47.0625 0-85.335938-38.273438-85.335938-85.335938 0-47.058593 38.273438-85.332031 85.335938-85.332031 47.058593 0 85.332031 38.273438 85.332031 85.332031 0 47.0625-38.273438 85.335938-85.332031 85.335938zm0-138.667969c-29.398438 0-53.335938 23.914062-53.335938 53.332031 0 29.421875 23.9375 53.335938 53.335938 53.335938 29.394531 0 53.332031-23.914063 53.332031-53.335938 0-29.417969-23.9375-53.332031-53.332031-53.332031zm0 0"/></svg>`;
  30. const iconOff = `<svg width="35" height="35" viewBox="0 -107 512 512"><path d="m362.667969 0h-213.335938c-82.324219 0-149.332031 66.988281-149.332031 149.332031 0 82.347657 67.007812 149.335938 149.332031 149.335938h213.335938c82.324219 0 149.332031-66.988281 149.332031-149.335938 0-82.34375-67.007812-149.332031-149.332031-149.332031zm-213.335938 234.667969c-47.058593 0-85.332031-38.273438-85.332031-85.335938 0-47.058593 38.273438-85.332031 85.332031-85.332031 47.0625 0 85.335938 38.273438 85.335938 85.332031 0 47.0625-38.273438 85.335938-85.335938 85.335938zm0 0"/></svg>`;
  31. const textStyle = `
  32. .hide-set {
  33. transition: opacity 0.3s;
  34. opacity: 0.1;
  35. }
  36. .show-set {
  37. opacity: 1 !important;
  38. }
  39. .icon-set {
  40. position: absolute;
  41. transition: opacity 0.3s;
  42. }
  43. .toggle-off-set {
  44. opacity: 0 !important;
  45. }`;
  46. const colors = ["r-13gxpu9", "r-61mi1v", "r-daml9f", "r-xfsgu1", "r-1qkqhnw", "r-nw8l94"];
  47. let currentUrl = document.location.href;
  48. let updating = false;
  49.  
  50. css();
  51.  
  52. init(10);
  53.  
  54. locationChange();
  55.  
  56. window.addEventListener("scroll", update);
  57.  
  58. function init(times) {
  59. for (let i = 0; i < times; i++) {
  60. setTimeout(addToggle, 500 * i);
  61. setTimeout(sortToggle, 500 * i);
  62. setTimeout(findImage, 500 * i);
  63. setTimeout(removeBlock, 500 * i);
  64. setTimeout(showImage, 500 * i);
  65. }
  66. }
  67.  
  68. // toggle
  69. function addToggle() {
  70. // exist
  71. if (!!document.querySelector(".toggle-set")) return;
  72. // check
  73. const panel = document.querySelector(".r-1awozwy.r-1h3ijdo.r-1777fci") || document.querySelector(".r-18u37iz.r-1ye8kvj");
  74. if (!panel) return;
  75. // create
  76. const div1 = document.createElement("div");
  77. div1.className = "css-1dbjc4n r-obd0qt r-1pz39u2 r-1777fci r-1joea0r r-1vsu8ta r-18qmn74 toggle-set";
  78. div1.addEventListener("click", () => onClick(divOn, divOff));
  79. const div2 = document.createElement("div");
  80. div2.className = "css-18t94o4 css-1dbjc4n r-1niwhzg r-42olwf r-sdzlij r-1phboty r-rs99b7 r-1w2pmg r-1vuscfd r-53xb7h r-1ny4l3l r-mk0yit r-o7ynqc r-6416eg r-lrvibr";
  81. const divOn = document.createElement("div");
  82. divOn.className = `css-901oao r-1awozwy r-6koalj r-18u37iz r-16y2uox r-1qd0xha r-a023e6 r-vw2c0b r-1777fci r-eljoum r-dnmrzs r-bcqeeo r-q4m81j r-qvutc0 icon-set ${getColor()}`;
  83. divOn.innerHTML = iconOn;
  84. const svg1 = divOn.querySelector("svg");
  85. svg1.setAttribute("class", `r-4qtqp9 r-yyyyoo r-1q142lx r-dnmrzs r-bnwqim r-1plcrui r-lrvibr ${getColor()}`);
  86. const divOff = document.createElement("div");
  87. divOff.className = `css-901oao r-1awozwy r-6koalj r-18u37iz r-16y2uox r-1qd0xha r-a023e6 r-vw2c0b r-1777fci r-eljoum r-dnmrzs r-bcqeeo r-q4m81j r-qvutc0 icon-set ${getColor()}`;
  88. divOff.innerHTML = iconOff;
  89. const svg2 = divOff.querySelector("svg");
  90. svg2.setAttribute("class", `r-4qtqp9 r-yyyyoo r-1q142lx r-dnmrzs r-bnwqim r-1plcrui r-lrvibr ${getColor()}`);
  91. // on or off
  92. if (getToggle()) divOff.classList.add("toggle-off-set");
  93. else divOn.classList.add("toggle-off-set");
  94. // append
  95. panel.appendChild(div1);
  96. div1.appendChild(div2);
  97. div2.appendChild(divOn);
  98. div2.appendChild(divOff);
  99. }
  100.  
  101. function sortToggle() {
  102. // sometimes, there's a empty div block the toggle bar.
  103. const panel = document.querySelector(".r-1awozwy.r-1h3ijdo.r-1777fci");
  104. if (!panel) return;
  105. const lastChild = panel.lastElementChild;
  106. if (lastChild.childElementCount === 0) lastChild.remove();
  107. }
  108.  
  109. function onClick(on, off) {
  110. const afterClick = !getToggle();
  111. GM_setValue("toggle", afterClick);
  112. if (afterClick) {
  113. on.classList.remove("toggle-off-set");
  114. off.classList.add("toggle-off-set");
  115. } else {
  116. on.classList.add("toggle-off-set");
  117. off.classList.remove("toggle-off-set");
  118. }
  119. init(3);
  120. }
  121.  
  122. function getColor() {
  123. let finalColor = "";
  124. document.querySelectorAll("svg.r-50lct3").forEach(svg => {
  125. if (!!finalColor) return;
  126. const svgClass = svg.className.baseVal;
  127. for (const color of colors) {
  128. if (svgClass.includes(color)) {
  129. finalColor = color;
  130. }
  131. }
  132. });
  133. return finalColor;
  134. }
  135.  
  136. function getToggle() {
  137. return GM_getValue("toggle", true);
  138. }
  139.  
  140. // hide
  141. function findImage() {
  142. // toggle
  143. if (!getToggle()) return;
  144. // all images
  145. document.querySelectorAll(".r-4gszlv:not(.check-set)").forEach(function(image) {
  146. image.classList.add("check-set");
  147. // except emoji
  148. if (image.style.backgroundImage.includes("svg")) return;
  149. if (!image.className.includes("hide-set")) image.classList.add("hide-set");
  150. image.classList.remove("show-set");
  151. // event
  152. const touch = image.parentElement.querySelector("img");
  153. touch.addEventListener("mouseenter", imageListener);
  154. touch.addEventListener("mouseleave", imageListener);
  155. });
  156. }
  157.  
  158. function removeBlock() {
  159. // remove the div block on every avatar.
  160. document.querySelectorAll(".r-1twgtwe").forEach(block => block.remove());
  161. }
  162.  
  163. function imageListener() {
  164. const image = this.parentElement.querySelector("div");
  165. const isHiding = !image.className.includes("show-set");
  166. if (isHiding) image.classList.add("show-set");
  167. else image.classList.remove("show-set");
  168. }
  169.  
  170. // show
  171. function showImage() {
  172. // toggle
  173. if (getToggle()) return;
  174. // all images
  175. document.querySelectorAll(".check-set").forEach(function(image) {
  176. image.classList.remove("check-set");
  177. // except emoji
  178. if (image.style.backgroundImage.includes("svg")) return;
  179. image.classList.add("show-set");
  180. // event
  181. const touch = image.parentElement.querySelector("img");
  182. touch.removeEventListener("mouseenter", imageListener);
  183. touch.removeEventListener("mouseleave", imageListener);
  184. });
  185. }
  186.  
  187. // other
  188. function css() {
  189. const style = document.createElement("style");
  190. style.type = "text/css";
  191. style.innerHTML = textStyle;
  192. document.querySelector("head").appendChild(style);
  193. }
  194.  
  195. function update() {
  196. if (updating) return;
  197. updating = true;
  198. init(3);
  199. setTimeout(() => { updating = false; }, 1000);
  200. }
  201.  
  202. function locationChange() {
  203. const observer = new MutationObserver(mutations => {
  204. mutations.forEach(() => {
  205. if (currentUrl !== document.location.href) {
  206. currentUrl = document.location.href;
  207. init(10);
  208. }
  209. });
  210. });
  211. const target = document.querySelector("body");
  212. const config = { childList: true, subtree: true };
  213. observer.observe(target, config);
  214. }
  215.  
  216. })();

QingJ © 2025

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