YT: not interested in one click

Hover a thumbnail to see icons at the right: "Not interested" and "Don't recommend channel"

目前为 2020-11-14 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name YT: not interested in one click
  3. // @description Hover a thumbnail to see icons at the right: "Not interested" and "Don't recommend channel"
  4. // @version 1.0.5
  5. //
  6. // @match https://www.youtube.com/*
  7. //
  8. // @noframes
  9. // @grant none
  10. //
  11. // @author wOxxOm
  12. // @namespace wOxxOm.scripts
  13. // @license MIT License
  14. // ==/UserScript==
  15.  
  16. const ME = 'yt-one-click-dismiss';
  17. const THUMB_TAG = 'ytd-thumbnail';
  18. const COMMANDS = {
  19. NOT_INTERESTED: {block: 'video', text: 'Not interested'},
  20. REMOVE: {block: 'channel', text: "Don't recommend channel"},
  21. DELETE: {block: 'unwatch', text: "Remove from 'Watch later'"},
  22. };
  23. let STYLE;
  24.  
  25. const isThumb = el => el.localName === THUMB_TAG;
  26.  
  27. addEventListener('mouseover', onHover);
  28. addEventListener('click', onClick, true);
  29.  
  30. function onHover(e) {
  31. const thumb = e.composedPath().find(isThumb);
  32. if (thumb && !thumb.getElementsByClassName(ME)[0]) {
  33. for (const type of getMenuItems(thumb))
  34. if (COMMANDS[type])
  35. thumb.appendChild(COMMANDS[type].element);
  36. }
  37. }
  38.  
  39. async function onClick(e) {
  40. const {target} = e;
  41. const {block} = target.classList.contains(ME) && target.dataset;
  42. if (!block)
  43. return;
  44. e.stopPropagation();
  45. e.preventDefault();
  46. try {
  47. const index = STYLE.sheet.insertRule('ytd-menu-popup-renderer { display: none !important }');
  48. for (let more, el = target; el; el = el.parentElement) {
  49. if ((more = el.querySelector('.dropdown-trigger'))) {
  50. await 0;
  51. more.dispatchEvent(new Event('tap'));
  52. await 0;
  53. break;
  54. }
  55. }
  56. for (const el of document.querySelector('ytd-menu-popup-renderer [role="listbox"]').children) {
  57. if (block === (COMMANDS[el.data.icon.iconType] || {}).block) {
  58. el.click();
  59. await new Promise(setTimeout);
  60. break;
  61. }
  62. }
  63. document.body.click()
  64. STYLE.sheet.deleteRule(index);
  65. } catch (e) {}
  66. }
  67.  
  68. function *getMenuItems(thumb) {
  69. try {
  70. for (const {menuServiceItemRenderer: {icon, text}} of thumb.data.menu.menuRenderer.items) {
  71. const type = icon.iconType;
  72. const data = COMMANDS[type];
  73. if (data) {
  74. if (!data.element) {
  75. const el = data.element = document.createElement('div');
  76. el.className = ME;
  77. el.dataset.block = data.block;
  78. el.title = text.runs.map(r => r.text).join('') || data.text;
  79. }
  80. yield type;
  81. }
  82. }
  83. if (!STYLE) initStyle();
  84. } catch (e) {}
  85. }
  86.  
  87. function initStyle() {
  88. STYLE = document.createElement('style');
  89. STYLE.textContent = /*language=CSS*/ `
  90. ${THUMB_TAG}:hover .${ME} {
  91. display: block;
  92. }
  93. .${ME} {
  94. display: none;
  95. position: absolute;
  96. width: 16px;
  97. height: 16px;
  98. border-radius: 100%;
  99. border: 2px solid #fff;
  100. right: 8px;
  101. background: #0006;
  102. box-shadow: .5px .5px 7px #000;
  103. cursor: pointer;
  104. opacity: .75;
  105. z-index: 100;
  106. }
  107. .${ME}:hover {
  108. opacity: 1;
  109. }
  110. .${ME}:active {
  111. color: yellow;
  112. }
  113. .${ME}[data-block] {
  114. top: 70px;
  115. }
  116. .${ME}[data-block="channel"] {
  117. top: 100px;
  118. }
  119. .ytd-playlist-video-renderer .${ME}[data-block="unwatch"] {
  120. top: 15px;
  121. }
  122. .${ME}::after {
  123. content: "";
  124. position: absolute;
  125. top: 0;
  126. left: 0;
  127. right: 0;
  128. bottom: 0;
  129. height: 0;
  130. margin: auto;
  131. border: none;
  132. border-bottom: 2px solid #fff;
  133. }
  134. .${ME}[data-block="video"]::after {
  135. transform: rotate(45deg);
  136. }
  137. .${ME}[data-block="channel"]::after {
  138. margin: auto 3px;
  139. }
  140. `.replace(/;/g, '!important;');
  141. document.head.appendChild(STYLE);
  142. }

QingJ © 2025

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