NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Youtube Like/Dislike and Skip Ad Keyboard Shortcuts // @namespace youtube // @include https://www.youtube.com/* // @description Keybindings: "[" to like, "]" to dislike, and "S" to skip pre-video or banner ads. Browser notifications can be toggled via the menu. // @version 1.5 // @grant GM_notification // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand // @run-at document-end // @icon https://www.google.com/s2/favicons?domain=youtube.com&sz=128 // @updateURL https://openuserjs.org/meta/nascent/Youtube_likedislike_video_and_skip_ad_keyboard_shortcuts.meta.js // @license GPL-3.0-or-later // ==/UserScript== /*jshint esversion: 6 */ (function () { "use strict"; // Retrieve the saved setting; if not set, default to true. let browserNotifications = GM_getValue("browserNotifications", true); // Menu command for toggling browser notifications. function toggleBrowserNotifications() { browserNotifications = !browserNotifications; GM_setValue("browserNotifications", browserNotifications); alert(`Browser notifications are now ${browserNotifications ? "enabled" : "disabled"}.`); } GM_registerMenuCommand("Toggle Browser Notifications", toggleBrowserNotifications); let onVideoPage = false, skipAd = null, skipBannerAd = null, like = null, dislike = null; function findButtons() { // Only run on video watch pages. if (!/^\/watch/.test(location.pathname)) { onVideoPage = false; return; } onVideoPage = true; // Find the skip ad buttons. skipAd = document.querySelector(".ytp-ad-skip-button"); skipBannerAd = document.querySelector(".ytp-ad-overlay-close-button"); // Find the Like/Dislike buttons by custom element tags. like = document.querySelector("like-button-view-model button"); dislike = document.querySelector("dislike-button-view-model button"); // Fallback: Use attribute selectors if necessary. if (!like) { like = document.querySelector('button[aria-label*="like this video"]'); } if (!dislike) { dislike = document.querySelector('button[aria-label^="Dislike this video"]'); } } // Initial search. findButtons(); // Watch for DOM changes (AJAX navigation on YouTube). const observer = new MutationObserver(findButtons); observer.observe(document.documentElement, { childList: true, subtree: true }); // Listen for keydown events. window.addEventListener("keydown", (e) => { if (!onVideoPage) { return; } // Avoid interfering with input fields or editable content. const tag = e.target.tagName.toLowerCase(); if (e.target.isContentEditable || tag === "input" || tag === "textarea") { return; } // "[" key to toggle like. if (e.code === "BracketLeft" && like) { like.click(); if (browserNotifications && typeof GM_notification !== "undefined") { const action = like.getAttribute("aria-pressed") === "true" ? "Video Liked" : "Like Removed"; GM_notification({ title: "YouTube", text: action, silent: true, timeout: 2500 }); } } // "]" key to toggle dislike. else if (e.code === "BracketRight" && dislike) { dislike.click(); if (browserNotifications && typeof GM_notification !== "undefined") { const action = dislike.getAttribute("aria-pressed") === "true" ? "Video Disliked" : "Dislike Removed"; GM_notification({ title: "YouTube", text: action, silent: true, timeout: 2500 }); } } // "S" key to skip ads. else if (e.code === "KeyS") { if (skipAd) { skipAd.click(); } else if (skipBannerAd) { skipBannerAd.click(); } } }); })();