您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
A userscript with many utility functions!
// ==UserScript== // @name YouToolBox // @namespace Violentmonkey Scripts // @match https://www.youtube.com/watch* // @version 1.0 // @author CodeOS99 // @description A userscript with many utility functions! // @grant none // @license MIT // ==/UserScript== (function () { 'use strict'; console.log("YTB Active!"); // COLOURS const lightGray = '#A9A9A9'; const darkRed = '#8B0000'; const darkerRed = '#900C3F'; let menuHeld = false; // if the menu is held let menuOx = 0, menuOy = 0; // menu offset x and y // Wait until the page is fully ready to add stuff window.addEventListener('load', () => { makeMenu(); // make the menu button initially }); function makeMenu() { const style = document.createElement('style'); style.textContent = ` #main-menu button { cursor: pointer !important; }`; document.head.appendChild(style); let div = document.createElement('div'); div.id = "main-menu"; Object.assign(div.style, { position: 'fixed', top: '80px', left: '20px', zIndex: 9999, display: 'flex', alignItems: 'center', gap: '1px', userSelect: 'none', flexDirection: 'column' }); let mover = document.createElement('div'); Object.assign(mover.style, { width: '50px', height: '50px', backgroundColor: '#444', // make it visible marginLeft: '10px', borderRadius: '8px', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontWeight: 'bold', fontFamily: 'sans-serif', cursor: 'move', }); mover.textContent = 'Move'; let main_menu_btn = document.createElement('button'); main_menu_btn.id = 'main-menu-btn' main_menu_btn.textContent = 'Show menu?'; Object.assign(main_menu_btn.style, { top: '80px', left: '20px', zIndex: 9999, padding: '10px', fontSize: '14px', background: '#f33', color: '#fff', border: 'none', borderRadius: '4px', }); let topMenuDiv = document.createElement('div'); Object.assign(topMenuDiv.style, { width: '200px', height: '50px', backgroundColor: '#444', // make it visible marginLeft: '10px', borderRadius: '8px', display: 'none', alignItems: 'center', justifyContent: 'center', color: '#fff', fontWeight: 'bold', fontFamily: 'sans-serif', }); let closeMenuBtn = document.createElement('button'); closeMenuBtn.innerText = "X" Object.assign(closeMenuBtn.style, { top: '20px', left: '20px', width: '20px', zIndex: 9999, marginLeft: '10px', fontSize: '14px', background: 'red', color: '#fff', border: 'none', borderRadius: '4px', fontSize: '10px', }); let noteModeButton = document.createElement('button'); noteModeButton.innerText = "NOTES" Object.assign(noteModeButton.style, { top: '80px', left: '20px', width: '50px', zIndex: 9999, marginLeft: '10px', fontSize: '14px', background: lightGray, color: '#fff', border: 'none', borderRadius: '4px', fontSize: '10px', }); let calculatorModeBtn = document.createElement('button'); calculatorModeBtn.innerText = "CALC." Object.assign(calculatorModeBtn.style, { top: '80px', left: '20px', width: '50px', zIndex: 9999, marginLeft: '10px', marginRight: '10px', fontSize: '14px', background: lightGray, color: '#fff', border: 'none', borderRadius: '4px', fontSize: '10px' }); let quickSettingsModeBtn = document.createElement('button'); quickSettingsModeBtn.innerText = "SETTINGS" Object.assign(quickSettingsModeBtn.style, { top: '80px', left: '20px', width: '50px', zIndex: 9999, marginLeft: '10px', fontSize: '14px', background: lightGray, color: '#fff', border: 'none', borderRadius: '4px', fontSize: '10px' }); topMenuDiv.appendChild(closeMenuBtn); topMenuDiv.appendChild(quickSettingsModeBtn); topMenuDiv.appendChild(noteModeButton); topMenuDiv.appendChild(calculatorModeBtn); let menuBtns = [noteModeButton, calculatorModeBtn, quickSettingsModeBtn]; menuBtns.forEach(btn => { btn.onmouseenter = () => { btn.style.backgroundColor = 'gray'; } btn.onmouseleave = () => { btn.style.backgroundColor = lightGray; } btn.onmousedown = () => { btn.style.backgroundColor = 'black' } }); noteModeButton.onmouseup = () => { noteInput.style.display = 'block'; calculatorDiv.style.display = 'none'; quickSettingsDiv.style.display = 'none'; } closeMenuBtn.onmouseover = () => { closeMenuBtn.style.backgroundColor = darkRed; }; closeMenuBtn.onmouseleave = () => { closeMenuBtn.style.backgroundColor = 'red'; }; closeMenuBtn.onmouseup = () => { closeMenuBtn.style.backgroundColor = darkerRed; bottomMenuDiv.style.display = 'none'; topMenuDiv.style.display = 'none'; main_menu_btn.style.display = 'block'; btn.style.backgroundColor = lightGray; } let bottomMenuDiv = document.createElement('div'); Object.assign(bottomMenuDiv.style, { width: '200px', height: '50px', backgroundColor: '#444', marginLeft: '10px', borderRadius: '8px', display: 'none', alignItems: 'center', justifyContent: 'center', color: '#fff', fontWeight: 'bold', fontFamily: 'sans-serif', resize: 'both', overflow: 'auto' }); let noteInput = document.createElement('textarea'); noteInput.value = localStorage.getItem('ytb_notes') || ''; noteInput.addEventListener('input', () => { localStorage.setItem('ytb_notes', noteInput.value); }); noteInput.style.display = 'none'; const buttonLabels = [ '7', '8', '9', '/', '4', '5', '6', '*', '1', '2', '3', '-', '0', '.', '=', '+', 'CLR', 'DEL', '(', ')', ]; let calculatorBtns = []; let calculatorExpr = ''; let calculatorDiv = document.createElement('div'); Object.assign(calculatorDiv.style, { display: 'none', alignItems: 'center', justifyContent: 'center', }); let calcExprH1 = document.createElement('h1'); calcExprH1.innerText = "0"; Object.assign(calcExprH1.style, { backgroundColor: 'gray', borderRadius: '5px', }) calculatorDiv.appendChild(calcExprH1); let calculatorBtnDiv = document.createElement('div'); Object.assign(calculatorBtnDiv.style, { display: 'grid', gridTemplateColumns: 'repeat(4, 50px)', gap: '6px', padding: '10px', justifyContent: 'center', alignItems: 'center' }); calculatorDiv.appendChild(calculatorBtnDiv); bottomMenuDiv.appendChild(calculatorDiv); for (let i = 0; i < buttonLabels.length; i++) { let btn = document.createElement('button'); btn.innerText = buttonLabels[i]; Object.assign(btn.style, { backgroundColor: lightGray, color: 'white', border: 'none', borderRadius: '5px', padding: '15px', fontSize: '16px', cursor: 'pointer', width: '50px', height: '50px', }); btn.onmouseenter = () => { btn.style.backgroundColor = 'gray'; } btn.onmouseleave = () => { btn.style.backgroundColor = lightGray; } btn.onmousedown = () => { btn.style.backgroundColor = 'black' } btn.onmouseup = () => { btn.style.backgroundColor = lightGray; updateCalcExpr(buttonLabels[i]); } calculatorBtnDiv.appendChild(btn); calculatorBtns.push(btn); } function updateCalcExpr(val) { if(val !== 'CLR' && val !== 'DEL' && val !== '=') { if(calculatorExpr !== '0') calculatorExpr += val; else calculatorExpr = val; } else if(val === 'CLR') calculatorExpr = '0'; else if(val === 'DEL') { calculatorExpr = calculatorExpr.substring(0, calculatorExpr.length-1) if(calculatorExpr === '') { calculatorExpr = '0'; } } else if(val === '=') { if(!'+-/*.'.includes(calculatorExpr[calculatorExpr.length - 1])) { try { calculatorExpr = eval(calculatorExpr).toString(); } catch(e) { alert("You made an error in the expression!"); calculatorExpr = '0'; } } } calcExprH1.innerText = calculatorExpr; } let showCalculator = () => { calculatorDiv.style.display = 'flex' quickSettingsDiv.style.display = 'none'; noteInput.style.display = 'none'; } bottomMenuDiv.appendChild(noteInput); calculatorModeBtn.onmousedown = () => { calculatorModeBtn.style.backgroundColor = 'black'; showCalculator(); } let quickSettingsDiv = document.createElement('div'); const layout = [0.5, 0.75, 1, 1.25, 1.5, 144, 240, 360, 480, 720 ]; Object.assign(quickSettingsDiv.style, { display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', // Equal size columns gap: '6px', padding: '10px', justifyContent: 'center', alignItems: 'center', }); for(let btnSpec of layout) { let btn = document.createElement('button'); if(btnSpec <= 1.5) { if(btnSpec < 1) btn.innerText = `x${btnSpec} 🐌` else if(btnSpec == 1) btn.innerText = `x${btnSpec} 🐍` else btn.innerText = `x${btnSpec} 🐇` btn.onmouseup = () => { let player = document.querySelector('video'); player.playbackRate = btnSpec; btn.style.backgroundColor = lightGray; } } else { btn.innerText = `${btnSpec}p` btn.onclick = () => { // Video quality let qualityMap = { 144: 'tiny', 240: 'small', 360: 'medium', 480: 'large', 720: 'hd720', }; setQuality(qualityMap[btnSpec]); } } Object.assign(btn.style, { padding: '10px', fontSize: '14px', backgroundColor: lightGray, color: '#fff', border: 'none', borderRadius: '4px', cursor: 'pointer', width: '80px', }); btn.onmouseenter = () => { btn.style.backgroundColor = 'gray'; } btn.onmouseleave = () => { btn.style.backgroundColor = lightGray; } btn.onmousedown = () => { btn.style.backgroundColor = 'black' } quickSettingsDiv.appendChild(btn); } function setQuality(qualityLabel) { const player = document.getElementById('movie_player'); if (player && player.setPlaybackQualityRange) { player.setPlaybackQualityRange(qualityLabel); player.setPlaybackQuality(qualityLabel); } } function showQuickSettings() { quickSettingsDiv.style.display = 'grid'; calculatorDiv.style.display = 'none'; noteInput.style.display = 'none'; } quickSettingsModeBtn.onmouseup = () => { showQuickSettings(); } bottomMenuDiv.appendChild(quickSettingsDiv); mover.onmousedown = (e) => { if(!menuHeld) { menuHeld = true; menuOx = e.clientX - div.offsetLeft; menuOy = e.clientY - div.offsetTop; document.body.style.userSelect = 'none'; } } document.onmouseup = () => { // add the event listener to the body because there is a possibility for the mouse to move away from the button menuHeld = false; } document.onmousemove = (e) => { if(menuHeld) { div.style.left = (e.clientX - menuOx) + 'px'; div.style.top = (e.clientY - menuOy) + 'px'; } } main_menu_btn.onclick = () => { main_menu_btn.style.display = 'none'; topMenuDiv.style.display = 'flex'; bottomMenuDiv.style.display = 'flex'; }; div.appendChild(mover); div.appendChild(main_menu_btn); div.appendChild(topMenuDiv); div.appendChild(bottomMenuDiv); document.body.appendChild(div); } })();