Copy URL

Copy a site's URL with a floating icon and a native context menu shortcut.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Copy URL
// @namespace    http://tampermonkey.net/
// @version      1.3
// @description  Copy a site's URL with a floating icon and a native context menu shortcut.
// @author       Earth1283
// @match        *://*/*
// @grant        GM_addStyle
// @grant        GM_registerMenuCommand
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // Style that floating window
    GM_addStyle(`
        /* Floating Clipboard Icon */
        #url-clipboard-icon {
            position: fixed;
            bottom: 20px;
            right: 20px;
            width: 48px; /* Small size */
            height: 48px;
            background-color: #3498db; /* Blue background */
            color: #ffffff; /* White text/icon */
            border-radius: 50%; /* Circular shape */
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: 'Inter', sans-serif; /* Modern font */
            font-size: 24px; /* Icon size */
            cursor: pointer;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); /* Subtle shadow */
            transition: background-color 0.3s ease, transform 0.1s ease; /* Smooth transitions */
            z-index: 9999; /* Ensure it's on top */
            user-select: none; /* Prevent text selection */
        }

        #url-clipboard-icon:hover {
            transform: scale(1.05); /* Slight scale on hover */
        }

        #url-clipboard-icon.copied {
            background-color: #2ecc71; /* Green background when copied */
        }

        /* Basic clipboard icon using a common unicode character */
        #url-clipboard-icon::before {
            content: '📋'; /* Clipboard emoji */
            display: block;
            line-height: 1; /* Adjust line height for vertical centering */
        }

        /* Checkmark icon using a common unicode character */
        #url-clipboard-icon.copied::before {
            content: '✅'; /* Checkmark emoji */
        }

        /* Confirmation Balloon Message */
        #clipboard-balloon {
            position: fixed;
            bottom: 80px; /* Position above the icon */
            right: 20px;
            background-color: #333; /* Dark background for the balloon */
            color: #ffffff; /* White text */
            padding: 8px 12px;
            border-radius: 8px; /* Rounded corners for the balloon */
            font-family: 'Inter', sans-serif;
            font-size: 14px;
            opacity: 0; /* Start hidden */
            visibility: hidden; /* Start hidden */
            transition: opacity 0.3s ease, visibility 0.3s ease; /* Smooth fade in/out */
            z-index: 9998; /* Below the icon but above page content */
            white-space: nowrap; /* Prevent text wrapping */
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
        }

        #clipboard-balloon.show {
            opacity: 1; /* Fade in */
            visibility: visible; /* Make visible */
        }
    `);

    // --- DOM Element Creation ---

    // Floating Clipboard Icon
    const clipboardIcon = document.createElement('div');
    clipboardIcon.id = 'url-clipboard-icon';
    document.body.appendChild(clipboardIcon);

    // Confirmation Balloon Message
    const clipboardBalloon = document.createElement('div');
    clipboardBalloon.id = 'clipboard-balloon';
    document.body.appendChild(clipboardBalloon);

    // --- Helper Functions ---

    /**
     * Copies the current URL to the clipboard and shows visual feedback.
     */
    function copyCurrentUrl() {
        const url = window.location.href;

        // Create a temporary textarea to copy the URL
        const tempTextArea = document.createElement('textarea');
        tempTextArea.value = url;
        document.body.appendChild(tempTextArea);
        tempTextArea.select();

        try {
            const successful = document.execCommand('copy');
            if (successful) {
                // Animate the floating icon to show success
                clipboardIcon.classList.add('copied');

                // Show the balloon message
                clipboardBalloon.textContent = '✅ Copied!';
                clipboardBalloon.classList.add('show');

                // Revert icon after 1.5 seconds
                setTimeout(() => {
                    clipboardIcon.classList.remove('copied');
                }, 1500);

                // Hide balloon after 1.5 seconds
                setTimeout(() => {
                    clipboardBalloon.classList.remove('show');
                }, 1500);
            } else {
                console.error('Failed to copy URL using document.execCommand.');
            }
        } catch (err) {
            console.error('Error copying URL:', err);
        } finally {
            // Clean up the temporary textarea
            document.body.removeChild(tempTextArea);
        }
    }

    // --- Event Listeners ---

    // Floating icon click listener
    clipboardIcon.addEventListener('click', copyCurrentUrl);

    // Register a menu command for the native browser context menu
    // The 'GM_registerMenuCommand' function is provided by Tampermonkey/Greasemonkey.
    // Not sure of any other compatibility
    // It adds an item to the browser's native context menu when the script is active.
    // The first argument is the text that will appear in the context menu.
    GM_registerMenuCommand('📋 Copy Current URL', copyCurrentUrl);

})();