Greasy Fork镜像 支持简体中文。

推特url复制器1.0

懒人不想复制图片的时候也复制url,下版本考虑双击图片也直接复制了

  1. // ==UserScript==
  2. // @name 推特url复制器1.0
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.01
  5. // @description 懒人不想复制图片的时候也复制url,下版本考虑双击图片也直接复制了
  6. // @author Grok和deepseek喵
  7. // @match https://twitter.com/*
  8. // @match https://x.com/*
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. // 智能右键拦截策略
  17. document.addEventListener('contextmenu', function(e) {
  18. const img = e.target.closest('img:not([src*="/profile_images"])');
  19. if (img) {
  20. // 仅在图片右键时阻止默认菜单
  21. handleImageCopy(img);
  22. }
  23. }, { capture: true });
  24.  
  25. // 核心复制逻辑
  26. async function handleImageCopy(imgElement) {
  27. try {
  28. const url = await getOriginalStyleUrl(imgElement);
  29. await navigator.clipboard.writeText(url);
  30. showFeedback(`✓ 复制成功!: ${url}`);
  31. } catch (err) {
  32. showFeedback(`⚠️ 失败的man!: ${err.message}`, true);
  33. }
  34. }
  35.  
  36. // 经典模态框检测方法
  37. const getOriginalStyleUrl = (imgElement) => {
  38. return new Promise((resolve) => {
  39. // 优先使用原始模态框检测
  40. const modalLink = document.querySelector('div[aria-modal="true"] a[href*="/status/"][href*="/photo/"]');
  41. if (modalLink) {
  42. return resolve(modalLink.href);
  43. }
  44.  
  45. // 首页备用方案(保留原有智能提取)
  46. const container = imgElement.closest('article[data-testid="tweet"]');
  47. const statusLink = container?.querySelector('a[href*="/status/"][aria-label]');
  48. const tweetId = statusLink?.href.match(/\/status\/(\d+)/)?.[1];
  49. const username = container?.querySelector('a[href^="/"][role="link"]')?.pathname.split('/')[1];
  50.  
  51. if (tweetId && username) {
  52. resolve(`https://${location.host}/${username}/status/${tweetId}/photo/1`);
  53. } else {
  54. resolve(window.location.href);
  55. }
  56. });
  57. };
  58.  
  59. // 可视化反馈(优化版)
  60. const showFeedback = (() => {
  61. const style = document.createElement('style');
  62. style.textContent = `
  63. .url-copy-feedback {
  64. position: fixed;
  65. top: 20px;
  66. left: 50%;
  67. transform: translateX(-50%);
  68. background: rgba(15,20,25,0.95);
  69. color: rgb(255,255,255);
  70. padding: 12px 20px;
  71. border-radius: 8px;
  72. font-family: TwitterChirp, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  73. font-size: 14px;
  74. box-shadow: 0 3px 10px rgba(0,0,0,0.2);
  75. z-index: 99999;
  76. backdrop-filter: blur(4px);
  77. animation: feedbackSlide 0.3s ease-out, feedbackFade 2.5s forwards;
  78. white-space: nowrap;
  79. }
  80.  
  81. @keyframes feedbackSlide {
  82. from { top: -50px; opacity: 0; }
  83. to { top: 20px; opacity: 1; }
  84. }
  85.  
  86. @keyframes feedbackFade {
  87. 0%, 70% { opacity: 1; }
  88. 100% { opacity: 0; }
  89. }
  90. `;
  91. document.head.appendChild(style);
  92.  
  93. return (text, isError = false) => {
  94. const existing = document.querySelector('.url-copy-feedback');
  95. if (existing) existing.remove();
  96.  
  97. const div = document.createElement('div');
  98. div.className = 'url-copy-feedback';
  99. div.style.color = isError ? '#ff6b6b' : '#1da1f2';
  100. div.textContent = text;
  101.  
  102. document.body.appendChild(div);
  103. setTimeout(() => div.remove(), 2500);
  104. };
  105. })();
  106.  
  107. console.log('[精准复制器] 已激活');
  108. })();

QingJ © 2025

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