移除 YouTube Shorts

移除 YouTube 上的 Shorts 标签、Dismissible 元素、Shorts 链接和 Reel Shelf

  1. // ==UserScript==
  2. // @name Remove YouTube Shorts
  3. // @name:zh-CN 移除 YouTube Shorts
  4. // @name:zh-TW 移除 YouTube Shorts
  5. // @name:ja YouTube の Shorts を削除
  6. // @name:ko YouTube Shorts 제거
  7. // @name:es Eliminar YouTube Shorts
  8. // @name:pt-BR Remover YouTube Shorts
  9. // @name:ru Удалить YouTube Shorts
  10. // @name:id Hapus YouTube Shorts
  11. // @name:hi YouTube Shorts हटाएँ
  12. // @namespace https://github.com/strangeZombies
  13. // @version 2025.4.4.0
  14. // @description Remove YouTube Shorts tags, dismissible elements, Shorts links, and Reel Shelf
  15. // @description:zh-CN 移除 YouTube 上的 Shorts 标签、Dismissible 元素、Shorts 链接和 Reel Shelf
  16. // @description:zh-TW 移除 YouTube 上的 Shorts 标签、Dismissible 元素、Shorts 链接和 Reel Shelf
  17. // @description:ja YouTube 上の Shorts タグ、ディスミッシブル要素、Shorts リンク、および Reel Shelf を削除
  18. // @description:ko YouTube의 Shorts 태그, 해제 가능한 요소, Shorts 링크 및 Reel 선반 제거
  19. // @description:es Eliminar etiquetas de Shorts de YouTube, elementos desechables, enlaces de Shorts y estante de carretes
  20. // @description:pt-BR Remover tags de Shorts do YouTube, elementos descartáveis, links de Shorts e prateleira de rolos
  21. // @description:ru Удалите теги YouTube Shorts, элементы, которые можно отклонить, ссылки на Shorts и полку с катушками
  22. // @description:id Hapus tag Shorts YouTube, elemen yang dapat dihapus, tautan Shorts, dan Rak Reel
  23. // @description:hi YouTube Shorts टैग, खारिज करने योग्य तत्व, Shorts लिंक और Reel Shelf निकालें
  24. // @author StrangeZombies
  25. // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
  26. // @match https://*.youtube.com/*
  27. // @match https://m.youtube.com/*
  28. // @grant none
  29. // @run-at document-start
  30. // ==/UserScript==
  31.  
  32. (function () {
  33. 'use strict';
  34.  
  35. // 配置项
  36. const hideHistoryShorts = false; // 是否移除历史记录中的 Shorts 元素
  37. const debug = false; // 启用调试模式
  38.  
  39. // 通用选择器
  40. const commonSelectors = [
  41. 'a[href*="/shorts/"]',
  42. '[is-shorts]',
  43. 'yt-chip-cloud-chip-renderer:has(a[href*="/shorts/"])',
  44. 'ytd-reel-shelf-renderer',
  45. 'ytd-thumbnail-overlay-time-status-renderer[overlay-style="SHORTS"]',
  46. '#guide [title="Shorts"]',
  47. '.ytd-mini-guide-entry-renderer[title="Shorts"]',
  48. '.ytd-mini-guide-entry-renderer[aria-label="Shorts"]',
  49. ];
  50.  
  51. // 移动端选择器
  52. const mobileSelectors = [
  53. '.pivot-shorts',
  54. 'ytm-reel-shelf-renderer',
  55. 'ytm-search ytm-video-with-context-renderer [data-style="SHORTS"]',
  56. ];
  57.  
  58. // 特定页面选择器
  59. const feedSelectors = [
  60. 'ytd-browse[page-subtype="subscriptions"] ytd-grid-video-renderer [overlay-style="SHORTS"]',
  61. 'ytd-browse[page-subtype="subscriptions"] ytd-video-renderer [overlay-style="SHORTS"]',
  62. 'ytd-browse[page-subtype="subscriptions"] ytd-rich-item-renderer [overlay-style="SHORTS"]',
  63. ];
  64. const channelSelectors = ['yt-tab-shape[tab-title="Shorts"]'];
  65. const historySelectors = ['ytd-browse[page-subtype="history"] ytd-reel-shelf-renderer'];
  66.  
  67. // 移除 Shorts 元素的函数
  68. function removeElementsBySelectors(selectors) {
  69. selectors.forEach((selector) => {
  70. try {
  71. const elements = document.querySelectorAll(selector);
  72. elements.forEach((element) => {
  73. if (element.dataset.removedByScript) return; // 跳过已处理的元素
  74. let parent = element.closest(
  75. 'ytd-video-renderer, ytd-grid-video-renderer, ytd-compact-video-renderer, ytd-rich-item-renderer, ytm-video-with-context-renderer'
  76. );
  77. if (!parent) parent = element;
  78. parent.remove();
  79. parent.dataset.removedByScript = 'true'; // 标记为已处理
  80. if (debug) console.log(`Removed element: ${parent}`);
  81. });
  82. } catch (error) {
  83. if (debug) console.warn(`Error processing selector: ${selector}`, error);
  84. }
  85. });
  86. }
  87.  
  88. // 根据 URL 定位要处理的选择器
  89. function removeElements() {
  90. const currentUrl = window.location.href;
  91. if (debug) console.log('Current URL:', currentUrl);
  92.  
  93. if (currentUrl.includes('m.youtube.com')) {
  94. removeElementsBySelectors(mobileSelectors);
  95. }
  96. if (currentUrl.includes('/feed/subscriptions')) {
  97. removeElementsBySelectors(feedSelectors);
  98. }
  99. // 需要重新做,因为会多删除,还有其它bug在其它部分,还没来得及搞,能用就行
  100. //if (currentUrl.includes('/channel') || currentUrl.includes('/@')) {
  101. // removeElementsBySelectors(channelSelectors);
  102. //}
  103. if (hideHistoryShorts && currentUrl.includes('/feed/history')) {
  104. removeElementsBySelectors(historySelectors);
  105. }
  106.  
  107. // 通用选择器适用于所有页面
  108. removeElementsBySelectors(commonSelectors);
  109. }
  110.  
  111. // 防抖函数
  112. function debounce(func, delay) {
  113. let timeout;
  114. return (...args) => {
  115. clearTimeout(timeout);
  116. timeout = setTimeout(() => func.apply(this, args), delay);
  117. };
  118. }
  119.  
  120. const debouncedRemoveElements = debounce(removeElements, 300);
  121.  
  122. // 初始化脚本
  123. function init() {
  124. if (debug) console.log('Remove YouTube Shorts script activated');
  125. removeElements(); // 初次加载时执行清理
  126.  
  127. // 跨浏览器支持的导航事件
  128. const isFirefox = navigator.userAgent.includes('Firefox');
  129. if (isFirefox) {
  130. // Firefox 使用 popstate 监听导航变化
  131. window.addEventListener('popstate', removeElements);
  132. } else {
  133. // Chrome 使用 yt-navigate 事件
  134. document.addEventListener('yt-navigate-finish', removeElements);
  135. }
  136.  
  137. // 监听 DOM 变化
  138. const observer = new MutationObserver(debouncedRemoveElements);
  139. observer.observe(document.body, { childList: true, subtree: true });
  140. }
  141.  
  142. // 等待 DOM 完全加载后初始化脚本
  143. if (document.readyState === 'loading') {
  144. document.addEventListener('DOMContentLoaded', init);
  145. } else {
  146. init();
  147. }
  148. })();
  149.  
  150. //const selectors = [
  151. // https://gist.github.com/sumonst21/1779307b807509488d1a915d2bd370bd
  152. // '[is-shorts]', // YT Homepage - Hide the Shorts section
  153. // '#guide [title="Shorts"]', // YT Menu - Hide the Shorts button
  154. // '.ytd-mini-guide-entry-renderer[title="Shorts"]', // YT Menu - Hide the Shorts button
  155. // 'ytd-search ytd-video-renderer [overlay-style="SHORTS"]:upward(ytd-video-renderer)', // YT Search - Hide Shorts
  156. // 'ytd-reel-shelf-renderer',
  157. // 'ytd-browse[page-subtype="channels"] [role="tab"]:nth-of-type(3):has-text(Shorts)', // YT Channels - Hide the Shorts tab
  158. // 'ytd-browse[page-subtype="subscriptions"] ytd-grid-video-renderer [overlay-style="SHORTS"]:upward(ytd-grid-video-renderer)', // YT Subscriptions - Hide Shorts - Grid View
  159. // 'ytd-browse[page-subtype="subscriptions"] ytd-video-renderer [overlay-style="SHORTS"]:upward(ytd-item-section-renderer)', // YT Subscriptions - Hide Shorts - List View
  160. // 'ytd-browse[page-subtype="subscriptions"] ytd-rich-item-renderer [overlay-style="SHORTS"]:upward(ytd-rich-item-renderer)', // YT Subscriptions - New Layout - Hide Shorts
  161. // '#related ytd-compact-video-renderer [overlay-style="SHORTS"]:upward(ytd-compact-video-renderer)', // YT Sidebar - Hide Shorts
  162. // '.pivot-shorts:upward(ytm-pivot-bar-item-renderer)', // YT Mobile - Hide the Shorts Menu button
  163. // 'ytm-reel-shelf-renderer', // YT Mobile - Hide Shorts sections
  164. // 'ytm-search ytm-video-with-context-renderer [data-style="SHORTS"]', // YT Mobile - Hide Shorts in search results
  165. //];

QingJ © 2025

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