Autosave form Inputs and Display 15-Item History

Autosaves and displays the last 15 entries of a single input field. Entries are saved on Enter or button click, and can be recovered or deleted.

目前为 2024-08-10 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Autosave form Inputs and Display 15-Item History
  3. // @namespace http://tampermonkey.net/
  4. // @version 2024-08-08
  5. // @description Autosaves and displays the last 15 entries of a single input field. Entries are saved on Enter or button click, and can be recovered or deleted.
  6. // @author Lawrence d'Aniello
  7. // @match https://example.com/* // Customize to match your target website
  8. // @license MIT
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. // Example selectors - change these to match the specific site
  16. const inputField = document.querySelector('input[type="text"]'); // Change CSS selector to match your input field
  17. const searchButton = document.querySelector('button'); // Change CSS selector to match your search button
  18.  
  19. inputField.setAttribute('autocomplete', 'off');
  20.  
  21. let savedInputEntries = JSON.parse(localStorage.getItem('savedInputEntries')) || [];
  22.  
  23. function updateSavedInputEntries(newEntry) {
  24. if (newEntry.trim() !== "" && !savedInputEntries.includes(newEntry)) {
  25. savedInputEntries.push(newEntry);
  26. if (savedInputEntries.length > 15) {
  27. savedInputEntries.shift();
  28. }
  29. localStorage.setItem('savedInputEntries', JSON.stringify(savedInputEntries));
  30. displaySavedInputEntries();
  31. }
  32. }
  33.  
  34. function deleteEntry(entryToDelete) {
  35. savedInputEntries = savedInputEntries.filter(entry => entry !== entryToDelete);
  36. localStorage.setItem('savedInputEntries', JSON.stringify(savedInputEntries));
  37. displaySavedInputEntries();
  38. }
  39.  
  40. function displaySavedInputEntries() {
  41. let existingDropdown = document.getElementById('savedInputEntriesDropdown');
  42. if (existingDropdown) {
  43. existingDropdown.remove();
  44. }
  45.  
  46. const dropdown = document.createElement('ul');
  47. dropdown.id = 'savedInputEntriesDropdown';
  48. dropdown.style.listStyleType = 'none';
  49. dropdown.style.padding = '5px';
  50. dropdown.style.border = '1px solid #ccc';
  51. dropdown.style.position = 'absolute';
  52. dropdown.style.backgroundColor = '#fff';
  53. dropdown.style.zIndex = '1000';
  54. dropdown.style.maxHeight = '150px';
  55. dropdown.style.overflowY = 'auto';
  56.  
  57. const inputRect = inputField.getBoundingClientRect();
  58. dropdown.style.left = `${inputRect.left}px`;
  59. dropdown.style.top = `${inputRect.bottom + window.scrollY}px`;
  60. dropdown.style.width = `${inputRect.width}px`;
  61.  
  62. const uniqueEntries = new Set(savedInputEntries);
  63.  
  64. Array.from(uniqueEntries).reverse().forEach(entry => {
  65. const listItem = document.createElement('li');
  66. listItem.style.display = 'flex';
  67. listItem.style.justifyContent = 'space-between';
  68. listItem.style.padding = '5px';
  69. listItem.style.cursor = 'pointer';
  70. listItem.style.position = 'relative';
  71. listItem.style.transition = 'background-color 0.3s, color 0.3s';
  72. listItem.textContent = entry;
  73.  
  74. // Hover styles
  75. listItem.addEventListener('mouseover', function() {
  76. listItem.style.backgroundColor = '#f0f0f0';
  77. listItem.style.color = '#333';
  78. deleteButton.style.display = 'inline';
  79. });
  80. listItem.addEventListener('mouseout', function() {
  81. listItem.style.backgroundColor = '#fff';
  82. listItem.style.color = '#000';
  83. deleteButton.style.display = 'none';
  84. });
  85.  
  86. const deleteButton = document.createElement('button');
  87. deleteButton.textContent = '✖';
  88. deleteButton.style.display = 'none';
  89. deleteButton.style.background = 'none';
  90. deleteButton.style.border = 'none';
  91. deleteButton.style.color = 'red';
  92. deleteButton.style.cursor = 'pointer';
  93. deleteButton.style.position = 'absolute';
  94. deleteButton.style.right = '10px';
  95. deleteButton.style.top = '50%';
  96. deleteButton.style.transform = 'translateY(-50%)';
  97. deleteButton.addEventListener('click', function(event) {
  98. event.stopPropagation();
  99. deleteEntry(entry);
  100. });
  101.  
  102. listItem.appendChild(deleteButton);
  103.  
  104. listItem.addEventListener('click', function() {
  105. inputField.value = entry;
  106. hideSavedInputEntries();
  107. inputField.focus();
  108. });
  109. dropdown.appendChild(listItem);
  110. });
  111.  
  112. document.body.appendChild(dropdown);
  113. }
  114.  
  115. function hideSavedInputEntries() {
  116. let existingDropdown = document.getElementById('savedInputEntriesDropdown');
  117. if (existingDropdown) {
  118. existingDropdown.remove();
  119. }
  120. }
  121.  
  122. function handleClick(event) {
  123. if (event.target !== inputField && !inputField.contains(event.target)) {
  124. hideSavedInputEntries();
  125. } else if (event.target === inputField) {
  126. displaySavedInputEntries();
  127. }
  128. }
  129.  
  130. inputField.addEventListener('focus', function() {
  131. // Debounce the display function to prevent flickering
  132. setTimeout(displaySavedInputEntries, 100);
  133. });
  134.  
  135. document.addEventListener('click', handleClick);
  136.  
  137. inputField.addEventListener('input', function() {
  138. hideSavedInputEntries();
  139. });
  140.  
  141. inputField.addEventListener('keydown', function(event) {
  142. if (event.key === 'Enter') {
  143. updateSavedInputEntries(inputField.value);
  144. hideSavedInputEntries();
  145. }
  146. });
  147.  
  148. searchButton.addEventListener('click', function() {
  149. updateSavedInputEntries(inputField.value);
  150. hideSavedInputEntries();
  151. });
  152.  
  153. window.addEventListener('resize', function() {
  154. let dropdown = document.getElementById('savedInputEntriesDropdown');
  155. if (dropdown) {
  156. const inputRect = inputField.getBoundingClientRect();
  157. dropdown.style.left = `${inputRect.left}px`;
  158. dropdown.style.top = `${inputRect.bottom + window.scrollY}px`;
  159. dropdown.style.width = `${inputRect.width}px`;
  160. }
  161. });
  162. })();