您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Visual indicator of page progress while scrolling
当前为
// ==UserScript== // @license MIT // @name Scroll Page Progress // @namespace http://tampermonkey.net/ // @version 1.6.2 // @description Visual indicator of page progress while scrolling // @author You // @match *://*/* // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @grant none // ==/UserScript== (function() { 'use strict'; if (window.trustedTypes && window.trustedTypes.createPolicy) { window.trustedTypes.createPolicy('default', { createHTML: (string, sink) => string }); } let globalShadow function once(fn, context) { var result; return function() { if(fn) { result = fn.apply(context || this, arguments); fn = null; } return result; }; } function insertCirculaProgressBarEl() { const shadowHost = document.createElement('div') const shadow = shadowHost.attachShadow({ mode: "closed" }); const circularProgressBar = document.createElement('div') const contentWrapper = document.createElement('div') const closeOverlay = document.createElement('div') const title = document.createElement('div') const overlay = document.createElement('div') const leftSide = document.createElement('div') const rightSide = document.createElement('div') globalShadow = shadow circularProgressBar.classList.add('circular-progress-bar') title.classList.add('title'); closeOverlay.classList.add('close-overlay'); contentWrapper.classList.add('content-wrapper') overlay.classList.add('overlay'); leftSide.classList.add('left-side'); rightSide.classList.add('right-side'); shadowHost.id = 'host-shwadow-circular-progress' title.innerText = '-%' if (window.trustedTypes) { closeOverlay.innerHTML = window.trustedTypes.defaultPolicy.createHTML('×') } else { closeOverlay.innerHTML = '×' } closeOverlay.addEventListener('click', function() { circularProgressBar.style.display = 'none' const path = window.location.pathname; let savedPaths = JSON.parse(localStorage.getItem('not-allowed-paths')) || []; console.log(path, savedPaths) if (!savedPaths.includes(path)) { savedPaths.push(path); localStorage.setItem('not-allowed-paths', JSON.stringify(savedPaths)); } }); ;[title, overlay, leftSide, rightSide].forEach(childEl => contentWrapper.appendChild(childEl)) circularProgressBar.appendChild(closeOverlay) circularProgressBar.appendChild(contentWrapper) shadow.appendChild(circularProgressBar) document.body.appendChild(shadowHost) } function addCSS() { const styleSheet = document.createElement('style'); styleSheet.textContent = ` * { box-sizing: border-box; padding: 0; margin: 0; } .circular-progress-bar { --backgroundColor: #424242; --left-side-angle: 180deg; --barColor:orangered; width: 60px; height: 60px; color: #fff; border-radius: 50%; position: fixed; z-index: 2147483646; background: var(--backgroundColor); border: 5px solid white; box-shadow: 0 1px 1px hsl(0deg 0% 0% / 0.075), 0 2px 2px hsl(0deg 0% 0% / 0.075), 0 4px 4px hsl(0deg 0% 0% / 0.075), 0 8px 8px hsl(0deg 0% 0% / 0.075), 0 16px 16px hsl(0deg 0% 0% / 0.075); text-align: center; cursor: pointer; transition: opacity 0.2s ease; } .circular-progress-bar .overlay { width: 50%; height: 100%; position: absolute; top: 0; left: 0; z-index: 1; background-color: var(--backgroundColor); } .close-overlay { width: 20px; height: 20px; position: absolute; left: 100%; top: -30%; z-index: 2147483647; display: flex; justify-content: center; align-items: center; border-radius: 50%; background: orangered; font-size: 19px; text-align: center; opacity: 0; } .close-overlay:hover { font-weight: bold; } .content-wrapper { overflow: hidden; height: 100%; width: 100%; border-radius: 50%; position: relative; } .circular-progress-bar:hover .close-overlay { opacity:1; } .circular-progress-bar .title { font-size: 15px; font-weight: bold; position:relative; height: 100%; display:flex; justify-content:center; align-items: center; z-index: 100; } .circular-progress-bar .left-side, .circular-progress-bar .right-side { width: 50%; height: 100%; position: absolute; top: 0; left: 0; border: 5px solid var(--barColor); border-radius: 100px 0px 0px 100px; border-right: 0; transform-origin: right; } .circular-progress-bar .left-side { transform: rotate(var(--left-side-angle)); z-index: var(--zindex); } .circular-progress-bar .right-side { transform: rotate(var(--right-side-angle)); } ` globalShadow.appendChild(styleSheet) } insertCirculaProgressBarEl() addCSS() const currentState = { deg: 0, progress: 0, zIndex: 0 } function setAngle(deg) { const progressBar = globalShadow.querySelector('.circular-progress-bar') const leftSide = globalShadow.querySelector('.left-side') const rightSide = globalShadow.querySelector('.right-side') leftSide.style.opacity = "0" const zIndex = deg > 180 ? 100 : 0 const rightSideAngle = deg < 180 ? deg : 180 const leftSideAngle = deg const zIndexChangedToPositive = currentState.zIndex === 0 && zIndex === 100 if (deg > 180) { leftSide.style.opacity = "1" progressBar.style.setProperty('--left-side-angle', `${leftSideAngle}deg`); progressBar.style.setProperty('--zindex', zIndex); } progressBar.style.setProperty('--right-side-angle', `${rightSideAngle}deg`); currentState.deg = deg /*if (zIndex === 100 && zIndexChangedToPositive) { setUnsetOpacity() }*/ } function percentageToAngle (percentageNumber) { if (percentageNumber > 100) { return 360 } if (percentageNumber < 0) { return 0 } return (360 * percentageNumber)/100 } function setPercentage(percentageNumber) { const angle = percentageToAngle(percentageNumber) setAngle(angle) } function debounce(callback, wait) { let timerId; return (...args) => { clearTimeout(timerId); timerId = setTimeout(() => { callback(...args); }, wait); }; } const progressBar = globalShadow.querySelector('.circular-progress-bar') const body = document.body; let offsetX = 0, offsetY = 0, isDragging = false; progressBar.addEventListener("mousedown", (e) => { e.preventDefault() offsetX = e.clientX - progressBar.offsetLeft; offsetY = e.clientY - progressBar.offsetTop; isDragging = true; progressBar.style.cursor = "grabbing"; progressBar.style.opacity = "0.3"; }); document.addEventListener("mousemove", (e) => { if (isDragging) { e.preventDefault(); const left = e.clientX - offsetX; const top = e.clientY - offsetY; progressBar.style.left = `${left}px`; progressBar.style.top = `${top}px`; savePosition(left, top); // Guardar la posición cada vez que se mueve } }); document.addEventListener("mouseup", () => { isDragging = false; progressBar.style.cursor = "grab"; progressBar.style.opacity = "1"; }); function savePosition(left, top) { const position = { left, top }; localStorage.setItem("elementPosition", JSON.stringify(position)); } function loadPosition() { const savedPosition = localStorage.getItem("elementPosition"); if (savedPosition) { const { left, top } = JSON.parse(savedPosition); progressBar.style.left = `${left}px`; progressBar.style.top = `${top}px`; } else { progressBar.style.right = `10px`; progressBar.style.top = `10px`; } } function getCurrentScrollProgress() { const winScroll = document.body.scrollTop || document.documentElement.scrollTop; const height = document.documentElement.scrollHeight - document.documentElement.clientHeight; const progress = (winScroll / height) * 100; return Math.trunc(progress); } const progressBarTitle = globalShadow.querySelector('.title') document.onreadystatechange = function () { if (document.readyState == "complete") { if (window.trustedTypes && window.trustedTypes.createPolicy && !window.trustedTypes.defaultPolicy) { window.trustedTypes.createPolicy('default', { createHTML: (string, sink) => string }); } const currentPath = window.location.pathname; const savedPaths = JSON.parse(localStorage.getItem('not-allowed-paths')) || []; if (savedPaths.includes(currentPath)) { progressBar.style.display = 'none'; return; } loadPosition() document.addEventListener('scroll', debounce(() => { setPercentage(getCurrentScrollProgress()) progressBarTitle.innerText = getCurrentScrollProgress() + '%' console.log(progressBarTitle, getCurrentScrollProgress()) currentState.progress = getCurrentScrollProgress() currentState.deg = percentageToAngle(getCurrentScrollProgress()) }, 50)) } } })();