您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Puts the video title in the location bar of all YouTube video pages. Now with extra features add scrollbars, animate thumbnails, reduce font sizes and un-float the header.
当前为
- // ==UserScript==
- // @name Title Youtube Locations
- // @namespace TYTLs
- // @description Puts the video title in the location bar of all YouTube video pages. Now with extra features add scrollbars, animate thumbnails, reduce font sizes and un-float the header.
- // @version 1.1.8
- // @downstreamURL http://userscripts.org/scripts/source/87416.user.js
- // @include http://*.youtube.*/*
- // @include http://youtube.*/*
- // @include https://*.youtube.*/*
- // @include https://youtube.*/*
- //// YouTube thumbnails almost certainly appear if you do a video search:
- // @include https://www.google.co.uk/search?*&tbm=vid&*
- //// YouTube thumbnails occasionally appear in normal Google search results:
- // @include https://www.google.co.uk/search*
- // @grant GM_addStyle
- // @grant GM_log
- // ==/UserScript==
- // TODO: In case for some reason YouTube or another script redirects us to
- // another URL which has lost the title param we added, we will re-run forever.
- // To avoid this we should have a fallback. E.g. if the title we want to set
- // is the same as the last one we did set (via GM_set/getValue) then do not try
- // again.
- // This has never happened so far. :)
- // If you are interested in YouTube images:
- // Thumbnails url looks like http://img.youtube.com/vi/8aYQ_wjmriQ/2.jpg
- // Youtube generates 4 thumbnails: 0.jpg at 320x240, and 1.jpg, 2.jpg, 3.jpg
- // Also large: hqdefault.jpg (480x360) and sometimes but not always hq1.jpg, hq2.jpg, hq3.jpg
- var addTitleToLocation = true;
- var reduceFontSizes = true;
- var addScrollbars = true;
- var scrollDownToVideo = false; // YouTube's header ("masthead") is now floating. Setting this true will un-float it, then scroll down to hide it. But scrolling containers should then be enlarged.
- var animateThumbnails = true;
- var unfloatTheHeader = true;
- if (addTitleToLocation) {
- // NOTE: This code is deprecated, as I now use the userscripts URLs_Need_Titles
- setTimeout(function(){
- if (document.location.pathname == "/watch") {
- var title = document.title.replace(/ - YouTube$/,'')
- || null;
- if (title)
- title = title.replace(/ /g,'_').replace(/^[\r\n_]*/,'').replace(/[\r\n_]*$/,''); // "_"s paste better into IRC, since " "s become "%20"s which are hard to read. The second and third parts trim "_"s and newlines from the start and end of the string.
- if (title) {
- if (!document.location.hash) {
- document.location.replace(document.location.href + '#' + title); // Does not alter browser history
- // document.location.hash = title; // Crashes Chrome less often
- }
- }
- }
- },5000); // This is what really stops the crashing!
- }
- if (reduceFontSizes) {
- // == Reduce font size of thumbnail titles ==
- GM_addStyle(".yt-tile-default.video-list-item a .title, #watch-sidebar .video-list-item .title { font-size: 11px; line-height: 10px; }");
- // Defaults are font-size: 13px; and line-height: 15px; which show only two lines in my browser.
- }
- if (addScrollbars) {
- // == Scrollbars on comments and related vids, to keep the video in view. ==
- setTimeout(function(){
- // We could alternatively act on watch-panel but that includes the video navigation buttons!
- // BUG: Interferes with YouTube's lazy-loading of thumbnails for related video.
- if (document.location.href.indexOf("/all_comments?") >= 0) {
- return; // Leave the full comments page alone.
- }
- // The top of watch7-content has become very large, so put a scrollbar on the whole lot.
- var watchDiscussion = /* document.getElementById("watch-discussion") || */ document.getElementById("watch7-content");
- if (watchDiscussion) {
- var toSubtract = 464; // Small video screen
- //var toSubtract = 544; // Medium size video screen
- var roomForComments = window.innerHeight - toSubtract;
- if (roomForComments < 200) {
- roomForComments = 200;
- }
- watchDiscussion.style.overflow = "auto";
- watchDiscussion.style.maxHeight = roomForComments+"px"; /* For a video height 360p */
- GM_addStyle(" #watch7-content { border: 1px solid; border-color: #c8c8c8 #dddddd #dddddd #c8c8c8; margin-top: 5px; } #watch-header { margin-top: 0px; margin-bottom: 0px; } ");
- }
- var watchSidebar = document.getElementById("watch-sidebar") || document.getElementById("watch7-sidebar");
- if (watchSidebar) {
- watchSidebar.style.overflow = "auto";
- watchSidebar.style.maxHeight = (window.innerHeight - 69)+"px";
- // May 2012 - fixes below no longer needed.
- // Now the text wraps because of the scrollbar, so we widen the element:
- // watchSidebar.style.width = (320+24)+"px";
- // watchSidebar.style.width = '300px';
- // And we must widen its container also:
- // TODO BUG: Why does this work in the console, but not from the userscript?
- // document.getElementById("watch-main").style.width = (960+24)+"px";
- GM_addStyle(" #watch-sidebar, #watch7-sidebar { border: 1px solid; border-color: #c8c8c8 #dddddd #dddddd #c8c8c8; } ");
- }
- if (scrollDownToVideo) {
- // Un-float the header:
- GM_addStyle(" #masthead-positioner { position: initial; } #masthead-positioner-height-offset { height: 0px; } ");
- //// Title text
- // document.getElementById("eow-title").scrollIntoView();
- //// Uploader info and videolist popdown.
- // document.getElementById("watch-headline-user-info").scrollIntoView();
- //// The author's video list (was supposed to be a small gap above the video when collapsed, but it's not)
- // document.getElementById("watch-more-from-user").scrollIntoView();
- //// The video
- // document.getElementsByTagName("embed")[0].scrollIntoView();
- //// The video
- var watchVideo = document.getElementById("movie_player") || document.getElementById("player-api");
- if (watchVideo) {
- watchVideo.scrollIntoView();
- }
- //// Slight gap above the video (I prefer that)
- // var watchContainer = document.getElementById("watch7-container");
- // if (watchContainer) {
- // watchContainer.scrollIntoView();
- // }
- }
- // ~ October 2014
- // This feels like a bug in Chrome 38. The element is given position:absolute but it does not move up when its parent does! We can fix it anyway:
- GM_addStyle(" #watch8-secondary-actions { position: initial; } ");
- },1000);
- }
- if (animateThumbnails) {
- // == Thumbnail animation ==
- // TODO: This is working fine on "related videos" thumbnails, but not on queue
- // thumbnails, even if I have the queue open when I load the page.
- // Perhaps we are responding to a mouseout event from a child element, because
- // we are not checking the event target like we should do.
- function initThumbnailAnimator() {
- // function createThumbnailAnimatorEvent(thumbImage) {
- var thumbImage = null;
- var originalHref = null;
- var evt = null;
- var timer = null;
- //var frames = ["1.jpg","2.jpg","3.jpg"]; // "default.jpg",
- var frames = ["1","2","3"];
- var frameI = 0;
- function changeFrame() {
- frameI = (frameI + 1) % frames.length;
- var extension = originalHref.replace(/^.*\./, '');
- var filename = frames[frameI] + '.' + extension;
- thumbImage.src = originalHref.replace(/\/[^/]*$/,'') + '/' + filename;
- }
- function startAnimation() {
- originalHref = thumbImage.src;
- if (originalHref.match(/^data:/)) {
- return;
- }
- // We make this check quite late, due to lazy loading
- if (originalHref.match(/\/(.qdefault|default|0)\.(jpg|webp)$/)) {
- // logElem("Starting animation",thumbImage);
- timer = setInterval(changeFrame,600);
- }
- }
- function stopAnimation() {
- if (timer) {
- // logElem("Stopping animation",thumbImage);
- clearInterval(timer);
- timer = null;
- // This isn't really neccessary, except to ensure the check for default\.jpg above works next time!
- //thumbImage.src = thumbImage.src.replace(/\/[^/]*$/,'') + '/' + "default.jpg";
- thumbImage.src = originalHref;
- }
- }
- function logElem(name,elem) {
- report = "<"+elem.tagName+" id="+elem.id+" class="+elem.className+" src="+elem.src+" />";
- GM_log(name+" = "+report);
- }
- function check(fn) {
- return function(evt) {
- // logElem("["+evt.type+"] evt.target",evt.target);
- var elemToCheck = evt.target || evt.srcElement;
- if (elemToCheck.tagName == "IMG") {
- thumbImage = elemToCheck;
- return fn();
- } else if (elemToCheck.className=='screen') {
- var seekImg = elemToCheck.parentNode.getElementsByTagName("img")[0];
- if (seekImg) {
- thumbImage = seekImg;
- return fn();
- }
- // } else {
- // var imgCount = elemToCheck.getElementsByTagName("img").length;
- // if (imgCount == 1) {
- // thumbImage = elemToCheck.getElementsByTagName("img")[0];
- // // logElem("["+evt.type+"] checking sub-image",thumbImage);
- // logElem("Whilst checking",elemToCheck);
- // logElem(" Animating elem",thumbImage);
- // logElem(" with parent",thumbImage.parentNode);
- // logElem(" whilst currentTarget",evt.currentTarget);
- // logElem(" and srcElement",evt.srcElement);
- // return fn();
- // }
- }
- };
- }
- //// Unfortunately these do not fire on any HTMLImageElements when browsing the queue.
- document.body.addEventListener("mouseover",check(startAnimation),false);
- document.body.addEventListener("mouseout",check(stopAnimation),false);
- // var videoList = document.getElementById("watch-sidebar"); // or watch-module or watch-module-body or watch-related or watch-more-related
- // var videoList = document.getElementsByClassName("video-list")[0]; // can be 4 of these!
- // var thumbs = document.getElementsByTagName("img");
- // for (var i=0;i<thumbs.length;i++) {
- // createThumbnailAnimatorEvent(thumbs[i]);
- // }
- }
- setTimeout(initThumbnailAnimator,1000);
- }
- if (unfloatTheHeader) {
- GM_addStyle("#masthead-positioner { position: static; }");
- var gapElement = document.getElementById("masthead-positioner-height-offset");
- if (gapElement) {
- gapElement.parentNode.removeChild(gapElement);
- }
- }