SiteBlocker

Block sites you want with your own description!

  1. // ==UserScript==
  2. // @name SiteBlocker
  3. // @namespace https://github.com/asmagaa/SiteBlock
  4. // @version 1.2
  5. // @description Block sites you want with your own description!
  6. // @author asmagaa
  7. // @match *://*/*
  8. // @grant GM_setValue
  9. // @grant GM_getValue
  10. // @grant GM_registerMenuCommand
  11. // @grant GM_deleteValue
  12. // @run-at document-idle
  13. // @license MIT
  14. // ==/UserScript==
  15.  
  16. (function() {
  17. 'use strict';
  18.  
  19. const BLOCK_LIST_KEY = 'siteblocker_blocklist';
  20. const TEMP_UNBLOCK_KEY = 'siteblocker_temp_unblock';
  21. const TEMP_UNBLOCK_DURATION = 15 * 60 * 1000;
  22.  
  23. const currentHost = window.location.hostname.replace(/^www\./, '');
  24.  
  25. const blockList = GM_getValue(BLOCK_LIST_KEY, {});
  26. const tempUnblockTime = GM_getValue(TEMP_UNBLOCK_KEY, 0);
  27.  
  28. const isTempUnblocked = tempUnblockTime && Date.now() < tempUnblockTime;
  29.  
  30. if (blockList[currentHost] && !isTempUnblocked) {
  31. renderBlockPage(blockList[currentHost]);
  32. } else {
  33. setTimeout(renderControlPanel, 3000);
  34. }
  35.  
  36. GM_registerMenuCommand('Manage Blocked Sites', openBlockListManager);
  37. GM_registerMenuCommand('Clear All Blocks', clearAllBlocks);
  38.  
  39. function renderBlockPage(message) {
  40. const scrollPosition = window.scrollY;
  41.  
  42. document.body.innerHTML = `
  43. <div style="
  44. position: fixed;
  45. top: 0;
  46. left: 0;
  47. width: 100%;
  48. height: 100%;
  49. background: #fff;
  50. z-index: 999999;
  51. display: flex;
  52. flex-direction: column;
  53. justify-content: center;
  54. align-items: center;
  55. padding: 20px;
  56. box-sizing: border-box;
  57. font-family: Arial, sans-serif;
  58. text-align: center;
  59. ">
  60. <div style="max-width: 600px;">
  61. <h1 style="color: #e74c3c; font-size: 2.5rem; margin-bottom: 20px;">
  62. <span style="font-size: 3rem;">🚫</span> Site Blocked
  63. </h1>
  64. <div style="
  65. background: #f9f9f9;
  66. border-left: 4px solid #e74c3c;
  67. padding: 15px;
  68. margin: 20px 0;
  69. text-align: left;
  70. ">
  71. <p style="margin: 0; font-size: 1.2rem;">${message || 'You blocked this site using SiteBlocker'}</p>
  72. </div>
  73. <div style="margin: 30px 0; display: flex; gap: 10px; flex-wrap: wrap; justify-content: center;">
  74. <button id="siteblock-unblock-btn" style="
  75. padding: 12px 25px;
  76. font-size: 1rem;
  77. background: #2ecc71;
  78. color: white;
  79. border: none;
  80. border-radius: 4px;
  81. cursor: pointer;
  82. font-weight: bold;
  83. ">
  84. Unblock for 15 Minutes
  85. </button>
  86. <button id="siteblock-manage-btn" style="
  87. padding: 12px 25px;
  88. font-size: 1rem;
  89. background: #3498db;
  90. color: white;
  91. border: none;
  92. border-radius: 4px;
  93. cursor: pointer;
  94. ">
  95. Manage Blocked Sites
  96. </button>
  97. </div>
  98. <div style="margin-top: 30px; color: #7f8c8d; font-size: 0.9rem;">
  99. <p>SiteBlocker is preventing you from accessing this site.</p>
  100. <p>You can temporarily unblock or manage your blocked sites.</p>
  101. </div>
  102. </div>
  103. </div>
  104. `;
  105.  
  106. window.scrollTo(0, scrollPosition);
  107.  
  108. document.getElementById('siteblock-unblock-btn').addEventListener('click', tempUnblock);
  109. document.getElementById('siteblock-manage-btn').addEventListener('click', openBlockListManager);
  110. }
  111.  
  112. function renderControlPanel() {
  113. if (document.getElementById('siteblock-control-panel')) return;
  114. const panel = document.createElement('div');
  115. panel.id = 'siteblock-control-panel';
  116. panel.style.cssText = `
  117. position: fixed;
  118. bottom: 20px;
  119. right: 20px;
  120. z-index: 999999;
  121. background: white;
  122. border-radius: 8px;
  123. box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
  124. padding: 20px;
  125. width: 300px;
  126. font-family: Arial, sans-serif;
  127. transition: transform 0.3s ease;
  128. `;
  129.  
  130. panel.innerHTML = `
  131. <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
  132. <h3 style="margin: 0; color: #2c3e50;">SiteBlocker</h3>
  133. <button id="siteblock-close-btn" style="
  134. background: none;
  135. border: none;
  136. font-size: 1.2rem;
  137. cursor: pointer;
  138. color: #7f8c8d;
  139. ">×</button>
  140. </div>
  141. <p style="margin-top: 0; margin-bottom: 15px;">
  142. Current site: <strong>${currentHost}</strong>
  143. </p>
  144. <textarea id="siteblock-reason" placeholder="Why do you want to block this site?"
  145. style="width: 100%; height: 80px; padding: 10px; margin-bottom: 15px; border: 1px solid #ddd; border-radius: 4px;"></textarea>
  146. <div style="display: flex; gap: 10px;">
  147. <button id="siteblock-block-btn" style="
  148. flex: 1;
  149. padding: 10px;
  150. background: #e74c3c;
  151. color: white;
  152. border: none;
  153. border-radius: 4px;
  154. cursor: pointer;
  155. font-weight: bold;
  156. ">Block This Site</button>
  157. </div>
  158. <div style="margin-top: 15px; text-align: center;">
  159. <button id="siteblock-manage-link" style="
  160. background: none;
  161. border: none;
  162. color: #3498db;
  163. cursor: pointer;
  164. font-size: 0.9rem;
  165. text-decoration: underline;
  166. ">Manage Blocked Sites</button>
  167. </div>
  168. `;
  169.  
  170. document.body.appendChild(panel);
  171.  
  172. document.getElementById('siteblock-close-btn').addEventListener('click', () => {
  173. panel.style.transform = 'translateY(150%)';
  174. setTimeout(() => panel.remove(), 300);
  175. });
  176.  
  177. document.getElementById('siteblock-block-btn').addEventListener('click', blockCurrentSite);
  178. document.getElementById('siteblock-manage-link').addEventListener('click', openBlockListManager);
  179. }
  180.  
  181. function blockCurrentSite() {
  182. const reason = document.getElementById('siteblock-reason').value || "Blocked by SiteBlocker";
  183. const blockList = GM_getValue(BLOCK_LIST_KEY, {});
  184.  
  185. blockList[currentHost] = reason;
  186. GM_setValue(BLOCK_LIST_KEY, blockList);
  187.  
  188. const panel = document.getElementById('siteblock-control-panel');
  189. if (panel) {
  190. panel.innerHTML = `
  191. <div style="padding: 20px; text-align: center;">
  192. <div style="font-size: 3rem; color: #2ecc71;">✓</div>
  193. <h3 style="color: #2ecc71;">Site Blocked!</h3>
  194. <p>${currentHost} has been added to your block list.</p>
  195. <p>Refresh the page to activate blocking.</p>
  196. </div>
  197. `;
  198. setTimeout(() => {
  199. if (panel.parentNode) panel.parentNode.removeChild(panel);
  200. }, 3000);
  201. }
  202. }
  203.  
  204. function tempUnblock() {
  205. const unblockTime = Date.now() + TEMP_UNBLOCK_DURATION;
  206. GM_setValue(TEMP_UNBLOCK_KEY, unblockTime);
  207. window.location.reload();
  208. }
  209.  
  210. function openBlockListManager() {
  211. const blockList = GM_getValue(BLOCK_LIST_KEY, {});
  212.  
  213. const existingManager = document.getElementById('siteblock-manager');
  214. if (existingManager) existingManager.remove();
  215. const manager = document.createElement('div');
  216. manager.id = 'siteblock-manager';
  217. manager.style.cssText = `
  218. position: fixed;
  219. top: 0;
  220. left: 0;
  221. width: 100%;
  222. height: 100%;
  223. background: rgba(0,0,0,0.7);
  224. z-index: 1000000;
  225. display: flex;
  226. justify-content: center;
  227. align-items: center;
  228. font-family: Arial, sans-serif;
  229. `;
  230.  
  231. const sites = Object.entries(blockList);
  232.  
  233. manager.innerHTML = `
  234. <div style="
  235. background: white;
  236. border-radius: 8px;
  237. width: 90%;
  238. max-width: 600px;
  239. max-height: 90vh;
  240. overflow: hidden;
  241. display: flex;
  242. flex-direction: column;
  243. ">
  244. <div style="padding: 20px; border-bottom: 1px solid #eee;">
  245. <h2 style="margin: 0; color: #2c3e50;">Blocked Sites Manager</h2>
  246. </div>
  247. <div style="flex: 1; overflow-y: auto; padding: 20px;">
  248. ${sites.length ? `
  249. <table style="width: 100%; border-collapse: collapse;">
  250. <thead>
  251. <tr style="background: #f8f9fa;">
  252. <th style="text-align: left; padding: 10px; border-bottom: 1px solid #eee;">Site</th>
  253. <th style="text-align: left; padding: 10px; border-bottom: 1px solid #eee;">Reason</th>
  254. <th style="width: 100px; border-bottom: 1px solid #eee;"></th>
  255. </tr>
  256. </thead>
  257. <tbody>
  258. ${sites.map(([site, reason]) => `
  259. <tr>
  260. <td style="padding: 10px; border-bottom: 1px solid #eee;">${site}</td>
  261. <td style="padding: 10px; border-bottom: 1px solid #eee;">${reason}</td>
  262. <td style="padding: 10px; border-bottom: 1px solid #eee; text-align: center;">
  263. <button data-site="${site}" class="siteblock-remove-btn" style="
  264. background: #e74c3c;
  265. color: white;
  266. border: none;
  267. border-radius: 4px;
  268. padding: 5px 10px;
  269. cursor: pointer;
  270. ">Remove</button>
  271. </td>
  272. </tr>
  273. `).join('')}
  274. </tbody>
  275. </table>
  276. ` : `
  277. <div style="text-align: center; padding: 40px 20px; color: #7f8c8d;">
  278. <p style="font-size: 1.2rem;">No sites blocked yet</p>
  279. <p>Add sites using the control panel</p>
  280. </div>
  281. `}
  282. </div>
  283. <div style="padding: 20px; display: flex; justify-content: space-between; border-top: 1px solid #eee;">
  284. <button id="siteblock-manager-close" style="
  285. padding: 10px 20px;
  286. background: #3498db;
  287. color: white;
  288. border: none;
  289. border-radius: 4px;
  290. cursor: pointer;
  291. ">Close</button>
  292. <button id="siteblock-clear-all" style="
  293. padding: 10px 20px;
  294. background: #e74c3c;
  295. color: white;
  296. border: none;
  297. border-radius: 4px;
  298. cursor: pointer;
  299. ">Clear All</button>
  300. </div>
  301. </div>
  302. `;
  303.  
  304. document.body.appendChild(manager);
  305.  
  306. document.getElementById('siteblock-manager-close').addEventListener('click', () => manager.remove());
  307. document.getElementById('siteblock-clear-all').addEventListener('click', clearAllBlocks);
  308.  
  309. document.querySelectorAll('.siteblock-remove-btn').forEach(btn => {
  310. btn.addEventListener('click', (e) => {
  311. const site = e.target.dataset.site;
  312. const blockList = GM_getValue(BLOCK_LIST_KEY, {});
  313. delete blockList[site];
  314. GM_setValue(BLOCK_LIST_KEY, blockList);
  315. e.target.closest('tr').remove();
  316.  
  317. if (Object.keys(blockList).length === 0) {
  318. const tbody = manager.querySelector('tbody');
  319. if (tbody) {
  320. tbody.innerHTML = `
  321. <tr>
  322. <td colspan="3" style="text-align: center; padding: 20px; color: #7f8c8d;">
  323. No blocked sites
  324. </td>
  325. </tr>
  326. `;
  327. }
  328. }
  329. });
  330. });
  331. }
  332.  
  333. function clearAllBlocks() {
  334. if (confirm('Are you sure you want to remove ALL blocked sites?')) {
  335. GM_setValue(BLOCK_LIST_KEY, {});
  336. const manager = document.getElementById('siteblock-manager');
  337. if (manager) manager.remove();
  338. alert('All blocked sites have been removed.');
  339. }
  340. }
  341. })();

QingJ © 2025

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