您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Viewing original video thumbnails, avatars, and channel banners, with a thumbnail preview above the panel.
当前为
// ==UserScript== // @name YouTube Enhancer (Full-Sized Image Preview) // @description Viewing original video thumbnails, avatars, and channel banners, with a thumbnail preview above the panel. // @icon https://raw.githubusercontent.com/exyezed/youtube-enhancer/refs/heads/main/extras/youtube-enhancer.png // @version 1.1 // @author exyezed // @namespace https://github.com/exyezed/youtube-enhancer/ // @supportURL https://github.com/exyezed/youtube-enhancer/issues // @license MIT // @match https://www.youtube.com/* // @grant GM_addStyle // ==/UserScript== (function() { 'use strict'; GM_addStyle(` .YouTubeEnhancerFullSized-button { position: absolute; bottom: 10px; left: 5px; background-color: rgba(0, 0, 0, 0.75); color: white; border: none; border-radius: 3px; padding: 3px; font-size: 18px; cursor: pointer; z-index: 2000; opacity: 0; transition: opacity 0.3s; display: flex; align-items: center; justify-content: center; } .YouTubeEnhancerFullSized-container { position: relative; } .YouTubeEnhancerFullSized-container:hover .YouTubeEnhancerFullSized-button { opacity: 1; } .YouTubeEnhancerFullSized-clickable-image { cursor: pointer; } #YouTubeEnhancerFullSized-custom-image { width: 100%; height: auto; margin-bottom: 20px; box-sizing: border-box; border-radius: 10px; cursor: pointer; } `); const defaultIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="M18 20H4V6h9V4H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-9h-2zm-7.79-3.17l-1.96-2.36L5.5 18h11l-3.54-4.71zM20 4V1h-2v3h-3c.01.01 0 2 0 2h3v2.99c.01.01 2 0 2 0V6h3V4z"/></svg>`; const hoverIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="M19 7v2.99s-1.99.01-2 0V7h-3s.01-1.99 0-2h3V2h2v3h3v2zm-3 4V8h-3V5H5c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-8zM5 19l3-4l2 3l3-4l4 5z"/></svg>`; let YouTubeEnhancerFullSizedCurrentVideoId = ''; function YouTubeEnhancerFullSizedOpenImage(url) { window.open(url, '_blank'); } function YouTubeEnhancerFullSizedAddButton(element, getFullSizeUrl) { if (!element.closest('.YouTubeEnhancerFullSized-container')) { const container = document.createElement('div'); container.className = 'YouTubeEnhancerFullSized-container'; element.parentNode.insertBefore(container, element); container.appendChild(element); const button = document.createElement('button'); button.className = 'YouTubeEnhancerFullSized-button'; button.innerHTML = defaultIcon; button.addEventListener('mouseenter', () => { button.innerHTML = hoverIcon; }); button.addEventListener('mouseleave', () => { button.innerHTML = defaultIcon; }); button.onclick = (e) => { e.stopPropagation(); e.preventDefault(); YouTubeEnhancerFullSizedOpenImage(getFullSizeUrl(element.src)); }; container.appendChild(button); } } function YouTubeEnhancerFullSizedProcessAvatars() { const avatars = document.querySelectorAll('yt-avatar-shape img, yt-img-shadow#avatar img'); avatars.forEach(img => { if (!img.closest('.YouTubeEnhancerFullSized-container')) { const isWatchPage = window.location.pathname.startsWith('/watch'); YouTubeEnhancerFullSizedAddButton(img, (src) => src.replace(/=s\d+-c-k-c0x00ffffff-no-rj.*/, '=s0')); if (isWatchPage) { const button = img.closest('.YouTubeEnhancerFullSized-container').querySelector('.YouTubeEnhancerFullSized-button'); if (button) { button.style.display = 'none'; } } } }); } function YouTubeEnhancerFullSizedProcessChannelBanners() { const banners = document.querySelectorAll('yt-image-banner-view-model img'); banners.forEach(img => { if (!img.closest('.YouTubeEnhancerFullSized-container')) { YouTubeEnhancerFullSizedAddButton(img, (src) => src.replace(/=w\d+-.*/, '=s0')); } }); } function YouTubeEnhancerFullSizedProcessVideoThumbnails() { const thumbnails = document.querySelectorAll('ytd-thumbnail img, ytd-playlist-thumbnail img'); thumbnails.forEach(img => { if (!img.closest('.YouTubeEnhancerFullSized-container')) { YouTubeEnhancerFullSizedAddButton(img, (src) => { const videoId = src.match(/\/vi\/([^\/]+)/)[1]; return `https://i.ytimg.com/vi/${videoId}/maxresdefault.jpg`; }); } }); } function YouTubeEnhancerFullSizedGetVideoId() { const urlParams = new URLSearchParams(window.location.search); return urlParams.get('v'); } function YouTubeEnhancerFullSizedAddOrUpdateImage() { const newVideoId = YouTubeEnhancerFullSizedGetVideoId(); if (newVideoId && newVideoId !== YouTubeEnhancerFullSizedCurrentVideoId) { YouTubeEnhancerFullSizedCurrentVideoId = newVideoId; const targetElement = document.querySelector('#secondary-inner #panels'); if (targetElement) { let img = document.getElementById('YouTubeEnhancerFullSized-custom-image'); if (!img) { img = document.createElement('img'); img.id = 'YouTubeEnhancerFullSized-custom-image'; targetElement.parentNode.insertBefore(img, targetElement); img.addEventListener('click', () => { const maxResUrl = `https://i.ytimg.com/vi/${YouTubeEnhancerFullSizedCurrentVideoId}/maxresdefault.jpg`; YouTubeEnhancerFullSizedOpenImage(maxResUrl); }); } img.src = `https://i.ytimg.com/vi/${YouTubeEnhancerFullSizedCurrentVideoId}/mqdefault.jpg`; } } } function YouTubeEnhancerFullSizedObservePageChanges() { const observer = new MutationObserver((mutations) => { YouTubeEnhancerFullSizedProcessAvatars(); YouTubeEnhancerFullSizedProcessChannelBanners(); YouTubeEnhancerFullSizedProcessVideoThumbnails(); YouTubeEnhancerFullSizedAddOrUpdateImage(); }); observer.observe(document.body, { childList: true, subtree: true }); } // Initial processing YouTubeEnhancerFullSizedProcessAvatars(); YouTubeEnhancerFullSizedProcessChannelBanners(); YouTubeEnhancerFullSizedProcessVideoThumbnails(); YouTubeEnhancerFullSizedAddOrUpdateImage(); // Observe for future changes YouTubeEnhancerFullSizedObservePageChanges(); // Check when URL changes window.addEventListener('yt-navigate-finish', () => { YouTubeEnhancerFullSizedProcessAvatars(); YouTubeEnhancerFullSizedProcessChannelBanners(); YouTubeEnhancerFullSizedProcessVideoThumbnails(); YouTubeEnhancerFullSizedAddOrUpdateImage(); }); console.log('YouTube Enhancer (Full-Sized Image Preview) is running'); })();