Youtube - Fix channel links in sidebar recommendations

Fixes the channel links for the "Up next" and recommended videos below it on youtube.

目前为 2024-01-16 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Youtube - Fix channel links in sidebar recommendations
  3. // @namespace 1N07
  4. // @version 0.6.3
  5. // @description Fixes the channel links for the "Up next" and recommended videos below it on youtube.
  6. // @author 1N07
  7. // @license unlicense
  8. // @icon https://www.google.com/s2/favicons?domain=youtube.com
  9. // @match https://www.youtube.com/*
  10. // @require https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
  11. // @grant GM_registerMenuCommand
  12. // @grant GM_unregisterMenuCommand
  13. // @grant GM_getValue
  14. // @grant GM_setValue
  15. // @grant GM_addStyle
  16. // @compatible firefox Compatible with: Tampermonkey, Violentmonkey
  17. // @compatible firefox Not compatible with: Greasemonkey, FireMonkey
  18. // @compatible chrome Latest version untested, but likely works with at least Tampermonkey
  19. // @compatible opera Latest version untested, but likely works with at least Tampermonkey
  20. // @compatible edge Latest version untested, but likely works with at least Tampermonkey
  21. // @compatible safari Latest version untested, but likely works with at least Tampermonkey
  22. // ==/UserScript==
  23.  
  24. (function() {
  25. 'use strict';
  26.  
  27. var videoSectionOption;
  28. var videoSection = GM_getValue("videoSection", true);
  29. SetVidSecOption();
  30.  
  31. GM_addStyle(`
  32. ytd-compact-video-renderer .channel-link-blocker:hover ~ a #text.ytd-channel-name {
  33. text-decoration: underline;
  34. }
  35. .channel-link-blocker-parent
  36. {
  37. position: relative;
  38. }
  39. .channel-link-blocker
  40. {
  41. display: inline-block;
  42. position: absolute;
  43. width: 100%;
  44. height: 25px;
  45. background-color: rgba(255, 25, 25, 0);
  46. top: 32px;
  47. left: 0;
  48. z-index: 2019;
  49. }
  50. `);
  51.  
  52. setInterval(AddListeners, 200); //fairly stupid way to do this, but hey, it works so this is how I'm doing it for now... -> switch to mutationobserver?
  53.  
  54. function AddListeners() {
  55. // My big brain high IQ plan for preventing the video from opening, since seems whatever I do some click event is caught by youtube:
  56. // Adding invisible divs on top of channel links so I can handle the clicks however I want. :DD
  57. $(`ytd-compact-video-renderer .metadata.ytd-compact-video-renderer:not(.channel-link-blocker-parent) > a[href^='/watch'],
  58. ytd-compact-playlist-renderer .metadata.ytd-compact-playlist-renderer:not(.channel-link-blocker-parent) > a[href^='/watch']`
  59. ).each(function(){
  60. console.log("Adding link...");
  61. $(this).parent().addClass("channel-link-blocker-parent");
  62. $(this).parent().prepend(`<a class="channel-link-blocker" href="#"></a>`);
  63.  
  64. //get data source object from element. Newest source used by YT is .polymerController, but older sources that may still be in use if certain flags are in place include .inst or just the element itself
  65. const getVideoDataSource = o => o ? (o.polymerController || o.inst || o || 0) : (o || 0);
  66.  
  67. //no idea what the longBylineText.runs array can contain other than the object we want, so throwing a find method in there so that if there are other random objects in the array, we hopefully get the right one (also tons of optional chaining so that if something goes wrong we gracefully get falsy as the final value)
  68. const channelHandle = getVideoDataSource($(this).closest("ytd-compact-video-renderer")?.[0])?.data?.longBylineText?.runs?.find(el => el.navigationEndpoint?.browseEndpoint?.canonicalBaseUrl?.startsWith("/@"))?.navigationEndpoint.browseEndpoint.canonicalBaseUrl;
  69.  
  70. if(channelHandle?.length) {
  71. $(this).parent().find(".channel-link-blocker").prop("href", channelHandle + (videoSection ? "/videos" : ""));
  72. } else {
  73. console.log("Failed to get channel url");
  74. $(this).parent().find(".channel-link-blocker").on("click", (e) => {
  75. e.preventDefault();
  76. e.stopPropagation();
  77. alert("'Youtube - Fix channel links in sidebar recommendations' failed to get the channel link for this video for some reason. If this happens consistently, please report it at greasyfork.");
  78. });
  79. }
  80.  
  81. //blocker position adjustment
  82. $(this).parent().find(".channel-link-blocker").prop("style", "top: " + $(this).parent().find("a[href^='/watch']:first > h3").height() + "px;");
  83. //above adjustment appears to randomly fail. Attempted fix by delaying adjustment as perhaps the height hasn't been computed yet?
  84. //$(this) doesn't work from inside the seTimeout, so storing it here
  85. const storedThis = $(this);
  86. setTimeout(function() { storedThis.parent().find(".channel-link-blocker").prop("style", "top: " + storedThis.parent().find("a[href^='/watch']:first > h3").height() + "px;"); }, 1000);
  87. });
  88. }
  89.  
  90. function SetVidSecOption() {
  91. GM_unregisterMenuCommand(videoSectionOption);
  92. videoSectionOption = GM_registerMenuCommand("Fix channel links- videos section (" + (videoSection ? "yes" : "no") + ") -click to change-", function(){
  93. videoSection = !videoSection;
  94. GM_setValue("videoSection", videoSection);
  95. SetVidSecOption();
  96. });
  97. }
  98. })();

QingJ © 2025

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