定时关闭网页

拖拽弹窗,滑块设置分钟+秒,右上角显示剩余时间

当前为 2025-08-18 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         定时关闭网页
// @namespace    https://github.com/yingchen6
// @version      1.8.6
// @description  拖拽弹窗,滑块设置分钟+秒,右上角显示剩余时间
// @author       yingchen6
// @match        *://*/*
// @grant        GM_registerMenuCommand
// @license MIT
// ==/UserScript==


(function() {
    'use strict';

    let timerId = null;
    let remainingSeconds = 0;
    let paused = false;
    let displayDiv = null;

    function formatTime(seconds){
        const m = Math.floor(seconds/60);
        const s = seconds%60;
        return `${m}:${s.toString().padStart(2,'0')}`;
    }

    function startCountdown(min, sec){
        remainingSeconds = min*60 + sec;
        paused = false;

        // 创建显示剩余时间的div
        if(!displayDiv){
            displayDiv = document.createElement("div");
            displayDiv.style.position = "fixed";
            displayDiv.style.top = "20px";
            displayDiv.style.right = "20px";
            displayDiv.style.background = "rgba(0,0,0,0.7)";
            displayDiv.style.color = "#fff";
            displayDiv.style.padding = "10px 15px";
            displayDiv.style.borderRadius = "8px";
            displayDiv.style.fontSize = "18px";
            displayDiv.style.zIndex = "999999";
            displayDiv.style.cursor = "default";
            displayDiv.style.userSelect = "none";

            // 时间文本
            const timeLabel = document.createElement("span");
            timeLabel.id = "timeLabelDisplay";
            timeLabel.textContent = formatTime(remainingSeconds);
            displayDiv.appendChild(timeLabel);

            // 暂停/继续按钮
            const pauseBtn = document.createElement("button");
            pauseBtn.textContent = "暂停";
            pauseBtn.style.marginLeft = "10px";
            pauseBtn.style.cursor = "pointer";
            pauseBtn.addEventListener("click", (e)=>{
                e.stopPropagation();
                paused = !paused;
                pauseBtn.textContent = paused ? "继续" : "暂停";
            });
            displayDiv.appendChild(pauseBtn);

            document.body.appendChild(displayDiv);

            // 双击修改时间
            displayDiv.addEventListener("dblclick", ()=>{
                const m = Math.floor(remainingSeconds/60);
                const s = remainingSeconds%60;
                showTimeSetting(m,s);
            });
        } else {
            const timeLabel = document.getElementById("timeLabelDisplay");
            timeLabel.textContent = formatTime(remainingSeconds);
            displayDiv.style.display = "block";
        }

        if(timerId) clearInterval(timerId);

        timerId = setInterval(()=>{
            if(!paused){
                remainingSeconds--;
                if(remainingSeconds <= 0){
                    clearInterval(timerId);
                    displayDiv.style.display = "none";
                    window.location.href="about:blank";
                    return;
                }
                const timeLabel = document.getElementById("timeLabelDisplay");
                timeLabel.textContent = formatTime(remainingSeconds);
            }
        },1000);
    }

    function showTimeSetting(defaultMin=30, defaultSec=0){
        const wrapper = document.createElement("div");
        wrapper.style.position = "fixed";
        wrapper.style.top = "50%";
        wrapper.style.left = "50%";
        wrapper.style.transform = "translate(-50%,-50%)";
        wrapper.style.background = "#222";
        wrapper.style.color = "#fff";
        wrapper.style.padding = "20px";
        wrapper.style.borderRadius = "10px";
        wrapper.style.boxShadow = "0 0 15px rgba(0,0,0,0.5)";
        wrapper.style.zIndex = "999999";
        wrapper.style.display = "flex";
        wrapper.style.flexDirection = "column";
        wrapper.style.alignItems = "center";
        wrapper.style.cursor = "move";

        wrapper.innerHTML = `
            <h3>设置倒计时</h3>
            <div style="margin-bottom:10px;">
                <label>分钟: <span id="minLabel">${defaultMin}</span></label>
                <input id="minRange" type="range" min="0" max="180" step="1" value="${defaultMin}" style="width:200px;">
            </div>
            <div style="margin-bottom:10px;">
                <label>秒: <span id="secLabel">${defaultSec}</span></label>
                <input id="secRange" type="range" min="0" max="59" step="1" value="${defaultSec}" style="width:200px;">
            </div>
            <div style="margin-top:10px;">
                <button id="confirmBtn">确定</button>
                <button id="cancelBtn">取消</button>
            </div>
        `;
        document.body.appendChild(wrapper);

        const minRange = wrapper.querySelector("#minRange");
        const secRange = wrapper.querySelector("#secRange");
        const minLabel = wrapper.querySelector("#minLabel");
        const secLabel = wrapper.querySelector("#secLabel");
        const confirmBtn = wrapper.querySelector("#confirmBtn");
        const cancelBtn = wrapper.querySelector("#cancelBtn");

        minRange.addEventListener("input", ()=>{ minLabel.textContent = minRange.value; });
        secRange.addEventListener("input", ()=>{ secLabel.textContent = secRange.value; });

        minRange.addEventListener("mousedown", e=>e.stopPropagation());
        secRange.addEventListener("mousedown", e=>e.stopPropagation());

        confirmBtn.addEventListener("click", ()=>{
            const m = parseInt(minRange.value);
            const s = parseInt(secRange.value);
            document.body.removeChild(wrapper);
            startCountdown(m,s);
        });

        cancelBtn.addEventListener("click", ()=>{ document.body.removeChild(wrapper); });

        // 弹窗拖拽
        let isDown=false, offsetX=0, offsetY=0;
        wrapper.addEventListener("mousedown", e=>{
            if(e.target.tagName==="INPUT" || e.target.tagName==="BUTTON") return;
            isDown=true;
            offsetX = e.clientX - wrapper.offsetLeft;
            offsetY = e.clientY - wrapper.offsetTop;
        });
        document.addEventListener("mousemove", e=>{
            if(isDown){
                wrapper.style.left = (e.clientX-offsetX)+"px";
                wrapper.style.top = (e.clientY-offsetY)+"px";
            }
        });
        document.addEventListener("mouseup", ()=>{ isDown=false; });
    }

    if(typeof GM_registerMenuCommand !== "undefined"){
        GM_registerMenuCommand("开始计时", ()=>{
            showTimeSetting();
        });
    }

})();