您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Show a remove button on hover over video thumbnails in the Watch Later list
当前为
// ==UserScript== // @name YouTube Watch Later Remove Button on Hover // @namespace http://tampermonkey.net/ // @version 0.6.1 // @description Show a remove button on hover over video thumbnails in the Watch Later list // @license MIT // @match https://www.youtube.com/* // @run-at document-start // @grant none // @inject-into page // ==/UserScript== (function () { 'use strict'; let scriptEnable = false; const insp = o => o ? (o.polymerController || o.inst || o || 0) : (o || 0); function getItemData(menu) { if (!menu) return; let items = ((menu || 0).menuRenderer || 0).items || 0; if (!(items.length >= 1)) return; const filtered = items.filter((entry) => { if (!entry || typeof entry !== 'object') return false; try { const t = (JSON.stringify(entry) || ''); return t.includes('ACTION_REMOVE_VIDEO'); } catch (e) { return false; } }); if (filtered.length !== 1) return; let itemData = filtered[0]; itemData = Object.values(itemData).filter(e => e.serviceEndpoint || e.command)[0]; if (!itemData) return; return itemData; } const removeButtonOnclick = function (e) { const button = this; if (!scriptEnable) return; let videoElement = button.closest('ytd-thumbnail'); if (!videoElement) return; let renderer = videoElement.closest('ytd-playlist-video-renderer.style-scope.ytd-playlist-video-list-renderer[is-editable]'); if (!renderer) return; let data = insp(renderer).data || 0; const itemData = getItemData(data.menu); if (!itemData) return; e.preventDefault(); // Prevent the default action of the event e.stopPropagation(); // Stop the event from bubbling up e.stopImmediatePropagation(); // Prevents other listeners of the same event from being called const cntNode = (document.querySelector('ytd-app') || renderer); (function (data) { const a = data.serviceEndpoint; const b = data.command; a && this.ytComponentBehavior.resolveCommand(a); b && this.ytComponentBehavior.resolveCommand(b); }).call(insp(cntNode), itemData); }; function createRemoveButton(videoElement) { let removeButton = document.createElement('button'); removeButton.className = 'watch-later-remove-button'; removeButton.textContent = 'Remove'; removeButton.style.position = 'absolute'; removeButton.style.top = '5px'; removeButton.style.right = '5px'; removeButton.style.zIndex = '1000'; removeButton.onclick = removeButtonOnclick; videoElement.appendChild(removeButton); } const mouseenterHandler = function (e) { if (!e || !(e.target instanceof HTMLElement)) return; if (!scriptEnable) return; if (!e.target.classList.contains('ytd-playlist-video-renderer')) return; let videoElement = e.target.closest('ytd-thumbnail'); if (!videoElement) return; let renderer = videoElement.closest('ytd-playlist-video-renderer.style-scope.ytd-playlist-video-list-renderer[is-editable]'); if (!renderer || renderer.is !== 'ytd-playlist-video-renderer') return; let data = insp(renderer).data || 0; let itemData = getItemData(data.menu); if (!itemData) return; let button = videoElement.querySelector('button.watch-later-remove-button') if (!button) { createRemoveButton(videoElement); } else { button.style.display = ''; } }; const mouseleaveHandler = function (e) { if (!e || !(e.target instanceof HTMLElement)) return; if (!e.target.classList.contains('ytd-playlist-video-renderer')) return; let button = e.target.querySelector('button.watch-later-remove-button'); if (button) { button.style.display = 'none'; } }; document.addEventListener('yt-navigate-finish', () => { const newEnable = location.pathname === '/playlist' && location.search.includes('list=WL'); if (scriptEnable ^ newEnable) { if (scriptEnable) { scriptEnable = false; document.removeEventListener('mouseenter', mouseenterHandler, true); document.removeEventListener('mouseleave', mouseleaveHandler, true); } else if (newEnable) { scriptEnable = true; document.addEventListener('mouseenter', mouseenterHandler, true); document.addEventListener('mouseleave', mouseleaveHandler, true); } } }, false); })();