Greasy Fork is available in English.
(自用脚本) Youtube 视频进度条实时显示
// ==UserScript==
// @author Lete114
// @version 0.1
// @license MIT License
// @name Youtube 视频进度条
// @description (自用脚本) Youtube 视频进度条实时显示
// @match https://*.youtube.com/*
// @icon https://www.youtube.com/s/desktop/b83f134a/img/favicon_48x48.png
// @namespace https://github.com/Lete114/my-tampermonkey-scripts
// @grant GM_registerMenuCommand
// ==/UserScript==
;(function () {
'use strict'
/**
* @param { string } Selector
* @param { Element } el
*/
const $ = (Selector, el) => (el || document).querySelector(Selector)
/**
*
* @param { function } func
* @param { number } delay
* @returns
*/
function throttle(func, delay) {
let timer = null
return function (...args) {
if (!timer) {
timer = setTimeout(() => {
func.apply(this, args)
timer = null
}, delay)
}
}
}
const reg = /https:\/\/.*.youtube.com\/watch/
const div = document.createElement('div')
const className = 'ytp-video-progress'
div.className = `${className} ytp-swatch-background-color`
const pos = localStorage.getItem(className) ? 'bottom' : 'top'
div.style = `${pos}: 0; left: 0; position: absolute; height: 3px; transition: width 0.4s ease;`
// 主要用于检测 url 变化时判断是视频页面则执行
setInterval(videoPage, 200)
let url = null
function videoPage() {
const currentURL = window.location.href
const isVideoPage = reg.test(currentURL)
// 不是视频页面
if (!isVideoPage) {
div.style.width = 0
return
}
// 确保只执行一次
if (currentURL === url) return
url = currentURL
const video = $('video')
video.addEventListener('timeupdate', throttle(handlerTimeupdate, 1000))
function handlerTimeupdate() {
if (video.paused) return
const percentage = (video.currentTime / video.duration) * 100
const width = percentage + '%'
div.style.width = width
}
if (location.hostname === 'm.youtube.com') {
$('#player').appendChild(div)
} else {
const timer = setInterval(() => {
const playerContainerOuter = $('#ytd-player')
if (playerContainerOuter) {
clearInterval(timer)
playerContainerOuter.appendChild(div)
}
}, 500)
}
GM_registerMenuCommand('切换进度条位置(顶部或底部)', function () {
if (localStorage.getItem(className)) {
localStorage.removeItem(className)
div.style.removeProperty('bottom')
div.style.top = 0
} else {
localStorage.setItem(className, true)
div.style.removeProperty('top')
div.style.bottom = 0
}
})
}
})()