Greasy Fork

Greasy Fork is available in English.

url-bar-plus 优化的自定义网址输入框 (滚动感知版)

在网页底部添加一个网址输入框,滚动到底部时自动隐藏,支持多行显示并自适应高度,使用快捷键Ctrl+K隐藏与显示

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

You will need to install an extension such as Tampermonkey to install this script.

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         url-bar-plus 优化的自定义网址输入框 (滚动感知版)
// @namespace    http://tampermonkey.net/
// @version      4.3
// @description  在网页底部添加一个网址输入框,滚动到底部时自动隐藏,支持多行显示并自适应高度,使用快捷键Ctrl+K隐藏与显示
// @author       cat (优化 by Assistant)
// @match        *://*/*
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // 样式定义
    const styles = `
        #custom-url-input {
            position: fixed;
            bottom: 0;
            left: 0;
            width: 100%;
            font-size: 16px;
            padding: 10px;
            border-top: 2px solid #ccc;
            background-color: rgba(249, 249, 249, 0.95);
            z-index: 10000;
            white-space: pre-wrap;
            overflow-wrap: break-word;
            overflow: hidden;
            min-height: 30px;
            max-height: 150px;
            transition: all 0.3s ease;
            box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
        }
        #custom-url-input:focus {
            outline: none;
            border-top-color: #007BFF;
        }
        #custom-url-input:hover {
            background-color: rgba(249, 249, 249, 1);
        }
        #custom-url-input-tooltip {
            position: fixed;
            bottom: 100%;
            left: 10px;
            background-color: #333;
            color: #fff;
            padding: 5px 10px;
            border-radius: 3px;
            font-size: 12px;
            display: none;
        }
    `;

    // 创建样式元素
    const styleElement = document.createElement('style');
    styleElement.textContent = styles;
    document.head.appendChild(styleElement);

    // 创建输入框
    const urlInput = document.createElement('div');
    urlInput.id = 'custom-url-input';
    urlInput.contentEditable = true;
    urlInput.innerHTML = colorizeUrl(window.location.href);
    document.body.appendChild(urlInput);

    // 创建提示框
    const tooltip = document.createElement('div');
    tooltip.id = 'custom-url-input-tooltip';
    tooltip.textContent = 'Ctrl+K: 显示/隐藏 | Enter: 跳转 | Shift+Enter: 换行';
    document.body.appendChild(tooltip);

    // 初始化显示状态
    urlInput.style.display = getCookie('urlInputDisplay') || 'block';

    // 事件监听器
    urlInput.addEventListener('keydown', handleKeyDown);
    urlInput.addEventListener('input', handleInput);
    urlInput.addEventListener('focus', () => tooltip.style.display = 'block');
    urlInput.addEventListener('blur', () => tooltip.style.display = 'none');
    window.addEventListener('popstate', updateUrl);
    document.addEventListener('keydown', handleGlobalKeyDown);

    // 新增:滚动事件监听器
    window.addEventListener('scroll', handleScroll);

    // 颜色化网址函数
    function colorizeUrl(url) {
        const parts = url.match(/^([^:]+:)(\/\/[^\/]+)(.*)/);
        if (!parts) return url;
        const [, protocol, host, path] = parts;
        return `<span style="color: #007BFF;">${protocol}</span>` +
               `<span style="color: #28A745;">${host}</span>` +
               `<span style="color: #DC3545;">${path}</span>`;
    }

    // 处理键盘事件
    function handleKeyDown(event) {
        if (event.key === 'Enter') {
            event.preventDefault();
            if (!event.shiftKey) {
                const newUrl = urlInput.innerText.trim();
                if (newUrl) {
                    window.location.href = newUrl;
                }
            } else {
                // Shift+Enter: 插入换行
                document.execCommand('insertLineBreak');
            }
            // 在每次按下回车键(无论是否有Shift)后更新颜色
            urlInput.innerHTML = colorizeUrl(urlInput.innerText);
        }
    }

    // 处理输入事件
    function handleInput() {
        adjustHeight(urlInput);
    }

    // 更新URL
    function updateUrl() {
        urlInput.innerHTML = colorizeUrl(window.location.href);
        adjustHeight(urlInput);
    }

    // 处理全局键盘事件
    function handleGlobalKeyDown(event) {
        if (event.ctrlKey && event.key === 'k') {
            event.preventDefault();
            toggleUrlInput();
        }
    }

    // 切换输入框显示状态
    function toggleUrlInput() {
        urlInput.style.display = urlInput.style.display === 'none' ? 'block' : 'none';
        setCookie('urlInputDisplay', urlInput.style.display);
        if (urlInput.style.display === 'block') {
            urlInput.focus();
        }
    }

    // 调整高度
    function adjustHeight(element) {
        element.style.height = 'auto';
        element.style.height = Math.min(element.scrollHeight, 150) + 'px';
    }

    // 设置 cookie
    function setCookie(name, value, days = 365) {
        const date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        const expires = `expires=${date.toUTCString()}`;
        document.cookie = `${name}=${value};${expires};path=/`;
    }

    // 获取 cookie
    function getCookie(name) {
        const cookieArr = document.cookie.split(';');
        for (let i = 0; i < cookieArr.length; i++) {
            const cookiePair = cookieArr[i].split('=');
            if (name === cookiePair[0].trim()) {
                return decodeURIComponent(cookiePair[1]);
            }
        }
        return null;
    }

    // 新增:处理滚动事件
    function handleScroll() {
        if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight - 10) {
            // 滚动到接近底部时隐藏输入框
            urlInput.style.display = 'none';
        } else if (getCookie('urlInputDisplay') === 'block') {
            // 如果不在底部,且之前状态为显示,则显示输入框
            urlInput.style.display = 'block';
        }
    }

    // 初始化
    adjustHeight(urlInput);
})();