Enables keyboard shortcuts to like/dislike a video on YouTube.
当前为
// ==UserScript==
// @name YouTube Like/Dislike Shortcut
// @name:pt-BR Atalhos Gostei/Não Gostei no YouTube
// @namespace will64gamer
// @author will64gamer
// @description Enables keyboard shortcuts to like/dislike a video on YouTube.
// @description:pt-BR Cria atalhos para os botões gostei/não gostei em um vídeo no YouTube.
// @include https://www.youtube.com/*
// @license MIT
// @version 2.3
// ==/UserScript==
// You can change the codes to whichever keys you want to use for liking, disliking, and opening or writing comments on Shorts.
const codeLike = "NumpadAdd";
const codeDislike = "NumpadSubtract";
const codeComments = "NumpadMultiply";
const codeWrite = "NumpadDivide";
// Change this to false if you don't want Shorts to refresh on load.
const shortsRefresh = true;
let isShort = false;
let tag, like, dislike, sLike, sDislike, comments, closeComments, textbox, initialRefresh;
const observer = new MutationObserver(findButtons);
addEventListener('yt-page-data-updated', reset);
addEventListener('popstate', reset);
function reset() {
isVideo = /^\/watch/.test(location.pathname);
isShort = /^\/shorts/.test(location.pathname);
if (isVideo||isShort) {
removeEventListener("keydown", press);
like = null; dislike = null; sLike = null; sDislike = null; comments = null; closeComments = null; textbox = null;
observer.observe(document.documentElement, {childList: true, subtree: true});
findButtons();
} else {initialRefresh = true;}
}
function findButtons() {
if ((like && dislike) || (sLike && sDislike && comments)) {
addEventListener("keydown", press);
observer.disconnect();
let currentURL = location.href;
if (isShort && shortsRefresh) {
let shortInterval = setInterval(() => {
if (location.href !== currentURL) {
clearInterval(shortInterval);
location.reload();
}
}, 400);
} else if (isVideo) {initialRefresh = true;}
}
if (isShort) {
if (initialRefresh) {
initialRefresh = false;
location.reload();
}
sLike = document.getElementById("like-button")?.getElementsByTagName('button')[0];
sDislike = document.getElementById("dislike-button")?.getElementsByTagName('button')[0];
comments = document.getElementById("comments-button")?.getElementsByTagName('button')[0];
} else {
like = document.getElementsByTagName("like-button-view-model")[0]?.firstElementChild?.firstElementChild?.firstElementChild;
dislike = document.getElementsByTagName("dislike-button-view-model")[0]?.firstElementChild?.firstElementChild?.firstElementChild;
}
}
function openComments() {
comments.click();
let closeCommentsInterval = setInterval(() => {
if (!closeComments) {
closeComments = document.getElementById("visibility-button")?.getElementsByTagName('button')[0];
} else {
clearInterval(closeCommentsInterval);
}
}, 300);
}
function press(e) {
if (e.target.getAttribute("contenteditable") === "true") {return;}
tag = e.target.tagName.toLowerCase();
if (tag === "input" || tag === "textarea") {return;}
switch (e.code) {
case codeComments:
if (comments) {
if (closeComments) {
closeComments.click();
closeComments = null;
} else {
openComments();
}
}
break;
case codeWrite:
if (textbox) {
openComments();
setTimeout(() => {
textbox.click();
}, 100);
} else if (comments) {
openComments();
let textboxInterval = setInterval(() => {
if (!textbox) {
textbox = document.getElementById("simplebox-placeholder");
} else {
textbox.focus();
clearInterval(textboxInterval);
}
}, 300);
}
break;
case codeLike:
if (like) {like.click();}
else if (sLike) {sLike.click();}
break;
case codeDislike:
if (dislike) {dislike.click();}
else if (sDislike) {sDislike.click();}
break;
}
}