Beanfun QR Code Click-to-Copy

在 beanfun! QR Code 登入頁面,點擊 QR Code 圖片時,自動複製其連結到剪貼簿。

  1. // ==UserScript==
  2. // @name Beanfun QR Code Click-to-Copy
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.7.1
  5. // @description 在 beanfun! QR Code 登入頁面,點擊 QR Code 圖片時,自動複製其連結到剪貼簿。
  6. // @author eunalice (Generated by Gemini 2.5 Pro)
  7. // @match *://*.beanfun.com/loginform.aspx*
  8. // @match *://tw.newlogin.beanfun.com/loginform.aspx*
  9. // @grant GM_setClipboard
  10. // @grant GM_addStyle
  11. // @run-at document-end
  12. // @license MIT
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18. const IFRAME_ID = 'ifmForm8';
  19. const QR_CODE_IMAGE_SELECTOR = '#theQrCodeImg';
  20. const PREFIX_TO_REMOVE = 'https://tw.newlogin.beanfun.com/qrhandler.ashx?u=';
  21. const NOTIFICATION_ID = 'gm-qr-copy-notify';
  22. const LISTENER_ADDED_FLAG = 'gm_qr_listener_added';
  23.  
  24. GM_addStyle(`
  25. #${NOTIFICATION_ID} {
  26. position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%);
  27. background-color: rgba(0, 0, 0, 0.8); color: white; padding: 10px 20px;
  28. border-radius: 5px; z-index: 10000; font-size: 14px;
  29. opacity: 0; transition: opacity 0.5s ease-in-out; pointer-events: none;
  30. }
  31. #${NOTIFICATION_ID}.visible { opacity: 1; }
  32. `);
  33.  
  34. function showNotification(message, duration = 3000) {
  35. let notify = document.getElementById(NOTIFICATION_ID);
  36. if (!notify) {
  37. notify = document.createElement('div');
  38. notify.id = NOTIFICATION_ID;
  39. document.body.appendChild(notify);
  40. }
  41. notify.textContent = message;
  42. notify.offsetHeight;
  43. notify.classList.add('visible');
  44. if (notify.timer) clearTimeout(notify.timer);
  45. notify.timer = setTimeout(() => {
  46. notify.classList.remove('visible');
  47. }, duration);
  48. }
  49.  
  50. function setupClickListener(targetIframe) {
  51. try {
  52. setTimeout(() => {
  53. const iframeDoc = targetIframe.contentDocument || targetIframe.contentWindow?.document;
  54. if (!iframeDoc) {
  55. return;
  56. }
  57.  
  58. const qrImageElement = iframeDoc.querySelector(QR_CODE_IMAGE_SELECTOR);
  59.  
  60. if (qrImageElement) {
  61. if (qrImageElement.dataset[LISTENER_ADDED_FLAG]) {
  62. return;
  63. }
  64.  
  65. qrImageElement.style.cursor = 'pointer';
  66. qrImageElement.title = '點擊以複製鏈結';
  67.  
  68. qrImageElement.addEventListener('click', (event) => {
  69. event.preventDefault();
  70. event.stopPropagation();
  71. event.stopImmediatePropagation();
  72.  
  73. let qrUrl = qrImageElement.src || qrImageElement.dataset.url;
  74.  
  75. if (qrUrl && String(qrUrl).trim()) {
  76. let originalUrl = String(qrUrl).trim();
  77. let finalValueToCopy = originalUrl;
  78.  
  79. if (PREFIX_TO_REMOVE && originalUrl.startsWith(PREFIX_TO_REMOVE)) {
  80. finalValueToCopy = originalUrl.substring(PREFIX_TO_REMOVE.length);
  81. }
  82.  
  83. GM_setClipboard(finalValueToCopy);
  84. showNotification('已複製鏈結!');
  85.  
  86. } else {
  87. showNotification('錯誤:無法從圖片獲取有效資料');
  88. }
  89. }, true);
  90.  
  91. qrImageElement.dataset[LISTENER_ADDED_FLAG] = 'true';
  92.  
  93. }
  94. }, 250);
  95.  
  96. } catch (e) {
  97. if (e.name === 'SecurityError') {
  98. showNotification('錯誤:無法設定點擊事件 (安全性限制)');
  99. } else {
  100. showNotification('設定點擊事件時發生錯誤');
  101. }
  102. }
  103. }
  104.  
  105. const checkInterval = setInterval(() => {
  106. const targetIframe = document.getElementById(IFRAME_ID);
  107. if (targetIframe) {
  108. clearInterval(checkInterval);
  109. targetIframe.addEventListener('load', () => setupClickListener(targetIframe));
  110. setupClickListener(targetIframe);
  111. }
  112. }, 500);
  113.  
  114. setTimeout(() => {
  115. clearInterval(checkInterval);
  116. }, 15000);
  117.  
  118. })();

QingJ © 2025

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