Archive.org Enhancer

UI/UX tweaks for archive.org — dark mode, compact layout, sticky header, better downloads, cleaner search, sidebar toggle, and more.

  1. // ==UserScript==
  2. // @name Archive.org Enhancer
  3. // @namespace http://tampermonkey.net/
  4. // @version 3.0
  5. // @description UI/UX tweaks for archive.org — dark mode, compact layout, sticky header, better downloads, cleaner search, sidebar toggle, and more.
  6. // @author Eliminater74
  7. // @license MIT
  8. // @match https://archive.org/*
  9. // @grant GM_addStyle
  10. // ==/UserScript==
  11.  
  12. (function () {
  13. 'use strict';
  14.  
  15. const settings = {
  16. darkMode: localStorage.getItem('archive_darkMode') === 'true',
  17. compactMode: localStorage.getItem('archive_compactMode') === 'true',
  18. stickyHeader: localStorage.getItem('archive_stickyHeader') === 'true',
  19. autoExpandDownloads: localStorage.getItem('archive_autoExpandDownloads') === 'true',
  20. navShortcuts: localStorage.getItem('archive_navShortcuts') === 'true',
  21. hideSidebar: localStorage.getItem('archive_hideSidebar') === 'true',
  22. };
  23.  
  24. const saveSetting = (key, value) => {
  25. settings[key] = value;
  26. localStorage.setItem(`archive_${key}`, value);
  27. applySettings();
  28. updateMenuUI();
  29. };
  30.  
  31. const toggleSetting = (key) => saveSetting(key, !settings[key]);
  32.  
  33. const applySettings = () => {
  34. document.body.classList.toggle('dark-mode-enhancer', settings.darkMode);
  35. document.body.classList.toggle('compact-layout-enhancer', settings.compactMode);
  36. document.body.classList.toggle('sticky-header-enhancer', settings.stickyHeader);
  37. document.body.classList.toggle('hide-sidebar-enhancer', settings.hideSidebar);
  38.  
  39. if (settings.autoExpandDownloads) expandDownloadSection();
  40. injectScrollButtons();
  41. };
  42.  
  43. const expandDownloadSection = () => {
  44. const showAll = document.querySelector('.format-group-toggle');
  45. if (showAll && showAll.innerText.includes('Show All')) {
  46. showAll.click();
  47. }
  48. };
  49.  
  50. const injectScrollButtons = () => {
  51. let container = document.getElementById('scrollToButtons');
  52.  
  53. if (container) {
  54. container.style.display = settings.navShortcuts ? 'block' : 'none';
  55. return;
  56. }
  57.  
  58. if (!settings.navShortcuts) return;
  59.  
  60. container = document.createElement('div');
  61. container.id = 'scrollToButtons';
  62. container.innerHTML = `
  63. <button id="scrollToFilesBtn" title="Scroll to Files">📁 Files</button>
  64. <button id="scrollToReviewsBtn" title="Scroll to Reviews">📝 Reviews</button>
  65. `;
  66. document.body.appendChild(container);
  67.  
  68. document.getElementById('scrollToFilesBtn').onclick = () => {
  69. const files = document.querySelector('.download-options, #descript, [id*=file], [id*=download]');
  70. if (files) files.scrollIntoView({ behavior: 'smooth' });
  71. else alert('Files section not found on this page.');
  72. };
  73.  
  74. document.getElementById('scrollToReviewsBtn').onclick = () => {
  75. const reviews = document.querySelector('#reviews, .reviews, [id*=review]');
  76. if (reviews) reviews.scrollIntoView({ behavior: 'smooth' });
  77. else alert('Reviews section not found on this page.');
  78. };
  79. };
  80.  
  81. // --- UI Panel ---
  82. const gear = document.createElement('div');
  83. gear.innerHTML = '⚙️';
  84. gear.title = 'Archive Enhancer Settings';
  85. gear.id = 'archiveEnhancerGear';
  86. gear.addEventListener('click', () => {
  87. const menu = document.getElementById('archiveEnhancerMenu');
  88. menu.style.display = menu.style.display === 'block' ? 'none' : 'block';
  89. });
  90. document.body.appendChild(gear);
  91.  
  92. const menu = document.createElement('div');
  93. menu.id = 'archiveEnhancerMenu';
  94. menu.innerHTML = `
  95. <label><input type="checkbox" id="darkModeToggle"> Dark Mode</label><br>
  96. <label><input type="checkbox" id="compactModeToggle"> Compact Layout</label><br>
  97. <label><input type="checkbox" id="stickyHeaderToggle"> Sticky Header</label><br>
  98. <label><input type="checkbox" id="autoExpandToggle"> Auto Expand Downloads</label><br>
  99. <label><input type="checkbox" id="navShortcutsToggle"> Scroll Buttons</label><br>
  100. <label><input type="checkbox" id="hideSidebarToggle"> Hide Sidebar</label>
  101. `;
  102. document.body.appendChild(menu);
  103.  
  104. const updateMenuUI = () => {
  105. document.getElementById('darkModeToggle').checked = settings.darkMode;
  106. document.getElementById('compactModeToggle').checked = settings.compactMode;
  107. document.getElementById('stickyHeaderToggle').checked = settings.stickyHeader;
  108. document.getElementById('autoExpandToggle').checked = settings.autoExpandDownloads;
  109. document.getElementById('navShortcutsToggle').checked = settings.navShortcuts;
  110. document.getElementById('hideSidebarToggle').checked = settings.hideSidebar;
  111. };
  112.  
  113. // Event Listeners
  114. document.getElementById('darkModeToggle').addEventListener('change', () => toggleSetting('darkMode'));
  115. document.getElementById('compactModeToggle').addEventListener('change', () => toggleSetting('compactMode'));
  116. document.getElementById('stickyHeaderToggle').addEventListener('change', () => toggleSetting('stickyHeader'));
  117. document.getElementById('autoExpandToggle').addEventListener('change', () => toggleSetting('autoExpandDownloads'));
  118. document.getElementById('navShortcutsToggle').addEventListener('change', () => toggleSetting('navShortcuts'));
  119. document.getElementById('hideSidebarToggle').addEventListener('change', () => toggleSetting('hideSidebar'));
  120.  
  121. applySettings();
  122. updateMenuUI();
  123.  
  124. // --- Styles ---
  125. GM_addStyle(`
  126. #archiveEnhancerGear {
  127. position: fixed;
  128. bottom: 20px;
  129. right: 20px;
  130. background: #444;
  131. color: white;
  132. font-size: 18px;
  133. padding: 10px;
  134. border-radius: 50%;
  135. cursor: pointer;
  136. z-index: 10000;
  137. box-shadow: 0 0 5px black;
  138. }
  139. #archiveEnhancerMenu {
  140. display: none;
  141. position: fixed;
  142. bottom: 70px;
  143. right: 20px;
  144. background: #222;
  145. color: white;
  146. padding: 12px;
  147. border-radius: 10px;
  148. z-index: 10000;
  149. box-shadow: 0 0 10px black;
  150. font-size: 14px;
  151. }
  152. #archiveEnhancerMenu label {
  153. display: block;
  154. margin-bottom: 6px;
  155. }
  156. #scrollToButtons {
  157. position: fixed;
  158. bottom: 20px;
  159. left: 20px;
  160. z-index: 9999;
  161. }
  162. #scrollToButtons button {
  163. margin-right: 8px;
  164. background: #333;
  165. color: white;
  166. border: none;
  167. padding: 6px 10px;
  168. border-radius: 6px;
  169. cursor: pointer;
  170. }
  171. .dark-mode-enhancer {
  172. background: #121212 !important;
  173. color: #e0e0e0 !important;
  174. }
  175. .dark-mode-enhancer a {
  176. color: #80d8ff !important;
  177. }
  178. .compact-layout-enhancer * {
  179. font-size: 14px !important;
  180. line-height: 1.4 !important;
  181. }
  182. .sticky-header-enhancer header,
  183. .sticky-header-enhancer .site-header {
  184. position: sticky !important;
  185. top: 0 !important;
  186. z-index: 9999 !important;
  187. background-color: #222 !important;
  188. }
  189. .hide-sidebar-enhancer #nav,
  190. .hide-sidebar-enhancer .nav-menu {
  191. display: none !important;
  192. }
  193. /* Cleaner search */
  194. .results .C234,
  195. .results .C {
  196. padding: 6px !important;
  197. line-height: 1.4;
  198. }
  199. `);
  200. })();

QingJ © 2025

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