Youtube scroll lock time link in picture-in-picture

When using Picture-in-Picture (PiP), don't scroll to the top of the page when clicking on a link that displays the time of the video.

当前为 2022-09-18 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name           Youtube scroll lock time link in picture-in-picture
// @name:ja        YouTubeでピクチャーインピクチャー使用時、時間リンクでページトップ遷移防止
// @namespace      https://github.com/ziopuzzle/
// @version        1.1
// @description    When using Picture-in-Picture (PiP), don't scroll to the top of the page when clicking on a link that displays the time of the video.
// @description:ja 動画をポップアウトしていても、動画時間リンクでページトップに戻ってしまう現象を解決します。
// @author         ziopuzzle
// @match          https://www.youtube.com/*
// @grant          none
// @license        MIT
// ==/UserScript==

(function() {
    'use strict';

    const SEND_LOG = false;

    function loadPage(fn) {
        // Fook page change(Youtube is single page application)
        // Note: https://stackoverflow.com/questions/24297929/
        document.addEventListener('yt-navigate-finish', fn, false);
    }
    function timeLinkClick() {
        // If using Picture-in-Picture
        if (document.pictureInPictureElement) {
            // After scrolling back to the top by Youtube, restore the scroll position.
            const scroll = document.documentElement.scrollTop;
            document.addEventListener('yt-autonav-pause-scroll', (event) => {
                sendLog('scroll to ' + scroll.toString());
                document.documentElement.scrollTop = scroll;
            }, {once : true});
        }
    }
    function sendLog(s) {
        if (SEND_LOG) {
            console.log('[PIP_SCROLL_LOCK] ' + s);
        }
    }
    // Disabled script if youtube is embedded
    if (window.top === window.self) {
        loadPage(() => {
            sendLog('page loaded');
            // For check playback time link
            const videoID = new URL(window.location.href).searchParams.get('v');
            sendLog('VideoID: ' + videoID);
            // Observe comment elements to be added
            const observer = new MutationObserver((mutations) => {
                mutations.forEach((mutation) => { mutation.addedNodes.forEach((element) => {
                    if (element.tagName == 'YTD-COMMENT-THREAD-RENDERER') {
                        // Extract links where the time written.
                        element.querySelectorAll('a[href*="t="][href*="v=' + videoID + '"]').forEach((element) => {
                            sendLog('playback link found');
                            // Make event when a link is clicked
                            element.addEventListener('click', timeLinkClick, false);
                        });
                    }
                });});
            })
            observer.observe(document.getElementById('content'), { childList: true, subtree: true });
            sendLog('observer connect');
            document.addEventListener('yt-navigate-start', () => {
                observer.disconnect();
                sendLog('observer disconnect');
            }, {once : true});
        });
    }

})();