LeetCode 描述內容複製器

複製 LeetCode 題目描述內容到剪貼簿的輕巧按鈕。

// ==UserScript==
// @name         LeetCode 描述內容複製器
// @namespace    https://abc0922001.github.io/leetcode-userscripts
// @version      2.0
// @description  複製 LeetCode 題目描述內容到剪貼簿的輕巧按鈕。
// @author       abc0922001
// @match        https://leetcode.com/problems/*
// @grant        none
// @license      MIT
// ==/UserScript==

(() => {
  'use strict';

  /**
   * 等待指定元素出現後回傳該元素
   * @param {string} selector - CSS 選擇器
   * @param {number} timeout - 最長等待毫秒數
   * @returns {Promise<Element>}
   */
  function waitForElement(selector, timeout = 5000) {
    return new Promise((resolve, reject) => {
      const found = document.querySelector(selector);
      if (found) return resolve(found);

      const observer = new MutationObserver(() => {
        const el = document.querySelector(selector);
        if (el) {
          observer.disconnect();
          resolve(el);
        }
      });

      observer.observe(document.body, { childList: true, subtree: true });

      setTimeout(() => {
        observer.disconnect();
        reject(new Error(`等待元素 "${selector}" 超時 (${timeout}ms)`));
      }, timeout);
    });
  }

  /**
   * 顯示提示訊息
   * @param {string} message - 顯示內容
   */
  function showAlert(message) {
    window.alert(message);
  }

  /**
   * 將 HTML 內容複製至剪貼簿
   * @param {string} content - 要複製的 HTML
   */
  function copyToClipboard(content) {
    navigator.clipboard.writeText(content)
      .then(() => showAlert('✅ 描述內容已複製到剪貼簿!'))
      .catch(err => showAlert(`❌ 複製失敗:${err.message}`));
  }

  /**
   * 初始化按鈕並綁定點擊事件
   */
  function createCopyButton() {
    const button = document.createElement('button');
    button.textContent = '📋 複製描述';
    Object.assign(button.style, {
      position: 'fixed',
      top: '10px',
      right: '10px',
      zIndex: 1000,
      padding: '6px 10px',
      fontSize: '14px',
      backgroundColor: '#2b7de9',
      color: '#fff',
      border: 'none',
      borderRadius: '4px',
      cursor: 'pointer',
    });

    button.addEventListener('click', () => {
      const selector = 'div.elfjS[data-track-load="description_content"]';
      waitForElement(selector)
        .then(el => copyToClipboard(el.innerHTML))
        .catch(err => {
          showAlert('⚠️ 找不到描述內容區塊。');
          console.error(err);
        });
    });

    document.body.appendChild(button);
  }

  // 🚀 啟動腳本
  createCopyButton();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址