🏠 Home 

Greasy Fork is available in English.

Copy Genius Lyrics

Adds a button to copy lyrics from Genius.com


安装此脚本?
  1. // ==UserScript==
  2. // @name Copy Genius Lyrics
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.1
  5. // @description Adds a button to copy lyrics from Genius.com
  6. // @match https://genius.com/*
  7. // @grant GM_addStyle
  8. // @license MIT
  9. // ==/UserScript==
  10. (function () {
  11. 'use strict';
  12. /** Error logging */
  13. const logError = (error, context) => console.error(`[Copy Genius Lyrics] Error in ${context}:`, error);
  14. /** Copies lyrics to clipboard */
  15. const copyLyrics = () => {
  16. try {
  17. const lyrics = [...document.querySelectorAll('[data-lyrics-container="true"]')]
  18. .map(container => container.innerText.trim())
  19. .join('\n\n');
  20. if (!lyrics) {
  21. showNotification('No lyrics found.');
  22. return;
  23. }
  24. navigator.clipboard.writeText(lyrics)
  25. .then(() => showNotification('Lyrics copied!'))
  26. .catch(error => {
  27. logError(error, 'copyLyrics (clipboard)');
  28. showNotification('Failed to copy.');
  29. });
  30. } catch (error) {
  31. logError(error, 'copyLyrics');
  32. showNotification('An error occurred.');
  33. }
  34. };
  35. /** Displays a notification message */
  36. const showNotification = (message) => {
  37. try {
  38. const notification = document.createElement('div');
  39. notification.className = 'copy-lyrics-notification';
  40. notification.textContent = message;
  41. document.body.appendChild(notification);
  42. setTimeout(() => {
  43. notification.style.opacity = '0';
  44. setTimeout(() => notification.remove(), 500);
  45. }, 2000);
  46. } catch (error) {
  47. logError(error, 'showNotification');
  48. }
  49. };
  50. /** Initializes the copy button and injects it into the DOM */
  51. const initCopyButton = () => {
  52. try {
  53. const button = document.createElement('button');
  54. button.id = 'copy-lyrics-button';
  55. button.textContent = 'Copy Lyrics';
  56. button.addEventListener('click', copyLyrics);
  57. const targetContainer = document.querySelector('.dRuelM'); // Update if Genius changes its class names
  58. if (targetContainer) {
  59. targetContainer.appendChild(button);
  60. } else {
  61. logError('Target container not found (dRuelM)', 'DOM initialization');
  62. }
  63. } catch (error) {
  64. logError(error, 'initCopyButton');
  65. }
  66. };
  67. /** Injects custom styles for the button and notification */
  68. const injectStyles = () => {
  69. GM_addStyle(`
  70. #copy-lyrics-button {
  71. margin-top: 10px;
  72. padding: 10px 15px;
  73. font-size: 16px;
  74. background-color: #1db954;
  75. color: white;
  76. border: none;
  77. border-radius: 5px;
  78. box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  79. cursor: pointer;
  80. transition: background-color 0.2s ease-in-out;
  81. }
  82. #copy-lyrics-button:hover {
  83. background-color: #1ed760;
  84. }
  85. .copy-lyrics-notification {
  86. position: fixed;
  87. bottom: 20px;
  88. right: 20px;
  89. padding: 10px 20px;
  90. background-color: #1db954;
  91. color: white;
  92. font-size: 14px;
  93. border-radius: 5px;
  94. opacity: 0;
  95. animation: fadeInOut 2.5s forwards;
  96. z-index: 1000;
  97. }
  98. @keyframes fadeInOut {
  99. 0% { opacity: 0; transform: translateY(20px); }
  100. 10% { opacity: 1; transform: translateY(0); }
  101. 90% { opacity: 1; transform: translateY(0); }
  102. 100% { opacity: 0; transform: translateY(20px); }
  103. }
  104. `);
  105. };
  106. /** Initializes the script */
  107. const init = () => {
  108. injectStyles();
  109. initCopyButton();
  110. };
  111. // Run script after page load
  112. window.addEventListener('load', init);
  113. })();