YouTube View Most Popular and Newest Uploader Videos (2018+)

See the user's most 'Popular' and 'Newest' video pages in a sliding-dropdown preview without even having to leave the video page.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name               YouTube View Most Popular and Newest Uploader Videos (2018+)
// @namespace          YVMUV
// @version            23.1
// @description        See the user's most 'Popular' and 'Newest' video pages in a sliding-dropdown preview without even having to leave the video page. 
// @run-at             document-start
// @include            *://www.youtube.com/watch?v=*
// @include            *://www.youtube.com/channel/*/videos?*
// @exclude            *://www.youtube.com/tv*
// @exclude            *://www.youtube.com/embed/*
// @exclude            *://www.youtube.com/live_chat*
// @exclude            *://www.youtube.com/feed/subscriptions?flowx=2*
// @require            http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// @require            https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js
// @resource  primefix https://greasyfork.org/scripts/370052-youtube-old-site-design/code/Youtube%20Old%20Site%20Design.user.js
// @resource  primefixb https://greasyfork.org/scripts/32906-get-me-old-youtube/code/Get%20me%20Old%20Youtube.user.js
// @resource spfremove https://greasyfork.org/scripts/16935-disable-spf-youtube/code/Disable%20SPF%20Youtube.user.js
// @grant              GM_getResourceText
// @grant              GM_getValue
// @grant              GM_setValue
// @grant              GM_addStyle
// @author             drhouse
// @contributor        Artain [Get me Old Youtube]
// ==/UserScript==
this.$ = this.jQuery = jQuery.noConflict(true);

$(document).ready(function () {

    eval(GM_getResourceText("spfremove"));
    //eval(GM_getResourceText("primefix"));
    eval(GM_getResourceText("primefixb"));


    if(window.location != window.parent.location){
        $('#masthead-positioner').remove();
        $('div.branded-page-v2-top-row').remove();
        $('#appbar-guide-menu').remove();
        $('div#masthead-positioner-height-offset').remove();

        var links = document.getElementById('content').getElementsByTagName('a');

        for(var i=0 ; i<links.length ; i++){
            links[i].setAttribute('target', '_top');
        }
    }
    else {
        //not in frame
    }

    var dest = '#watch7-user-header > div > a';
    var channel = $(dest).attr('href');
    var link = 'https://www.youtube.com' + channel + '/videos?view=0&sort=p&flow=grid';

    var link2 = "'" + link + "'";
    var dest2 = $('#watch8-secondary-actions > div:nth-child(3)');

    var linkdd = 'https://www.youtube.com' + channel + '/videos?view=0&sort=dd&flow=grid';
    var linkdd2 = "'" + linkdd + "'";
    $('<button class="yt-uix-button yt-uix-button-size-default yt-uix-button-has-icon  yt-uix-tooltip addto-button" type="button" title="More actions" aria-pressed="false" id="popular" role="button" aria-haspopup="false" data-tooltip-text="Popular videos" aria-labelledby="yt-uix-tooltip93-arialabel"><span class="yt-uix-button-content"><a href="' + link + '">&nbsp;Most popular videos</a></span></button>').insertAfter(dest2).css('color', '#666')
    $('<button class="yt-uix-button yt-uix-button-size-default yt-uix-button-has-icon  yt-uix-tooltip addto-button" type="button" title="More actions" aria-pressed="false" id="newest" role="button" aria-haspopup="false" data-tooltip-text="Newest videos" aria-labelledby="yt-uix-tooltip93-arialabel"><span class="yt-uix-button-content"><a href="' + linkdd + '">&nbsp;Newest videos</a></span></button>').insertAfter(dest2).css('color', '#666');

    document.getElementById("popular").addEventListener("click", function(event){
        event.preventDefault()
    });
    document.getElementById("newest").addEventListener("click", function(event){
        event.preventDefault()
    });

    $("head").append (
        '<link '
        + 'href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" '
        + 'rel="stylesheet" type="text/css">'
    );

    $("head").append (
        '<link '
        + 'href="//unity.alwaysdata.net/test/push.css" '
        + 'rel="stylesheet" type="text/css">'
    );

    +function ($) {

        // PUSH PLUGIN CLASS DEFINITION
        // ============================

        // variable used to indetify inilitizing of the Push plugin
        var pushAPI = '[data-toggle="push"]' // Default value is '[data-toggle="push"]'

        // Main function to get off canvas element and options
        var Push = function (element, options) {
            this.element = element
            this.options = options
        }

        // Current version
        Push.VERSION = '1.0'

        // Transition duration
        Push.TRANSITION_DURATION = 150

        // Default PUSH plugin settings
        Push.DEFAULTS = {

            // Easing method, used for the element when it (opens / closes).
            easing			: 'cubic-bezier(.2,.7,.5,1)', // Default value is 'cubic-bezier(.2,.7,.5,1)'

            // Duration for an element to (open / close)
            duration		: 1500, // Default value is 300

            // Delay before the element (opens / closes)
            delay			: 1000, // Default value is 0

            // Distance an element (opens / closes)
            distance		: 250, // Default value is 250

            // Enable or disable Anti Scrolling (outside the element)
            antiScroll		: false, // Default value is true

            // Enable or disable keyboard closing (escape key to close the element)
            keyboard		: true, // Default value is true

            // Enable or disable a modal like overlay (outside the element).
            overlay			: false, // Default value is true

            // Canvas element (outside togglable sidebars).
            canvas			: '#body-container' // Default value is '#wrapper'
        }

        // Function to check if the canvas element is open
        Push.prototype.isOpen = function () {

            // Return if the canvas element has the isOpen class
            return $(this.options.canvas).hasClass('isOpen')
        }

        // Function to toggle (open or close)
        Push.prototype.toggle = function () {

            // If canvas is already open
            if (this.isOpen()) {
                this.close() // close canvas and hide element
            }

            // If canvas isn't open
            else {
                this.open() // open canvas and reveal element
            }
        }

        // Function to find all fixed elements
        Push.prototype.findFixed = function () {

            // Filter all elements with position: fixed
            var fixed_elements = $('*').filter(function() {
                return $(this).css("position") === 'fixed';
            }).not(this.element) // Skip sidebar element

            // Return all fixed elements, except the sidebar element
            return fixed_elements
        }

        // Function to disable scrolling outside an element
        Push.prototype.disableScrolling = function () {

            // Add overflow hidden to body, to prevent scrolling
            $(document.body).css('overflow', 'hidden')

            // On touch devices, overflow: hidden, is ignored. So we specefiy another prevention for touch devices.
            if ('ontouchstart' in document.documentElement) {
                $(document).on('touchmove.bs.push', function (e) {
                    e.preventDefault()
                })
            }
        }

        // Function to enable scrolling outside an element
        Push.prototype.enableScrolling = function () {

            // Override the previously added overflow hiddien. To active normal scroll behaviour
            $(document.body).css('overflow', 'auto')

            // Turn off the anti touch functionality for touch devices.
            if ('ontouchstart' in document.documentElement) {
                $(document).off('touchmove.bs.push')
            }
        }

        // Function to disable key press to close an element
        Push.prototype.disableKeyboard = function () {

            // Turn off the previously added keybind to close an open sidebar
            $(window).off('keydown.bs.push')
        }

        // Function to enable key press to close an element
        Push.prototype.enableKeyboard = function () {

            // Add functionality to close a sidebar, with a specefied keybind
            $(window).one('keydown.bs.push', $.proxy(function (e) {
                e.which == 13 && this.close() || e.which == 32 && this.close() // default value is: 27 (ESC key)
            }, this))
        }

        // Function to remove an overlay outside the element
        Push.prototype.disableOverlay = function () {

            // Prepare the overlay variable
            var $overlay = $(".modal-backdrop");

            // Remove previously added overlay effect, from the canvas element
            $overlay.remove();
        }

        // Function to add an overlay outside the element
        Push.prototype.enableOverlay = function () {

            // Prepare the overlay variable
            var $overlay = $('<div class="modal-backdrop in"></div>');

            // Add an overlay effect to the canvas element
            $overlay.appendTo(this.options.canvas);
        }

        // Function to open an element
        Push.prototype.open = function () {

            // Set the (that) variable, for easy access, and to avoid conflict.
            var that = this

            // Get all fixed elements, except the sidebar elements
            var fixedElements = this.findFixed()

            // If options is set to disable scrolling, disable it on opening
            if (this.options.antiScroll) this.disableScrolling()

            // If options is set to enable keyboard, enable it on opening
            if (this.options.keyboard) this.enableKeyboard()

            // If options is set to activate overlay, activate it on opening
            if (this.options.overlay) this.enableOverlay()

            // Reveal the toggled sidebar
            $(this.element).removeClass('hidden')

            // Open the canvas elemen
            $(this.options.canvas)
                .on('click.bs.push', $.proxy(this.close, this)) // If the user clicks on the canvas element, call the close functionality.
                .trigger('open.bs.push') // Trigger the open sequence
                .addClass('isOpen') // adds the isOpen class, to identify that the canvas is open

            // If browser doesn't support CSS3 transitions & translations
            if (!$.support.transition) {

                // Move all specefied fixed elements, when canvas is open
                fixedElements
                    .css({
                    'left': this.options.distance + 'px',
                    'position': 'relative'
                })

                // Move the actual canvas
                $(this.options.canvas)
                    .css({
                    'left': this.options.distance + 'px',
                    'position': 'relative'
                })
                    .trigger('opened.bs.push') // Indicate that the opening sequence is complete
                return
            }

            // Prepare the CSS3 transitioning of the all fixed elements, except for the sidebars
            fixedElements
                .css({
                '-webkit-transition': '-webkit-transform ' + this.options.duration + 'ms ' + this.options.easing,
                '-ms-transition': '-ms-transform ' + this.options.duration + 'ms ' + this.options.easing,
                'transition': 'transform ' + this.options.duration + 'ms ' + this.options.easing
            })

            // Prepare the CSS3 transitioning of the canvas element
            $(this.options.canvas)
                .css({
                '-webkit-transition': '-webkit-transform ' + this.options.duration + 'ms ' + this.options.easing,
                '-ms-transition': '-ms-transform ' + this.options.duration + 'ms ' + this.options.easing,
                'transition': 'transform ' + this.options.duration + 'ms ' + this.options.easing
            })

            this.options.canvas.offsetWidth // Force reflow

            // Move all specefied fixed elements, when the canvas opening sequence is initilised
            fixedElements
                .css({
                '-webkit-transform': 'translateY(' + this.options.distance + 'px)',
                '-ms-transform': 'translateY(' + this.options.distance + 'px)',
                'transform': 'translateY(' + this.options.distance + 'px)'
            })

            // Move the actual canvas element, when the opening sequence is initialised
            $(this.options.canvas)
                .css({
                '-webkit-transform': 'translateY(' + this.options.distance + 'px)',
                '-ms-transform': 'translateY(' + this.options.distance + 'px)',
                'transform': 'translateY(' + this.options.distance + 'px)'
            })
                .one('bsTransitionEnd', function () {
                $(that.options.canvas).trigger('opened.bs.push') // Indicate that the opening sequence is complete
            })
                .emulateTransitionEnd(this.options.duration) // Emulate the ending prosedure of the canvas opening
        }

        // Function to close an element
        Push.prototype.close = function () {

            // Set the (that) variable, for easy access, and to avoid conflict.
            var that = this

            // Get all fixed elements, except the sidebar elements
            var fixedElements = this.findFixed()

            // If options is set to enable keyboard, disable it on closing
            if (this.options.keyboard) this.disableKeyboard()

            // If options is set to activate overlay, deactivate it on closing
            if (this.options.overlay) this.disableOverlay()

            // If options is set to disable scrolling, enable it on clsoing
            if (this.options.antiScroll) this.enableScrolling()

            // Function to finilize the closing prosedure
            function complete () {

                // Hide the toggled sidebar
                $(that.element).addClass('hidden')

                // Reset the CSS3 transitioning and translation, of the all fixed elements back to default.
                fixedElements
                    .css({
                    '-webkit-transition': '',
                    '-ms-transition': '',
                    'transition': '',
                    '-webkit-transform': '',
                    '-ms-transform': '',
                    'transform': ''
                })

                // Reset the CSS3 transitioning and translation, of the canvas element back to default.
                $(that.options.canvas)
                    .removeClass('isOpen') // remove the isOpen class, to identify that the canvas is closed
                    .css({
                    '-webkit-transition': '',
                    '-ms-transition': '',
                    'transition': '',
                    '-webkit-transform': '',
                    '-ms-transform': '',
                    'transform': ''
                })
                    .trigger('closed.bs.push') // Indicate that the closing sequence is complete
            }

            // If browser doesn't support CSS3 transitions & translations
            if (!$.support.transition) {

                // Move back all specefied fixed elements to default.
                fixedElements
                    .css({
                    'left': '',
                    'position': ''
                })

                // Move back the canvas element to default.
                $(this.options.canvas)
                    .trigger('close.bs.push') // Trigger the close sequence
                    .css({
                    'left': '',
                    'position': ''
                })
                    .off('click.bs.push') // Turn off the click indicator for the canvas element

                // Initilise the final closing functionality
                return complete()
            }

            // Remove the CSS3 trasform values for all fixed elements
            fixedElements
                .css({
                '-webkit-transform': 'none',
                '-ms-transform': 'none',
                'transform': 'none'
            })

            // Remove the CSS3 transform values for the canvas element
            $(this.options.canvas)
                .trigger('close.bs.push') // Trigger the close sequence
                .off('click.bs.push') // Turn off the click indicator for the canvas element
                .css({
                '-webkit-transform': 'none',
                '-ms-transform': 'none',
                'transform': 'none'
            })
                .one('bsTransitionEnd', complete) // // Initilize the complete function, to finilise the closing
                .emulateTransitionEnd(this.options.duration) // Emulate the ending prosedure of the canvas closing
        }

        // PUSH PLUGIN DEFINITION
        // ======================

        // Function to initlise the push Plugin
        function Plugin(option) {

            // Begin initilising of the push plugin, for every indicator clicked
            return this.each(function () {

                // Prepare a variable, containing the designated element
                var $this		= $(this)

                // Prepare a variable, containing the data-attributes
                var data		= $this.data('bs.push')

                // Prepare the plugin options
                var options		= $.extend(
                    {
                        // extentions...
                    },
                    Push.DEFAULTS, // Initilise default plugin values
                    $this.data(), // Get the extending options from the plugin indicator
                    typeof option == 'object' && option // Setup an object with the designated options
                )

                // If the push indicatore doesn't contain any data atributes. Use the default values
                if (!data) $this.data('bs.push', (data = new Push(this, options)))

                // If the push indicator has a data attribute, containing a string
                if (typeof option == 'string') data[option]() // Setup the option
            })
        }

        var old = $.fn.push

        $.fn.push				= Plugin
        $.fn.push.Constructor	= Push

        // PUSH AVOID CONFLICT
        // ====================

        $.fn.push.noConflict = function () {

            $.fn.push = old
            return this
        }


        // PUSH DATA-API
        // =============

        // When clicked on a push data API indicator, initilise the plugin
        $(document).on('click', pushAPI, function () {

            // Get all the data options
            var options = $(this).data()

            // Get the designated data-target (sidebar element)
            var $target = $(this.getAttribute('data-target'))

            // If no designated data-target is spcefied, use default value
            if (!$target.data('bs.push')) {
                $target.push(options) // Get all the other data options
            }

            // Toggle the designated data-target (sidebar	)
            $target.push('toggle')
        })
    }(jQuery);

    //----------------------------------------------------------------

    channel = $('#popular > span > a').attr('href');
    var channeln = $('#newest > span > a').attr('href');

    var channel2 = channel + '#browse-items-primary';
    var channel2n = channeln + '#browse-items-primary';

    var ifrm;
    ifrm = document.createElement("iframe");
    ifrm.setAttribute("src", channel2);
    ifrm.setAttribute("id", "ifrmz");
    ifrm.style.width = 1500+"px";
    ifrm.style.height = 548+"px";

    var ifrm2;
    ifrm2 = document.createElement("iframe");
    ifrm2.setAttribute("src", channel2n);
    ifrm2.setAttribute("id", "ifrmz2");
    ifrm2.style.width = 1500+"px";
    ifrm2.style.height = 548+"px";

    $('<nav class="push-sidebar hidden" id="sidebar-left"></nav>').insertBefore('#body-container');
    $('<nav class="push-sidebar hidden" id="sidebar-left2"></nav>').insertBefore('#body-container');
    $( "#body-container" ).wrap( '<section class="canvas" id="canvas"></section>' );

    function newload(){
        $('nav#sidebar-left').append(ifrm);
    }

    function newload2(){
        $('nav#sidebar-left2').append(ifrm2);
    }

    $( "#newest" ).attr({
        'class': "yt-uix-button yt-uix-button-size-default",
        'data-toggle': "push",
        'data-target': "#sidebar-left2",
        'data-distance': "500"
    });

    $( "#newest" ).click(function(e) {
        newload2();

    });

    $( "#popular" ).attr({
        'class': "yt-uix-button yt-uix-button-size-default",
        'data-toggle': "push",
        'data-target': "#sidebar-left",
        'data-distance': "500"
    });

    $( "#popular" ).click(function(e) {
        newload();
    });

});