URL link with dragable layout

URL layout with drag function and double tap to copy with feedback

目前为 2025-03-19 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name URL link with dragable layout
  3. // @version 1.3
  4. // @description URL layout with drag function and double tap to copy with feedback
  5. // @author L.M.M
  6. // @match *://*/*
  7. // @grant none
  8. // @namespace https://greasyfork.org/users/1437292
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. window.addEventListener('load', function() {
  15. let urlBox = document.getElementById('urlOverlay');
  16. if (!urlBox) {
  17. urlBox = document.createElement('div');
  18. urlBox.id = 'urlOverlay';
  19. urlBox.style.position = 'fixed';
  20. urlBox.style.bottom = '10px';
  21. urlBox.style.right = '10px';
  22. urlBox.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
  23. urlBox.style.color = 'white';
  24. urlBox.style.padding = '5px 10px';
  25. urlBox.style.fontSize = '12px';
  26. urlBox.style.fontFamily = 'Arial, sans-serif';
  27. urlBox.style.zIndex = '9999';
  28. urlBox.style.borderRadius = '5px';
  29. urlBox.style.maxWidth = '50%';
  30. urlBox.style.wordWrap = 'break-word';
  31. urlBox.style.cursor = 'grab';
  32. urlBox.style.userSelect = 'none';
  33. document.body.appendChild(urlBox);
  34. }
  35.  
  36. let copyFeedback = document.createElement('div');
  37. copyFeedback.id = 'copyFeedback';
  38. copyFeedback.style.position = 'fixed';
  39. copyFeedback.style.bottom = '35px';
  40. copyFeedback.style.right = '10px';
  41. copyFeedback.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
  42. copyFeedback.style.color = 'white';
  43. copyFeedback.style.padding = '5px 10px';
  44. copyFeedback.style.fontSize = '12px';
  45. copyFeedback.style.fontFamily = 'Arial, sans-serif';
  46. copyFeedback.style.borderRadius = '5px';
  47. copyFeedback.style.zIndex = '10000';
  48. copyFeedback.style.display = 'none';
  49. copyFeedback.textContent = 'URL copied!';
  50. document.body.appendChild(copyFeedback);
  51.  
  52. function updateURL() {
  53. urlBox.textContent = window.location.href;
  54. }
  55.  
  56. function copyURL() {
  57. if (navigator.clipboard && navigator.clipboard.writeText) {
  58. navigator.clipboard.writeText(window.location.href).then(() => {
  59. showCopyFeedback();
  60. });
  61. }
  62. }
  63.  
  64. function showCopyFeedback() {
  65. copyFeedback.style.display = 'block';
  66. setTimeout(() => {
  67. copyFeedback.style.display = 'none';
  68. }, 1500);
  69. }
  70.  
  71. let isDragging = false;
  72. let startX, startY, initialTop, initialLeft;
  73. let lastTapTime = 0;
  74. const doubleTapThreshold = 300;
  75.  
  76. urlBox.addEventListener('touchstart', (e) => {
  77. e.preventDefault();
  78. const touch = e.touches[0];
  79. isDragging = true;
  80. urlBox.style.cursor = 'grabbing';
  81. startX = touch.clientX;
  82. startY = touch.clientY;
  83. const rect = urlBox.getBoundingClientRect();
  84. initialTop = rect.top;
  85. initialLeft = rect.left;
  86. });
  87.  
  88. urlBox.addEventListener('touchmove', (e) => {
  89. if (!isDragging) return;
  90. e.preventDefault();
  91. const touch = e.touches[0];
  92. const deltaX = touch.clientX - startX;
  93. const deltaY = touch.clientY - startY;
  94. urlBox.style.top = `${initialTop + deltaY}px`;
  95. urlBox.style.left = `${initialLeft + deltaX}px`;
  96. urlBox.style.bottom = 'auto';
  97. urlBox.style.right = 'auto';
  98.  
  99. copyFeedback.style.top = `${initialTop + deltaY - 30}px`;
  100. copyFeedback.style.left = `${initialLeft + deltaX}px`;
  101. copyFeedback.style.bottom = 'auto';
  102. copyFeedback.style.right = 'auto';
  103. });
  104.  
  105. urlBox.addEventListener('touchend', (e) => {
  106. if (isDragging) {
  107. isDragging = false;
  108. urlBox.style.cursor = 'grab';
  109. const touch = e.changedTouches[0];
  110. const deltaX = Math.abs(touch.clientX - startX);
  111. const deltaY = Math.abs(touch.clientY - startY);
  112.  
  113. if (deltaX < 5 && deltaY < 5) {
  114. const currentTime = new Date().getTime();
  115. if (currentTime - lastTapTime < doubleTapThreshold) {
  116. copyURL();
  117. }
  118. lastTapTime = currentTime;
  119. }
  120. }
  121. });
  122.  
  123. updateURL();
  124.  
  125. const observer = new MutationObserver(() => {
  126. if (urlBox.textContent !== window.location.href) {
  127. updateURL();
  128. }
  129. });
  130.  
  131. observer.observe(document.body, { childList: true, subtree: true });
  132.  
  133. window.addEventListener('popstate', updateURL);
  134. window.addEventListener('hashchange', updateURL);
  135. });
  136. })();