您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
This script aims to revert some of Youtube's recent UI changes, switching everything back around and formatting the video cards back into their original dimensions. It works pretty well on my computer (at least it's better than all the other ones I've tried).
当前为
- // ==UserScript==
- // @name YouTube Revert Layout
- // @version 4.0
- // @author Garbhj
- // @namespace https://github.com/garbhj
- // @description This script aims to revert some of Youtube's recent UI changes, switching everything back around and formatting the video cards back into their original dimensions. It works pretty well on my computer (at least it's better than all the other ones I've tried).
- // @match *.youtube.com/watch?*
- // @run-at document-end
- // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
- // @license MIT
- // ==/UserScript==
- (function () {
- 'use strict';
- // Modify experiment flags to revert UI changes ***
- ytcfg.set('EXPERIMENT_FLAGS', {
- ...ytcfg.get('EXPERIMENT_FLAGS'),
- "kevlar_watch_comments_panel_button": false,
- "kevlar_watch_comments_ep_disable_theater": true,
- "kevlar_watch_grid": false,
- "kevlar_watch_grid_hide_chips": false,
- "kevlar_watch_grid_reduced_top_margin_rich_grid": false,
- "optimal_reading_width_comments_ep": false,
- "small_avatars_for_comments": false,
- "small_avatars_for_comments_ep": false,
- "swatcheroo_direct_use_rich_grid": false,
- "web_watch_compact_comments": false,
- "web_watch_compact_comments_header": false,
- "swatcheroo_rich_grid_delay": 0,
- "wn_grid_max_item_width": 0,
- "wn_grid_min_item_width": 0,
- });
- // Modify page elements (main function)
- let timeoutId = null; // With timeout function
- function modifyPageElements() {
- if (timeoutId) return; // if a timeout is already pending, exit
- if (window.location.href.includes("youtube.com/watch")) {
- const startTime = performance.now();
- modifySidebarVideos();
- const midTime = performance.now();
- adjustVideoPlayerElements();
- const endTime = performance.now();
- const executionTime1 = midTime - startTime;
- const executionTime2 = endTime - midTime;
- console.log(`modifySidebarVideos() took ${executionTime1.toFixed(2)}ms to execute`);
- console.log(`adjustVideoPlayerElements() took ${executionTime2.toFixed(2)}ms to execute`);
- }
- timeoutId = setTimeout(() => {
- timeoutId = null; // reset the timeout id
- }, 50); // 50 ms rate limit
- }
- // Function to properly format sidebar video elements
- function modifySidebarVideos() {
- // ItemsContainer used for performance improvement, no substantial improvement at the end of the day
- // Try switcing "document" with "itemsContainer" for all the querySelections below (except for the last one) to try it out.
- //const itemsContainer = document.querySelector('#items.style-scope.ytd-watch-next-secondary-results-renderer');
- // Format thumbnails to specified width
- const thumbnailDivs = document.querySelectorAll('ytd-rich-grid-media #thumbnail');
- thumbnailDivs.forEach(function(div) {
- div.style.cssText = `width: 168px; position: absolute;`;
- // Additional attempts to modify corner radius with higher specificity (did not work)
- // div.style.borderRadius = "2px !important";
- // div.style.cssText += "#thumbnail.style-scope.ytd-rich-grid-media { border-radius: 2px !important; }";
- });
- // Modify details div spacing: Optimal min spacing was 99px for me - adjust if neccesary
- // I just put min-height because one line titles messed up spacing for some reason
- // Combined with metadata-line for efficiency
- const detailsDivs = document.querySelectorAll('#details');
- detailsDivs.forEach(div => {
- div.style.cssText = "padding-left:176px; margin-top:-12px; min-height: 101px;";
- });
- // Reformat text size and spacing (view count and relative upload time)
- const metadataLineDivs = document.querySelectorAll("div#metadata-line");
- metadataLineDivs.forEach(div => div.style.cssText = "font-size: 1.2rem; line-height: 1.2rem;");
- // Remove margins from contentsDivs (containing both thumbnail and details) to improve spacing
- const contentsDivs = document.querySelectorAll('div#contents.ytd-rich-grid-row');
- contentsDivs.forEach(div => div.style.cssText = "margin: 0px;");
- // Sepecify rich-item-renderer div spacing (includes playlist and ad items as well) because it's quite big by default
- const richItemDivs = document.querySelectorAll("div#contents.ytd-rich-grid-row > ytd-rich-item-renderer");
- richItemDivs.forEach(div => {
- div.style.cssText = "margin-left: 0px; margin-right 0px; margin-bottom: 13px;";
- // Remove channel avatar profile pics
- const avatarLink = div.querySelector("a#avatar-link");
- if (avatarLink) avatarLink.remove();
- });
- // Modify video title styles (Selecting the yt-formatted-string element within the video-title-link)
- const videoTitleElements = document.querySelectorAll("a#video-title-link yt-formatted-string#video-title");
- videoTitleElements.forEach(element => {
- element.style.fontSize = "1.4rem";
- element.style.lineHeight = "2rem";
- });
- // Modify channel name styles (Targeting specific div in channel-name)
- const channelNameDivs = document.querySelectorAll("#items.style-scope.ytd-watch-next-secondary-results-renderer ytd-channel-name#channel-name div#container");
- channelNameDivs.forEach(div => {
- div.style.fontSize = "1.2rem";
- div.style.lineHeight = "1.9rem";
- });
- // Remove sponsored thumbnail cards (I included this because UBlock standard filters can't handle them yet)
- var sponsoredThumbnails = document.querySelectorAll('div[id="fulfilled-layout"][class*="ytd-ad-slot-renderer"]');
- sponsoredThumbnails.forEach(function(thumbnail) {
- thumbnail.parentNode.removeChild(thumbnail);
- });
- // Removes weird gap at the top of secondary recommendations
- const secondaryDivs = document.querySelectorAll("div#secondary");
- secondaryDivs.forEach(div => div.style.cssText = "padding-top: 0px;");
- }
- // Resize the elements of the video player (otherwise the video player and bottom bar get cut off)
- function adjustVideoPlayerElements() {
- // Get the container's dimensions
- const container = document.getElementById("player");
- if (!container) return; // Exit if container is not found
- // Check if container width is zero (while fullscreen or theatre mode)
- if (container.offsetWidth === 0) {
- console.log("Skipping resize due to zero-width container.");
- return;
- }
- const containerWidth = container.offsetWidth + "px"; // width
- const containerHeight = container.offsetHeight + "px"; // height
- // Adjust main video stream
- const videoStream = document.querySelector(".video-stream.html5-main-video");
- if (videoStream) {
- videoStream.style.width = containerWidth;
- videoStream.style.height = container.offsetHeight + "px"; // Set height like this becasue 100% must made the height 0
- }
- // Adjust interactive video content
- const ivVideoContent = document.querySelector(".ytp-iv-video-content");
- if (ivVideoContent) {
- ivVideoContent.style.width = containerWidth;
- ivVideoContent.style.height = '100%'; // Set height to 100% of its parent
- }
- // Adjust video controls bar (for some reason didn't sync)
- const bottomWidth = (container.offsetWidth - 24) + "px" // Calculate width considering margins
- const chromeBottom = document.querySelector(".ytp-chrome-bottom");
- if (chromeBottom) {
- chromeBottom.style.width = bottomWidth;
- chromeBottom.style.left = '12px'; // Align it with a slight gap on the left
- }
- // Adjust the chapter hover bar within the bottom controls
- const chapterHoverBar = document.querySelector(".ytp-chapter-hover-container");
- if (chapterHoverBar) {
- chapterHoverBar.style.width = bottomWidth;
- }
- }
- // Initialize MutationObserver: will run modifyPageElements upon change
- const observer = new MutationObserver(modifyPageElements);
- observer.observe(document.body, { childList: true, subtree: true });
- })();