YouTube: Search results in Grid view

See more results in one go, without irrelevant results, such as 'People also watched' and 'For you', in the way.

目前为 2023-12-21 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name YouTube: Search results in Grid view
  3. // @namespace https://greasyfork.org/users/1166888-pedro
  4. // @match https://www.youtube.com/*
  5. // @version 2023.12.20
  6. // @author Pedro
  7. // @description See more results in one go, without irrelevant results, such as 'People also watched' and 'For you', in the way.
  8. // @grant GM_registerMenuCommand
  9. // @grant GM_setValue
  10. // @grant GM_getValue
  11. // @compatible Chrome
  12. // @compatible Safari
  13. // @compatible Firefox
  14. // @license MIT
  15. // ==/UserScript==
  16. GM_registerMenuCommand('Settings', settingsMenu);
  17.  
  18. function settingsMenu() {
  19. const menu = document.createElement('settings-menu');
  20. document.documentElement.appendChild(menu);
  21. menu.insertAdjacentHTML('afterbegin', `
  22. <div>
  23. <header>
  24. <span>Settings</span>
  25. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
  26. <path d="M0 0h24v24H0V0z" fill="none" opacity=".87"></path>
  27. <path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm4.3 14.3c-.39.39-1.02.39-1.41 0L12 13.41 9.11 16.3c-.39.39-1.02.39-1.41 0-.39-.39-.39-1.02 0-1.41L10.59 12 7.7 9.11c-.39-.39-.39-1.02 0-1.41.39-.39 1.02-.39 1.41 0L12 10.59l2.89-2.89c.39-.39 1.02-.39 1.41 0 .39.39.39 1.02 0 1.41L13.41 12l2.89 2.89c.38.38.38 1.02 0 1.41z"></path>
  28. </svg>
  29. </header>
  30. <label>
  31. <span>Videos per row</span>
  32. <input type="number" id="videosPerRow">
  33. </label>
  34. <label>
  35. <span>Hide right sidebar</span>
  36. <input type="checkbox" id="hideRightSidebar">
  37. </label>
  38. <style>
  39. settings-menu svg {
  40. color: var(--background-3);
  41. width: 24px;
  42. height: 24px;
  43. transition: 0.4s;
  44. }
  45.  
  46. settings-menu svg:hover {
  47. color: inherit;
  48. transform: rotate(-90deg);
  49. }
  50.  
  51. settings-menu svg:active {
  52. transform: scale(1.5);
  53. }
  54.  
  55. settings-menu div {
  56. margin: 10px;
  57. }
  58.  
  59. settings-menu {
  60. width: 225px;
  61. position: fixed;
  62. background: var(--background);
  63. top: 20px;
  64. right: 20px;
  65. z-index: 9999;
  66. color: var(--text);
  67. font-size: 1.4rem;
  68. border-radius: 12px;
  69. box-shadow: 0 4px 32px 0 rgba(0, 0, 0, 0.1);
  70. font-weight: 400;
  71. border: 1px solid var(--border);
  72. }
  73.  
  74. settings-menu header {
  75. font-size: 1.7rem;
  76. font-weight: 500
  77. }
  78.  
  79. settings-menu header,
  80. settings-menu label {
  81. padding: 6px;
  82. display: flex;
  83. align-items: center;
  84. }
  85.  
  86. settings-menu svg,
  87. settings-menu label {
  88. cursor: pointer;
  89. }
  90.  
  91. settings-menu span {
  92. flex-grow: 1;
  93. }
  94.  
  95. settings-menu [type="number"] {
  96. font-family: "Roboto";
  97. font-size: inherit;
  98. box-sizing: border-box;
  99. border: none;
  100. width: 60px;
  101. height: 30px;
  102. background: var(--background-2);
  103. color: inherit;
  104. outline: none;
  105. border-radius: 5px;
  106. padding: 0 3px;
  107. }
  108.  
  109. settings-menu [type="number"]::-webkit-inner-spin-button {
  110. height: 30px;
  111. }
  112.  
  113. settings-menu [type="checkbox"] {
  114. appearance: none;
  115. -webkit-tap-highlight-color: transparent;
  116. position: relative;
  117. border: 0;
  118. outline: 0;
  119. width: 37.5px;
  120. height: 24px;
  121. cursor: pointer;
  122. }
  123.  
  124. settings-menu [type="checkbox"]:after {
  125. content: "";
  126. width: 100%;
  127. height: 100%;
  128. display: inline-block;
  129. border-radius: 100px;
  130. clear: both;
  131. background: var(--toggle-button-track);
  132. transition: background-color linear 0.08s;
  133. }
  134.  
  135. settings-menu [type="checkbox"]:checked:after {
  136. background: #1db954;
  137. }
  138.  
  139. settings-menu [type="checkbox"]:before {
  140. content: "";
  141. height: 19.5px;
  142. width: 19.5px;
  143. display: block;
  144. position: absolute;
  145. left: 0;
  146. top: 2px;
  147. border-radius: 50%;
  148. background: #fff;
  149. box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1), 0 2px 3px 0 rgba(0, 0, 0, 0.2);
  150. transform: translateX(2px);
  151. transition: transform linear 0.1s, background-color linear 0.08s;
  152. }
  153.  
  154. settings-menu [type="checkbox"]:checked:before {
  155. transform: translateX(80%);
  156. transition: transform linear 0.1s, background-color linear 0.08s;
  157. }
  158.  
  159. @media (prefers-color-scheme: dark) {
  160. :root {
  161. color-scheme: dark;
  162. --text: #f1f1f1;
  163. --background: #121212;
  164. --background-2: #272727;
  165. --background-3: #999;
  166. --toggle-button-track: rgba(113, 113, 113, 0.4);
  167. --border: rgba(255, 255, 255, 0.2)
  168. }
  169. }
  170.  
  171. @media (prefers-color-scheme: light) {
  172. :root {
  173. --text: #030303;
  174. --background: #fff;
  175. --background-2: #e5e5e5;
  176. --background-3: #666;
  177. --toggle-button-track: rgba(144, 144, 144, 0.4);
  178. }
  179. }
  180. </style>
  181. </div>`);
  182.  
  183. menu.addEventListener('change', function(event) {
  184. if (event.target.type === 'number') {
  185. GM_setValue('videosPerRow', event.target.value);
  186. document.documentElement.style.setProperty('--videos-per-row', event.target.value);
  187. } else {
  188. GM_setValue('hideRightSidebar', event.target.checked);
  189. document.documentElement.classList.toggle('hideRightSidebar');
  190. }
  191. });
  192.  
  193. menu.querySelector('#videosPerRow').value = GM_getValue('videosPerRow') || 5;
  194. menu.querySelector('#hideRightSidebar').checked = GM_getValue('hideRightSidebar');
  195. menu.querySelector('svg').addEventListener('click', function() {
  196. menu.remove();
  197. });
  198. }
  199.  
  200. document.documentElement.style.setProperty('--videos-per-row', GM_getValue('videosPerRow') || 5);
  201. if (GM_getValue('hideRightSidebar')) document.documentElement.classList.add('hideRightSidebar');
  202.  
  203. document.documentElement.insertAdjacentHTML('beforeend', `
  204. <style>
  205. ytd-search ytd-search-pyv-renderer,
  206. ytd-search ytd-ad-slot-renderer,
  207. ytd-search .metadata-snippet-container-one-line.ytd-video-renderer,
  208. ytd-search .metadata-snippet-container.ytd-video-renderer,
  209. ytd-search #description-text.ytd-video-renderer,
  210. ytd-search #description.ytd-channel-renderer,
  211. ytd-search #list,
  212. ytd-search #expandable-metadata.ytd-video-renderer:not(:empty),
  213. ytd-search ytd-exploratory-results-renderer.ytd-item-section-renderer,
  214. ytd-search ytd-horizontal-card-list-renderer.ytd-item-section-renderer:not(:first-child),
  215. ytd-search ytd-reel-shelf-renderer.ytd-item-section-renderer,
  216. ytd-search ytd-shelf-renderer.ytd-item-section-renderer,
  217. .hideRightSidebar ytd-search #secondary.ytd-two-column-search-results-renderer {
  218. display: none !important;
  219. }
  220.  
  221. ytd-search #view-more.ytd-playlist-renderer {
  222. display: block;
  223. }
  224.  
  225. ytd-search #container.ytd-search {
  226. width: 100%;
  227. max-width: calc(var(--videos-per-row) * (var(--ytd-rich-grid-item-max-width) + var(--ytd-rich-grid-item-margin)));
  228. }
  229.  
  230. ytd-search #header.ytd-search,
  231. ytd-search ytd-two-column-search-results-renderer,
  232. ytd-search #primary.ytd-two-column-search-results-renderer {
  233. max-width: 100% !important;
  234. }
  235.  
  236. ytd-search #contents>ytd-item-section-renderer,
  237. ytd-search #contents>ytd-item-section-renderer>#contents {
  238. display: contents;
  239. }
  240.  
  241. ytd-search #contents.ytd-section-list-renderer {
  242. display: flex;
  243. flex-wrap: wrap;
  244. }
  245.  
  246. ytd-search ytd-video-renderer,
  247. ytd-search ytd-radio-renderer,
  248. ytd-search ytd-playlist-renderer,
  249. ytd-search ytd-show-renderer,
  250. ytd-search ytd-channel-renderer {
  251. margin-left: calc(var(--ytd-rich-grid-item-margin) / 2);
  252. margin-right: calc(var(--ytd-rich-grid-item-margin) / 2);
  253. width: calc(100% / var(--videos-per-row) - var(--ytd-rich-grid-item-margin) - 0.01px);
  254. margin-bottom: 24px;
  255. }
  256.  
  257. ytd-search ytd-movie-renderer {
  258. margin-left: calc(var(--ytd-rich-grid-item-margin) / 2);
  259. margin-right: calc(var(--ytd-rich-grid-item-margin) / 2);
  260. width: calc(200% / var(--videos-per-row) - var(--ytd-rich-grid-item-margin) - 0.01px);
  261. margin-bottom: 24px;
  262. }
  263.  
  264. ytd-search yt-did-you-mean-renderer,
  265. ytd-search yt-showing-results-for-renderer,
  266. ytd-search ytd-thumbnail.ytd-video-renderer,
  267. ytd-search ytd-playlist-thumbnail.ytd-radio-renderer,
  268. ytd-search ytd-playlist-thumbnail.ytd-playlist-renderer,
  269. ytd-search ytd-playlist-thumbnail.ytd-show-renderer {
  270. min-width: 100% !important;
  271. }
  272.  
  273. ytd-search .thumbnail-container.ytd-movie-renderer {
  274. min-width: 0 !important;
  275. }
  276.  
  277. ytd-search ytd-item-section-renderer[top-spacing-zero]:first-child #contents.ytd-item-section-renderer .ytd-item-section-renderer:first-child:not(yt-did-you-mean-renderer):not(yt-showing-results-for-renderer) {
  278. margin-top: 16px;
  279. }
  280.  
  281. ytd-search #dismissible.ytd-video-renderer,
  282. ytd-search ytd-radio-renderer,
  283. ytd-search ytd-playlist-renderer,
  284. ytd-search #content-section.ytd-channel-renderer,
  285. ytd-search #info-section.ytd-channel-renderer,
  286. ytd-search ytd-show-renderer {
  287. flex-direction: column;
  288. }
  289.  
  290. ytd-search .ytd-channel-renderer {
  291. align-self: center;
  292. text-align: center;
  293. }
  294.  
  295. ytd-search #video-title:is(.ytd-video-renderer, .ytd-radio-renderer, .ytd-playlist-renderer, .ytd-show-renderer, .ytd-movie-renderer),
  296. ytd-search #channel-title.ytd-channel-renderer {
  297. font-size: 1.6rem;
  298. line-height: 2.2rem;
  299. font-weight: 500;
  300. }
  301.  
  302. ytd-search #channel-name.ytd-video-renderer,
  303. ytd-search ytd-video-meta-block:not([rich-meta]) .ytd-video-meta-block:is(#metadata-line, #byline-container),
  304. ytd-search #metadata.ytd-channel-renderer,
  305. ytd-search #view-more.ytd-playlist-renderer {
  306. font-size: 1.4rem;
  307. line-height: 2rem;
  308. max-height: 2rem;
  309. }
  310.  
  311. ytd-search h3:is(.ytd-video-renderer, .ytd-radio-renderer, .ytd-playlist-renderer, .ytd-show-renderer),
  312. ytd-search #channel-title.ytd-channel-renderer {
  313. margin: 12px 0 4px 0 !important;
  314. }
  315.  
  316. ytd-search #content.ytd-playlist-renderer,
  317. ytd-search #content.ytd-radio-renderer,
  318. ytd-search #info-section.ytd-channel-renderer {
  319. flex-basis: 100%;
  320. }
  321.  
  322. ytd-search ytd-playlist-thumbnail.ytd-show-renderer {
  323. flex: 0 !important;
  324. }
  325.  
  326. ytd-search #info.ytd-channel-renderer {
  327. padding: 0 0px 16px 0;
  328. }
  329.  
  330. ytd-search #avatar-section.ytd-channel-renderer,
  331. ytd-search ytd-playlist-thumbnail.ytd-playlist-renderer {
  332. margin: 0 !important;
  333. }
  334.  
  335. ytd-search .ytd-channel-renderer:is(#buttons, #purchase-button, #subscribe-button) {
  336. padding: 0 !important;
  337. }
  338.  
  339. ytd-search .text-wrapper.ytd-video-renderer {
  340. position: relative;
  341. width: 100%;
  342. }
  343.  
  344. ytd-search #channel-thumbnail.ytd-video-renderer {
  345. position: absolute;
  346. top: 12px;
  347. }
  348.  
  349. ytd-search yt-img-shadow.ytd-video-renderer img.yt-img-shadow {
  350. width: 36px;
  351. height: 36px;
  352. }
  353.  
  354. ytd-search #meta.ytd-video-renderer {
  355. display: contents;
  356. }
  357.  
  358. ytd-search ytd-video-meta-block.ytd-video-renderer,
  359. ytd-search #buttons.ytd-video-renderer,
  360. ytd-search #badges.ytd-video-renderer {
  361. order: 2;
  362. }
  363.  
  364. ytd-search ytd-video-renderer[use-search-ui] #channel-info.ytd-video-renderer {
  365. padding: 0;
  366. }
  367.  
  368. ytd-search #badges.ytd-video-renderer {
  369. margin: 4px 0 0 0;
  370. }
  371.  
  372. body[dir=ltr] ytd-search ytd-menu-renderer.ytd-video-renderer {
  373. position: absolute;
  374. right: -12px;
  375. margin: 4px 0 0 0;
  376. }
  377.  
  378. body[dir=ltr] ytd-search #title-wrapper.ytd-video-renderer {
  379. padding-right: 24px;
  380. }
  381.  
  382. body[dir=ltr] ytd-search .ytd-video-renderer:is(#title-wrapper, #channel-name, #badges, #buttons),
  383. body[dir=ltr] ytd-search ytd-video-meta-block.ytd-video-renderer {
  384. padding-left: 48px;
  385. }
  386.  
  387. body[dir=rtl] ytd-search ytd-menu-renderer.ytd-video-renderer {
  388. position: absolute;
  389. left: -12px;
  390. margin: 4px 0 0 0;
  391. }
  392.  
  393. body[dir=rtl] ytd-search #title-wrapper.ytd-video-renderer {
  394. padding-left: 24px;
  395. }
  396.  
  397. body[dir=rtl] ytd-search .ytd-video-renderer:is(#title-wrapper, #channel-name, #badges, #buttons),
  398. body[dir=rtl] ytd-search ytd-video-meta-block.ytd-video-renderer {
  399. padding-right: 48px;
  400. }
  401.  
  402. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) #description-text.ytd-video-renderer,
  403. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) #list.ytd-playlist-renderer {
  404. display: none;
  405. }
  406.  
  407. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) #metadata.ytd-video-meta-block,
  408. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) #view-more.ytd-playlist-renderer {
  409. display: block;
  410. }
  411.  
  412. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) ytd-two-column-browse-results-renderer {
  413. width: calc(100% - 32px) !important;
  414. max-width: calc(var(--videos-per-row) * (var(--ytd-rich-grid-item-max-width) + var(--ytd-rich-grid-item-margin)));
  415. }
  416.  
  417. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) #contents.ytd-item-section-renderer,
  418. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) ytd-item-section-renderer.ytd-section-list-renderer {
  419. display: contents;
  420. }
  421.  
  422. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) #contents.ytd-section-list-renderer {
  423. display: flex;
  424. flex-wrap: wrap;
  425. }
  426.  
  427. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) ytd-video-renderer,
  428. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) ytd-playlist-renderer,
  429. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) ytd-show-renderer {
  430. width: calc(100% / var(--videos-per-row) - var(--ytd-rich-grid-item-margin) - 0.01px);
  431. margin-left: calc(var(--ytd-rich-grid-item-margin) / 2);
  432. margin-right: calc(var(--ytd-rich-grid-item-margin) / 2);
  433. margin-bottom: 24px;
  434. }
  435.  
  436. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) ytd-thumbnail.ytd-video-renderer,
  437. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) ytd-playlist-thumbnail.ytd-playlist-renderer,
  438. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) ytd-playlist-thumbnail.ytd-show-renderer {
  439. width: 100%;
  440. height: 100%;
  441. flex: 0;
  442. }
  443.  
  444. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) ytd-thumbnail.ytd-video-renderer:before,
  445. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) ytd-playlist-thumbnail.ytd-playlist-renderer:before,
  446. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) ytd-playlist-thumbnail.ytd-show-renderer:before {
  447. display: block;
  448. content: "";
  449. padding-top: 56.11%;
  450. }
  451.  
  452. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) #dismissible.ytd-video-renderer,
  453. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) ytd-playlist-renderer,
  454. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) ytd-show-renderer {
  455. flex-direction: column;
  456. }
  457.  
  458. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) #video-title:is(.ytd-video-renderer, .ytd-playlist-renderer, .ytd-show-renderer) {
  459. font-size: 1.6rem;
  460. line-height: 2.2rem;
  461. font-weight: 500;
  462. }
  463.  
  464. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) ytd-video-meta-block:not([rich-meta]) .ytd-video-meta-block:is(#byline-container, #metadata-line),
  465. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) #view-more.ytd-playlist-renderer {
  466. font-size: 1.4rem;
  467. line-height: 2rem;
  468. max-height: 2rem;
  469. }
  470.  
  471. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) .title-and-badge.ytd-video-renderer,
  472. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) h3:is(.ytd-playlist-renderer, .ytd-show-renderer) {
  473. margin: 12px 0 4px 0;
  474. }
  475.  
  476. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) #badges.ytd-video-renderer {
  477. margin: 4px 0 0 0;
  478. }
  479.  
  480. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) #content.ytd-playlist-renderer {
  481. flex-basis: 100%;
  482. }
  483.  
  484. ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) .text-wrapper.ytd-video-renderer {
  485. max-width: 100%;
  486. }
  487.  
  488. body[dir=ltr] ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) ytd-menu-renderer.ytd-video-renderer {
  489. position: absolute;
  490. right: -12px;
  491. margin-top: 4px;
  492. }
  493.  
  494. body[dir=ltr] ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) #meta.ytd-video-renderer {
  495. padding-right: 24px;
  496. }
  497.  
  498. body[dir=rtl] ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) ytd-menu-renderer.ytd-video-renderer {
  499. position: absolute;
  500. left: -12px;
  501. margin-top: 4px;
  502. }
  503.  
  504. body[dir=rtl] ytd-browse[page-subtype=channels][has-c4-tabbed-header-renderer]:has(.yt-tab-group-shape-wiz__slider[style*="width: 0px;"]) #meta.ytd-video-renderer {
  505. padding-left: 24px;
  506. }
  507. </style>`);