Greasy Fork

Greasy Fork is available in English.

YouTube Focus Mode

Put YouTube in focus mode! Hides all unasked for content (recommendations, subscriptions, related, etc.) on the home and watch pages.

当前为 2019-10-15 提交的版本,查看 最新版本

// ==UserScript==
// @name         YouTube Focus Mode
// @namespace    http://tampermonkey.net/
// @version      1.0.1
// @description  Put YouTube in focus mode! Hides all unasked for content (recommendations, subscriptions, related, etc.) on the home and watch pages.
// @author       EmeraldSlash
// @match        *://*.youtube.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // css selectors and disable states for YouTube features
    const HOME_PAGE_FEED = ["ytd-section-list-renderer[page-subtype='home']", true];
    const HOME_PAGE_SEARCH_BAR = ["input#search", true];
    const WATCH_PAGE_RELATED = ["ytd-compact-video-renderer.ytd-watch-next-secondary-results-renderer:not([expansion='collapsed']).ytd-watch-next-secondary-results-renderer", true];
    const WATCH_PAGE_CONTINUATION = ["#continuations.style-scope.ytd-watch-next-secondary-results-renderer", true]; // the continuations element is what handles infinite scroll (loading new recommended videos) so we want to delete it

    // import library for detecting added elements
    // insertion-query v1.0.3 (2016-01-20)
    // license:MIT
    // Zbyszek Tenerowicz <[email protected]> (http://naugtur.pl/)
    var insertionQ=function(){"use strict";function a(a,b){var d,e="insQ_"+g++,f=function(a){(a.animationName===e||a[i]===e)&&(c(a.target)||b(a.target))};d=document.createElement("style"),d.innerHTML="@"+j+"keyframes "+e+" {  from {  outline: 1px solid transparent  } to {  outline: 0px solid transparent }  }\n"+a+" { animation-duration: 0.001s; animation-name: "+e+"; "+j+"animation-duration: 0.001s; "+j+"animation-name: "+e+";  } ",document.head.appendChild(d);var h=setTimeout(function(){document.addEventListener("animationstart",f,!1),document.addEventListener("MSAnimationStart",f,!1),document.addEventListener("webkitAnimationStart",f,!1)},n.timeout);return{destroy:function(){clearTimeout(h),d&&(document.head.removeChild(d),d=null),document.removeEventListener("animationstart",f),document.removeEventListener("MSAnimationStart",f),document.removeEventListener("webkitAnimationStart",f)}}}function b(a){a.QinsQ=!0}function c(a){return n.strictlyNew&&a.QinsQ===!0}function d(a){return c(a.parentNode)?a:d(a.parentNode)}function e(a){for(b(a),a=a.firstChild;a;a=a.nextSibling)void 0!==a&&1===a.nodeType&&e(a)}function f(f,g){var h=[],i=function(){var a;return function(){clearTimeout(a),a=setTimeout(function(){h.forEach(e),g(h),h=[]},10)}}();return a(f,function(a){if(!c(a)){b(a);var e=d(a);h.indexOf(e)<0&&h.push(e),i()}})}var g=100,h=!1,i="animationName",j="",k="Webkit Moz O ms Khtml".split(" "),l="",m=document.createElement("div"),n={strictlyNew:!0,timeout:20};if(m.style.animationName&&(h=!0),h===!1)for(var o=0;o<k.length;o++)if(void 0!==m.style[k[o]+"AnimationName"]){l=k[o],i=l+"AnimationName",j="-"+l.toLowerCase()+"-",h=!0;break}var p=function(b){return h&&b.match(/[^{}]/)?(n.strictlyNew&&e(document.body),{every:function(c){return a(b,c)},summary:function(a){return f(b,a)}}):!1};return p.config=function(a){for(var b in a)a.hasOwnProperty(b)&&(n[b]=a[b])},p}();

    // update function that gets called everytime a new page loads
    // mostly redundant because of insertionQ? only relevant on fresh page loads & for search bar focusing
    function update() {
        // remove homepage feed
        if (HOME_PAGE_FEED[1]) {
            let result = document.querySelectorAll(HOME_PAGE_FEED[0]);
            if (result.length > 0) {
                result[0].remove();

                // focus search bar if homepage feed was removed
                if (HOME_PAGE_SEARCH_BAR[1]) {
                    let search = document.querySelector(HOME_PAGE_SEARCH_BAR[0]);
                    if (search) {
                        search.focus();
                    }
                }
            }
        }

        // remove related section on watch page
        if (WATCH_PAGE_RELATED[1]) {
            let result = document.querySelectorAll(WATCH_PAGE_RELATED[1]);
            if (WATCH_PAGE_CONTINUATION[1]) {
                result = [...result, ...document.querySelectorAll(WATCH_PAGE_CONTINUATION[0])];
            }
            if (result.length > 0) {
                for (let i = 0; i < result.length; i++) {
                    result[i].remove()
                }
            }
        }
    }

    // page change and element added listeners
    document.addEventListener('yt-navigate-finish', update);

    // remove related section on watch page and infinite scroll element
    if (WATCH_PAGE_RELATED[1]) {
        insertionQ(WATCH_PAGE_RELATED[0]).every(function(element) {
            element.remove()
        })
        insertionQ(WATCH_PAGE_CONTINUATION[0]).every(function(element) {
            element.remove()
        })
    }

    // call initial update
    update()
})();