auto show more for YouTube

this plugin will press "show more" button when it displayed by scrolling.

目前為 2019-10-09 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name           auto show more for YouTube
// @name:ja        YouTubeの「もっと見る」ボタンを自動で押す
// @description    this plugin will press "show more" button when it displayed by scrolling.
// @description:ja YouTube.comの「もっと見る」ボタンが、スクロールによって画面に表示された瞬間、自動で押されます。
// @namespace      https://twitter.com/sititou70
// @license        MIT
// @include        /https*:\/\/www\.youtube\.com\/.*/
// @version        2.2.1
// @grant          none
// ==/UserScript==

//settings
let scroll_event_interval = 200;
const adjust_scroll_px = 0;
const target_infos = [
    {
        name: "comment reply",
        selector: "ytd-comment-replies-renderer ytd-button-renderer#more-replies paper-button#button",
        click_times: 1,
    },
    {
        name: "more comment replies",
        selector: "yt-next-continuation.ytd-comment-replies-renderer > paper-button",
        click_times: Infinity,
    },
    {
        name: "comment read more",
        selector: "ytd-expander.ytd-comment-renderer > paper-button#more",
        click_times: 1,
    },
    {
        name: "related videos",
        selector: "yt-next-continuation.ytd-watch-next-secondary-results-renderer > paper-button",
        click_times: 1,
    },
    {
        name: "video info",
        selector: "ytd-expander.style-scope.ytd-video-secondary-info-renderer > paper-button#more",
        click_times: 1,
    },
];

//global variables
let button_caches = {};
const initButtonCaches = () =>
    target_infos.forEach(x => {
        button_caches[x.name] = [];
    });
initButtonCaches();

//utils
const user_agent = window.navigator.userAgent.toLowerCase();
const fireClickEvent = (elem) => {
    if( user_agent.match(/(msie|MSIE)/) || user_agent.match(/(T|t)rident/) ) {
        elem.fireEvent("onclick");
    } else {
        const event = document.createEvent("MouseEvents");
        event.initEvent("click", true, true);
        elem.dispatchEvent(event);
    }
};

//events
const scrollHandler = () =>
    target_infos.forEach(target_info => {
        document.querySelectorAll(target_info.selector).forEach(elem => {
            let button_cahce = button_caches[target_info.name].find(y => y.elem === elem);

            if(button_cahce === undefined){
                button_cahce = {
                    elem,
                    click_times: 0,
                };
                button_caches[target_info.name].push(button_cahce);
            }

            const click_times_flg = button_cahce.click_times < target_info.click_times;
            const button_position_flg = elem.getBoundingClientRect().y - window.innerHeight + adjust_scroll_px < 0;
            if(click_times_flg && button_position_flg){
                fireClickEvent(elem);
                button_cahce.click_times++;

                //highlight clicked button for debugging
                //x.style.border = "1px solid #f00";
            }
        });
    });

let waiting_for_scroll_event_interval = false;
document.addEventListener("scroll", () => {
    if(waiting_for_scroll_event_interval)return;
    waiting_for_scroll_event_interval = true;
    setTimeout(() => {
        waiting_for_scroll_event_interval = false;
    }, scroll_event_interval);

    scrollHandler();
});

document.addEventListener("click", function(e){
    let target = e.target;
    while(target !== document.body){
        if(target.tagName === "A"){
            initButtonCaches();
            return;
        }
        target = target.parentElement;
    }
});