您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Return dislikes on youtube mobile page. Uses returnyoutubedislike.com API
当前为
// ==UserScript== // @name Return Youtube Dislike On Mobile // @namespace https://gitlab.com/Dwyriel // @version 1.1 // @description Return dislikes on youtube mobile page. Uses returnyoutubedislike.com API // @author Dwyriel // @license MIT // @match *://*.youtube.com/* // @grant none // @homepageURL https://gitlab.com/Dwyriel/Greasyfork-Scripts // ==/UserScript== (function () { 'use strict'; const scriptName = "[Return Youtube Dislike On Mobile]"; const API_URL = "https://returnyoutubedislikeapi.com/votes?videoId="; const buttonTag = "ytm-toggle-button-renderer"; const dislikeButtonID = "dislikeButtonID_198wa16df78ms1d"; let dislikeCache = {}; let oldURL = ""; let videoID; let fetching = false; const config = { attributes: true, childList: true, subtree: true }; let mutationObserver = new MutationObserver(() => { }); const getVideoID = () => { return (new Proxy(new URLSearchParams(window.location.search), { get: (UrlSearchParams, key) => UrlSearchParams.get(key) })).v; } const formatedDislikeNumber = () => { let dislikes = dislikeCache[videoID]; let formattedNum = 0, character = ''; if (dislikes / 1000000000 >= 1) { formattedNum = Math.round(dislikes / 1000000000); character = 'B'; } else if (dislikes / 1000000 >= 1) { formattedNum = Math.round(dislikes / 1000000); character = 'M'; } else if (dislikes / 1000 >= 1) { formattedNum = Math.round(dislikes / 1000); character = 'K'; } else formattedNum = dislikes; return formattedNum + character; } const modifyDislikeButton = () => { //check explanation at the end of the file let buttons = document.getElementsByTagName(buttonTag); if (buttons.length == 0) return; document.getElementById(dislikeButtonID)?.remove(); let dislikeButton = buttons[1].children[0]; dislikeButton.children[0].style = "margin: 0 6px 0 -6px"; let dislikes = buttons[0].children[0].children[1].cloneNode(true); dislikes.id = dislikeButtonID; dislikeButton.appendChild(dislikes); dislikeButton.appendChild(dislikeButton.children[1]); let dislikeString = formatedDislikeNumber(); dislikes.children[0].innerHTML = dislikeString; dislikeButton.style = `width: ${56 + (8 * dislikeString.length)}px`; } let hookObserver = async () => { let buttons = document.getElementsByTagName(buttonTag); if (buttons.length > 0) { mutationObserver.disconnect(); modifyDislikeButton(); mutationObserver.observe(buttons[1].parentNode, config); } else await new Promise(() => setTimeout(hookObserver, 100)); } const callback = () => { let currURL = window.location.href; if (window.location.pathname != "/watch") { oldURL = currURL; return; } if (fetching || (oldURL == currURL)) return; fetching = true; oldURL = currURL; videoID = getVideoID(); if (typeof videoID != 'string') { fetching = false; return; } if (dislikeCache[videoID] != undefined) { fetching = false; hookObserver(); return; } let request = new Request(API_URL + videoID); fetch(request).then(response => response.json(), (reason) => { fetching = false; console.error("Couldn't fetch dislikes", reason) }).then(response => { console.log(`${scriptName} response from api: \n${JSON.stringify(response)}`); dislikeCache[videoID] = response.dislikes; fetching = false; hookObserver(); }, (reason) => { fetching = false; console.error("Couldn't fetch dislikes", reason) }); }; mutationObserver = new MutationObserver(() => { hookObserver(); }); const old_pushState = history.pushState; history.pushState = function pushState() { let origFuncReturn = old_pushState.apply(this, arguments); window.dispatchEvent(new Event('historyChanged')); return origFuncReturn; }; window.addEventListener('popstate', () => window.dispatchEvent(new Event('historyChanged'))); window.addEventListener('load', () => callback()); window.addEventListener('historyChanged', () => { mutationObserver.disconnect(); callback(); }); })(); /* modifyDislikeButton function explanation let elements = document.getElementsByTagName(likeButtonTag); //get both like and dislike buttons if they exist if (elements.length == 0) return; document.getElementById(dislikeButtonID)?.remove(); //remove if it was already created before let likeButtonElement = elements[0]; //like button is always the first let actualLikeButton = likeButtonElement.children[0]; //only has 1 children (a Button tag) let likes = actualLikeButton.children[1]; //like/dislike count is always the second children (the first is the icon) let dislikeButtonElement = elements[1];//same as above, for the second(dislike) button let actualDislikeButton = dislikeButtonElement.children[0]; let dislikeIcon = actualDislikeButton.children[0]; dislikeIcon.style = "margin: 0 6px 0 -6px"; //applies the same margin that the like icon has let dislikes = likes.cloneNode(true); actualDislikeButton.appendChild(dislikes); //appends cloned Node as the last child actualDislikeButton.appendChild(actualDislikeButton.children[1]); //move second Node to last pos to keep them consistent dislikeButton.style = `width: ${56 + (8 * dislikeString.length)}px`; //increase dislike button size using a similar formula of the like button let dislikeText = dislikes.children[0]; //get span inside dislike div dislikeText.innerHTML = dislikeCount; */