// ==UserScript== // @name 视频触屏滑动脚本 // @namespace http://tampermonkey.net/ // @version 1.0.1 // @description 左右滑动可以拖动视频进度条 // @author sanngtsu // @match *://*/* // @grant none // @run-at document-end // ==/UserScript== (function() { 'use strict'; const SENSITIVITY = 0.6; const MIN_SWIPE_DISTANCE = 10; let isTouching = false; let startX = 0, startY = 0; let startVideoTime = 0; let currentVideo = null; let hasMoved = false; let tipElement = null; function formatTime(seconds) { if (isNaN(seconds)) return "00:00"; const m = Math.floor(seconds / 60).toString().padStart(2, '0'); const s = Math.floor(seconds % 60).toString().padStart(2, '0'); return `${m}:${s}`; } function createTip() { if (tipElement) return; tipElement = document.createElement('div'); tipElement.style.cssText = ` position: absolute; z-index: 99999999; background: rgba(0, 0, 0, 0.75); color: #fff; padding: 8px 14px; border-radius: 6px; font-size: 16px; font-weight: 500; display: none; pointer-events: none; white-space: nowrap; `; } function getFullscreenContainer() { return document.fullscreenElement || document.documentElement; } function isFullscreen() { return !!document.fullscreenElement; } function showTip(video, current, total) { if (!tipElement) createTip(); const container = getFullscreenContainer(); if (tipElement.parentElement !== container) { container.appendChild(tipElement); } const rect = video.getBoundingClientRect(); tipElement.textContent = `${formatTime(current)} / ${formatTime(total)}`; tipElement.style.left = '50%'; tipElement.style.transform = 'translate(-50%, 0)'; tipElement.style.top = rect.top + 60 + 'px'; tipElement.style.display = 'block'; } function hideTip() { if (tipElement) tipElement.style.display = 'none'; } function getActiveVideo() { const videos = document.querySelectorAll('video'); for (let v of videos) { if (!v.paused && !v.ended) return v; } return videos[0] || null; } document.addEventListener('touchstart', e => { if (!isFullscreen()) return; if (e.touches.length !== 1) return; currentVideo = getActiveVideo(); if (!currentVideo) return; isTouching = true; hasMoved = false; startX = e.touches[0].clientX; startY = e.touches[0].clientY; startVideoTime = currentVideo.currentTime; }, { passive: true }); document.addEventListener('touchmove', e => { if (!isFullscreen()) return; if (!isTouching || !currentVideo) return; if (e.touches.length !== 1) return; const nowX = e.touches[0].clientX; const nowY = e.touches[0].clientY; const diffX = Math.abs(nowX - startX); const diffY = Math.abs(nowY - startY); if (diffX < MIN_SWIPE_DISTANCE && diffY > MIN_SWIPE_DISTANCE) return; if (diffX > 3) hasMoved = true; const moveX = nowX - startX; const timeChange = moveX * SENSITIVITY; let newTime = startVideoTime + timeChange; newTime = Math.max(0, Math.min(newTime, currentVideo.duration)); currentVideo.currentTime = newTime; showTip(currentVideo, newTime, currentVideo.duration); e.preventDefault(); }, { passive: false }); document.addEventListener('touchend', e => { if (!isFullscreen()) return; if (!isTouching) return; if (hasMoved) { e.preventDefault(); e.stopPropagation(); } setTimeout(() => hideTip(), 150); isTouching = false; currentVideo = null; hasMoved = false; }); document.addEventListener('touchcancel', () => { if (!isFullscreen()) return; hideTip(); isTouching = false; currentVideo = null; hasMoved = false; }); })();