您需要先安装一个扩展,例如 篡改猴、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.2
- // @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');
- 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');
- 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);
- })();