Naurok Auto Copy & Notify (Optimized Version)

Автокопирование вопросов, ответов и изображений без лагов

当前为 2025-02-21 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Naurok Auto Copy & Notify (Optimized Version)
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.3
  5. // @description Автокопирование вопросов, ответов и изображений без лагов
  6. // @author ENDERVANO
  7. // @license MIT
  8. // @match *://naurok.com.ua/test/testing/*
  9. // @grant GM_setClipboard
  10. // ==/UserScript==
  11.  
  12. (function () {
  13. 'use strict';
  14.  
  15. let lastQuestionText = ""; // Храним последний вопрос, чтобы не копировать дублирующийся
  16.  
  17. function addCopyButton() {
  18. let questionContainer = document.querySelector('.test-content-text');
  19. if (!questionContainer) return;
  20.  
  21. let questionElem = document.querySelector('.test-content-text-inner');
  22. let question = questionElem ? questionElem.innerText.trim() : "Вопрос не найден";
  23.  
  24. if (question === lastQuestionText) return; // Если вопрос не изменился — не перерисовываем кнопку
  25. lastQuestionText = question;
  26.  
  27. let oldButton = document.querySelector("#copyQuestionButton");
  28. if (oldButton) oldButton.remove();
  29.  
  30. let imageElem = document.querySelector('.test-content-image img');
  31. let imageUrl = imageElem ? imageElem.src : null;
  32. let imageText = imageUrl ? `\n[Изображение вопроса: ${imageUrl}]` : "";
  33.  
  34. let answerElems = document.querySelectorAll('.question-option-inner');
  35. let answers = [];
  36. let correctAnswers = [];
  37.  
  38. answerElems.forEach(el => {
  39. let textElem = el.querySelector('.question-option-inner-content');
  40. let imageElem = el.querySelector('.question-option-image');
  41.  
  42. let text = textElem ? textElem.innerText.trim() : "";
  43. let answerImage = imageElem ? imageElem.style.backgroundImage.replace(/url\(["']?(.*?)["']?\)/, '$1') : null;
  44.  
  45. if (text || answerImage) {
  46. let answerText = text ? text : `[Изображение ответа: ${answerImage}]`;
  47. answers.push(answerText);
  48. if (el.classList.contains('correct')) {
  49. correctAnswers.push(answerText);
  50. }
  51. }
  52. });
  53.  
  54. if (!questionElem || answers.length === 0) return;
  55.  
  56. let copyText = `❓ Вопрос: ${question}${imageText}\n\n🔹 Варианты ответов:\n${answers.join("\n")}`;
  57. if (correctAnswers.length > 0) {
  58. copyText += `\n\n Правильные ответы:\n${correctAnswers.join("\n")}`;
  59. }
  60.  
  61. let copyButton = document.createElement("button");
  62. copyButton.id = "copyQuestionButton";
  63. copyButton.innerText = "📋 Скопировать вопрос";
  64. copyButton.style.cssText = `
  65. padding: 12px 20px;
  66. margin-top: 15px;
  67. width: 100%;
  68. background: #007BFF;
  69. color: white;
  70. border: none;
  71. border-radius: 8px;
  72. cursor: pointer;
  73. font-size: 16px;
  74. font-weight: bold;
  75. text-align: center;
  76. transition: all 0.3s ease-in-out;
  77. box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
  78. `;
  79.  
  80. copyButton.onmouseover = () => copyButton.style.background = "#0056b3";
  81. copyButton.onmouseout = () => copyButton.style.background = "#007BFF";
  82.  
  83. copyButton.onclick = function () {
  84. GM_setClipboard(copyText, "text");
  85. showNotification("✅ Вопрос скопирован!", imageUrl);
  86. };
  87.  
  88. questionContainer.appendChild(copyButton);
  89. }
  90.  
  91. function showNotification(message, imageUrl) {
  92. let existingNotification = document.querySelector("#copyNotification");
  93. if (existingNotification) existingNotification.remove();
  94.  
  95. let notification = document.createElement("div");
  96. notification.id = "copyNotification";
  97. notification.style.cssText = `
  98. position: fixed;
  99. top: 20px;
  100. right: 20px;
  101. background: white;
  102. color: black;
  103. padding: 15px 20px;
  104. border-radius: 10px;
  105. box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.2);
  106. display: flex;
  107. align-items: center;
  108. font-size: 16px;
  109. font-weight: bold;
  110. z-index: 9999;
  111. opacity: 0;
  112. transform: translateX(50px);
  113. transition: opacity 0.3s ease, transform 0.3s ease;
  114. `;
  115.  
  116. let icon = document.createElement("img");
  117. icon.src = "https://cdn-icons-png.flaticon.com/512/190/190411.png";
  118. icon.style.cssText = "width: 30px; height: 30px; margin-right: 10px;";
  119.  
  120. let text = document.createElement("span");
  121. text.innerText = message;
  122.  
  123. notification.appendChild(icon);
  124. notification.appendChild(text);
  125.  
  126. if (imageUrl) {
  127. let image = document.createElement("img");
  128. image.src = imageUrl;
  129. image.style.cssText = "width: 40px; height: 40px; margin-left: 10px; border-radius: 5px;";
  130. notification.appendChild(image);
  131. }
  132.  
  133. document.body.appendChild(notification);
  134.  
  135. setTimeout(() => {
  136. notification.style.opacity = "1";
  137. notification.style.transform = "translateX(0)";
  138. }, 50);
  139.  
  140. setTimeout(() => {
  141. notification.style.opacity = "0";
  142. notification.style.transform = "translateX(50px)";
  143. setTimeout(() => notification.remove(), 300);
  144. }, 3000);
  145. }
  146.  
  147. function observeChanges() {
  148. const observer = new MutationObserver(() => {
  149. addCopyButton();
  150. });
  151.  
  152. observer.observe(document.querySelector('.question-container'), { childList: true, subtree: true });
  153. }
  154.  
  155. function main() {
  156. setTimeout(() => {
  157. addCopyButton();
  158. observeChanges();
  159. }, 3000);
  160. }
  161.  
  162. main();
  163. })();