Auto-scroll to next YouTube Short.
// ==UserScript==
// @name Shorts Auto Scroll
// @namespace http://tampermonkey.net/
// @version 2025-07-10
// @description Auto-scroll to next YouTube Short.
// @author vincent bruneau
// @match *://www.youtube.com/*
// @grant none
// @license MIT
// ==/UserScript==
(function () {
'use strict';
let currentVideo = null;
let currentSrc = null;
function log(...args) {
console.log('[Shorts Auto Scroll]', ...args);
}
function isShortsPage() {
return location.pathname.startsWith("/shorts");
}
function getVideo() {
return document.querySelector("video.video-stream.html5-main-video");
}
function getNextButton() {
return document.querySelector('#navigation-button-down button');
}
function scrollToNext() {
const btn = getNextButton();
if (btn && btn.getAttribute("aria-disabled") !== "true") {
log("Scrolling to next Short");
btn.click();
} else {
log("Next button not found or disabled");
}
}
function bindToVideo(video) {
if (!video || video.dataset.autoScrollBound === "true") return;
video.dataset.autoScrollBound = "true";
video.dataset.autoScrollTriggered = "false";
log("Bound to video element:", video.src);
video.addEventListener("timeupdate", function () {
const duration = video.duration;
const current = video.currentTime;
if (
duration &&
current / duration > 0.98 &&
video.dataset.autoScrollTriggered !== "true"
) {
video.dataset.autoScrollTriggered = "true";
scrollToNext();
}
});
video.addEventListener("play", function () {
if (video.dataset.autoScrollTriggered === "true") {
log("Video played again — resetting scroll trigger");
video.dataset.autoScrollTriggered = "false";
}
});
}
function detectAndBindVideo() {
if (!isShortsPage()) return;
const video = getVideo();
if (!video) return;
const srcChanged = video.src !== currentSrc;
if (video !== currentVideo || srcChanged) {
currentVideo = video;
currentSrc = video.src;
bindToVideo(video);
}
}
function init() {
log("Shorts Auto Scroll initialized");
setInterval(detectAndBindVideo, 1000);
window.addEventListener("yt-navigate-finish", function () {
currentVideo = null;
currentSrc = null;
});
}
init();
})();