Shorts Auto Scroll

Auto-scroll to next YouTube Short.

  1. // ==UserScript==
  2. // @name Shorts Auto Scroll
  3. // @namespace http://tampermonkey.net/
  4. // @version 2025-07-10
  5. // @description Auto-scroll to next YouTube Short.
  6. // @author vincent bruneau
  7. // @match *://www.youtube.com/*
  8. // @grant none
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. (function () {
  13. 'use strict';
  14.  
  15. let currentVideo = null;
  16. let currentSrc = null;
  17.  
  18. function log(...args) {
  19. console.log('[Shorts Auto Scroll]', ...args);
  20. }
  21.  
  22. function isShortsPage() {
  23. return location.pathname.startsWith("/shorts");
  24. }
  25.  
  26. function getVideo() {
  27. return document.querySelector("video.video-stream.html5-main-video");
  28. }
  29.  
  30. function getNextButton() {
  31. return document.querySelector('#navigation-button-down button');
  32. }
  33.  
  34. function scrollToNext() {
  35. const btn = getNextButton();
  36. if (btn && btn.getAttribute("aria-disabled") !== "true") {
  37. log("Scrolling to next Short");
  38. btn.click();
  39. } else {
  40. log("Next button not found or disabled");
  41. }
  42. }
  43.  
  44. function bindToVideo(video) {
  45. if (!video || video.dataset.autoScrollBound === "true") return;
  46.  
  47. video.dataset.autoScrollBound = "true";
  48. video.dataset.autoScrollTriggered = "false";
  49.  
  50. log("Bound to video element:", video.src);
  51.  
  52. video.addEventListener("timeupdate", function () {
  53. const duration = video.duration;
  54. const current = video.currentTime;
  55. if (
  56. duration &&
  57. current / duration > 0.98 &&
  58. video.dataset.autoScrollTriggered !== "true"
  59. ) {
  60. video.dataset.autoScrollTriggered = "true";
  61. scrollToNext();
  62. }
  63. });
  64.  
  65. video.addEventListener("play", function () {
  66. if (video.dataset.autoScrollTriggered === "true") {
  67. log("Video played again — resetting scroll trigger");
  68. video.dataset.autoScrollTriggered = "false";
  69. }
  70. });
  71. }
  72.  
  73. function detectAndBindVideo() {
  74. if (!isShortsPage()) return;
  75.  
  76. const video = getVideo();
  77. if (!video) return;
  78.  
  79. const srcChanged = video.src !== currentSrc;
  80. if (video !== currentVideo || srcChanged) {
  81. currentVideo = video;
  82. currentSrc = video.src;
  83. bindToVideo(video);
  84. }
  85. }
  86.  
  87. function init() {
  88. log("Shorts Auto Scroll initialized");
  89.  
  90. setInterval(detectAndBindVideo, 1000);
  91.  
  92. window.addEventListener("yt-navigate-finish", function () {
  93. currentVideo = null;
  94. currentSrc = null;
  95. });
  96. }
  97.  
  98. init();
  99. })();

QingJ © 2025

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