返回首頁 

Greasy Fork is available in English.

⭐网页瞬间加载/跳过进度条直接加载网页(附重定向链接优化)⭐

任何链接内容跳过进度条秒加载,并优化删除重定向链接(解决95%的重定向问题,如知乎,微博等),所有参数可高度自定义


ติดตั้งสคริปต์นี้?
สคริปต์ที่แนะนำของผู้เขียน

คุณอาจชื่นชอบ 🌙 高级定制网页护眼模式🌙


ติดตั้งสคริปต์นี้
// ==UserScript==// @name         ⭐网页瞬间加载/跳过进度条直接加载网页(附重定向链接优化)⭐// @namespace    fenda// @version      1.0.15// @description  任何链接内容跳过进度条秒加载,并优化删除重定向链接(解决95%的重定向问题,如知乎,微博等),所有参数可高度自定义// @icon         data:image/png;base64,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###N6yZUsHQrGLp6enLsYYbwIlGixlQBuT2rn4ZQsDAOt8Zb1FIYWTYJT4TUND5G1//vOff3+SRMNlg8/iKZk39dbWbU02E1cqha5GiDQbwpolA7YvdM3t4HAHmBAzV9aMCNYbYyrVebM6fRCcZkJbMzzuIkLUAYTFd6PRhocbGujPToUAsO7ubb1C8At9z78AY7pbKRwx5lWS2QdAdAx0hax1qLwUzdyVMO4ysy0JyZVFyY8jDfZl+/b96all486T8OJqAwBv2tT3HuGLmyl11kohs+tT5sfkVlgIzH+wPACAoESJAQGYBIVUU5SgLyKivrRqlfPHvXtPuTRB1t29rdP3vRdJid8phDjbsmwqhES5SnPWbLrQIDy9RBIDABAhUlo2/XUkGn39n//8h1PWa1xVAPT17bwwEU8+JAW2YZeCBZIoEHtKI6C4/duE+5rLVE5wvbSSUvyWUPuyiYlDvzrVj2r48k2btq+VyLvJS6cvw5gxxqzMaZC7jIsBAJiJzVkAYdcCOY71nUi05e+feeaJUzKatFoAYO3t289X0n8AKdwmZSZNEUoFaudOhnVz6ucULhNSSAcwLlaTBCOELxQS+yiin7d8+enBmcGJ0tA6pe4g3d1bnpd2fQggPA9j0ggONsGNhQ2usAc6/N8FT9cwaXLSSk2KKSHII5R9lrL0zYcPH4aiXafUVRUArFvXczaS5AHG2G6lJM6JpykSe1MwsKyoFQgWgyPB/TRC6qvUsv9ldPT02PWLcVt3d/fGZFK8hhB8o8/lBkadjCXHhGAUCsMoDwDGd6KBpMM8MOKCx52o+tCRIwfuPNVyjqsBAGvjhu5vCE5fSjDTpUko08EzZu0ydn8tvJQ4AfJFoOzJIZAQbtx27OuESHxxbGysXktTEwdiqw5tsSx1v+fJFzh2VG8++QF9ZZ/A+tlAlwD2N3nXYL0TKpFsamq8ZGBg7yOn0hGwKAC0te1q4N7kXYSSdxBiZUK5jAQZXMV2o6JEBNETwoQQOLEISrtpHxP1G8bU9UePHvnpqUT8an3L+vW9bUjJW5RUf08pa9EppGB/0PVLTQpl/lXIHneCp3ku84wgrAjyhT9EKPq70dF9vzxVdK7FAMBetWrjpRa172LMZkEc/3yJKWUtuF4ZU+1AS/ycfxlj+qGJicN/OlWIXhYdKrxp3br+RqUSFyGlrseY9AURtqZS44nLXBYAgjlAoB62YFUEF6n/kIpdOjGx70iFU6zJ2xcMgNbWjhdQzP43IdZmXa8GwmxDMTqVngDadq3N/MD4###e6zKL/ZPryk/PnH6K7kKZha5f332OEvJjjFnPNfnT2Ujb8KCVAgDM0JBZhhD3EFUfGRk5cMtCJ1lLzy0IAJDDm06ph5Ci5xNiGeWrMJ3L+tYg2woCsxDioHRBOY/bx8eHPq5/qF8VUaCzc/N/813+GanQ2Yw6WGfaCR0XlQ0bqWRE7X6BqFUwQQvEuesTxl4yNnYARNKTEURYyWwrunchAGDtG7pukYrchJFFId5cV2jT0ZcLo0XgudQOGOyNYkJuU8r7/MjICCi79WsBFNi+/ayzZqdn75TSeqlSChp+aJ0g63WvYNBMCRatI2T6HwghnlEYX3D8+EGoRrdir4oBsHHjlpcrKR7WYQ6KZiIWMUKQLKUtCOH6+BlAmLomOUTS0dD6J9NEIqOoDWHsvn3NmubvnQqhDMvNFZs393cJD33Q9byLhODacTYXlBIsRyZBaE7cD+q16x+C9QMnjMlHgP9BIS7f9ySX8kGErKtWciW6igDQ2rpjo1Kprzu2/Reg9C5ww9ekBasCiE1QrlwqD+LSjyGsLh4dPfqd5WacU+n9u3bt6pidTj2YTLkvAUUWysT7HkfUyjoiiyUelaSDkpMKy7eMjh78fyXvrdEbygYAhDdPTCSvVJK8DyES0/tDpjDtQr5NJ2QgoUUnn6cmbEreu7q15cH6zr8Qas7/zPbtz9oan5190PPkuRiBkyZzYmceWygAQ###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###m+ET4Bi6bLBPa6bRpFo5LxjxwZqpm4o7ti0Q/m+TmCfW4xKAUAI9uOJ6avi8bFP1Vqw04rgsBqf5MaNZ+5QMv0djEnnYgHQsqrxbw8devprtfLJuH3jNgVaek5IayjUtZQIZBQi6cUTU1fE48c/XQdArSxt9eYBvQQwdr5HMOkupAMWEoHy+Qlmk06nUEOjc/HQ0L5/rd7sFjeSBkAg1xWy8ZYDAKWkl0jWAbC4pajdp9ev79yCkP39hQIgMJV6Xhph5L/7+OSxT9bK1+KNG7aq/PIn84tAmW7wmS/QZfKQ8BKJ6foJUCurWuV5tLR0bXYc9n2Cac9CToBAwvC5h1x35opEYupjVZ7igofTAMh/uigAdIM7jqCdDpTLMKcDJMJ4GQBMQpxHqeraC55s/cHloUBLS3evbZMfUMIWBQDPd5GXnr0ikTolAGC8gdAhUCrXSyRmrojHJ+s6wPLw6JK+VQOAkR9QxnrgReFToJgVKKwDBCJQIhlHDPPLJmfGPrGkE65g8EWcAHkASM9cEZ+uA6AC2q+YWwEAjk1+QBZ4AgQ6puulkcPQ20bGBz9bKx+vzaCc8xz3dnkiUKb/L4hEhPvp1MyVMzOT/1K3AtXK0lZvHptaN2/1CfouwbRroScAPAd+gMYG+w2Dw/u/VL3ZLW6kOU9wWWbQHB1Ax0VBa0xEqOSeN3vtxMT4x+sAWNyC1OLTPT39ZyeT3jcJxpsWogQHz6RSSdTcEn35kSMD36mV78TdXSYUAjRXU9snN9TVyPmBkyysBEPlL4ykhPwBLj0vcdvU1PgdkAJaKx9Xn0d1KHDWWc99wdjY5CNI4fULBQA8B34ATNRzpqaGf1edmS1+FNzdvV2l02ldyQtryw7UczElsYMrNxxaV83SgIEgOFM/XiIpvM/GGsnltRTqunjy1EcACmze###vE/H0ZzEmq7K930wFoKwSnGf/C9XVCXSAZDKufJ7akk5PH6gVyuK+vjNVPB7XZk1dzk43TJ4PANmpByCBD/Q89/8xK/2mekJ8rSxt9ebR2tr1dkrZPUiRmAmYzGYLlpMPENwzNT0pKcWbEomxY9Wb3eJGws973nnf279//4sYs7EugloAAIXivcMnBDg6hPB/IiR+1fT04cnFTan+dI1RgHZ29l3v++pWpIgdzgUINspS+QBwn06JTKcmbMfrqaVNEre3dz/b8+SvKGU2NEqGytCBHlDuQkBTNKn4sELynOPHB2uuAGq531G/70QKtLe3xyiNfNT38NuVMkpioSZ5wW/hEYyOaDLGNABc97HZ2aHnQ63EWqE1bmpq3eo4zn8x5kRBBKoEAMFuYKrC+UmF8TkTE4f/WCsfV5/H4imwffv2tVNT8c9Iab0aCieXCwDY9UF3BMYP/pyamnzE8ydeu/hZVW8EvGrVxm5K8U8ikYYuCbnwQc3bgu1Qc1+cDZ42AnaCAAAgAElEQVTTnWGUFOKSseOHaybSr3pkOn1HOuOMMzYnk/4j3Ce7g/CXck6ALAAACFj3jBPC/8DU1NAttURNvGFD3zql/IcxYi8kxM5Yf4x1J7gKl73LusShErAQElkM3Tc8su/yWvrA+lwWR4GNG7fvxkg+qhTSPoBShbEC3VBXUsTBCaBQ2ptFjNILxseHv7G4GVX3abxmzZpmRCKftkj0Iqwrw5mmBsXNoNkJzIVRg+lUIoSJ+MOx0f3PqSUZr7rkOv1Ga2/b+lqF0L8qpOZ6Bwc6YjiKOH+T1G22MNUbIyECeTzucV/smp0d31tLVMQI9dtr187e6tiRG4SA0tCm0V34KlYWJeeUUAQRKjyJxLZjxw4erKWPrM9l4RTo7T7zI6mke63CxjQOvFBMBAq/JQwAjDniMnlwQnnPQhMTMwufTfWf1EbdlpaN/+g40XsoiUQqKY4bng6cAK6XRI1NziVHjuz7fPWnWh9xGShA2zds+ZkU5HmYGv9QKREomGMAALjf52kom/m9iYmjUBSrpiIFMg0ytpzPuXzQYtG2BQFAd4kE4clHmPIvHDt2BMrfQYHR+rWCKdDV1bXZ99jvlKTN+V1Dw87SYn4A3V4VOJ5DeXT3nqmpo9fUWqxYpkXSjjMx5l/FiG0HNi63PPrc2uoGeVD/0YW4oKdsB798cLDuD1jBvK+n3tO1+QrPQ/coXTQ5t2VQaQCYBtv6PsS5lOl3j48PfabWEqb0V61b198oZfzrjNovwZjpiYPiUsklJfg2BOK+O9bS1PSW/Yf//M1Knq/fW2sU6HM2bvC/rRQ+DyMGFo6cCZYGQLZLpOe7RzEmrx8fP/ijWvvKANZk3bqeDyBEboTqcAYAuYpwqYmDMwxjCIwTPmH4w6tXN9y+Z88er9Rz9X+vTQqc0dN/9kx89vuMOWuEtvAtDAAKccS59xvHib1haOjpZ2rta+fOtfb2vpe6rvtty4pikOfzvrf0vLUYJOG4QwTL7znRxjcePLinZoKeSn9A/Y4QBUh7+5arhC/uwJha2gOcy/9ldIjJVJFGXAnBH1Yq8vbx8b011zloDgCrVvWsolQMMGavhSK5RqQxVzEzaJhl###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###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###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###UbuzQCck0OhPNVKL0uSuF4L9uaIy9tQ6AZVjc+ivLo4AOoOPkau7xq4SQjTqjLGMdCncLna+PW9C7ABqgQK5AZvd/jFB81ejo8C/rAChvLep3LRMFwERKiPMuIRDkGDdCVXutvIY4txQATJd6TzO/FP6TCJOLx8aGfw9ugToAlmlh668tnwKQVCMEvdZ1xQ0EWzFwkoUjHuYFAAHRCdovpRXn7u8dh/310NDQYPD2OgDKX4f6nctIAbAOJZPoOu6LKyGU2ngHskAwpRMhuSwouwLBdSb0AbrvSOX/ilJ8xbFjx34dLklfB8AyLmr91ZVRoK1tVwOlqUu5z2/GmDabGqRBWXYzlgEA2PnBkyZ0YxKl5H9hgt85MjIEzJ/Jw8zcX9kU6nfXKbC8FABxKJ1G7xFCvo8xKyZE4NE1sT44E/UJBbO4SEOliN9HouwVR44cOVqoGUn9BFje9ay/fQEUAI+xlOy9lNIrEaJRCHSbq0eqJSGJPJ6WCPHfEEr/cWxs6L+KvaYOgAUsQP2R5acAlGFEyHkXQuh6QqzVBFs6ghRMnVx4iHPvCWbhK8bGhn8xXx+nOgCWfy3rM1ggBaAC3eysd6sQ6EaEKAYfAYj4FiMpRPj/OHRoQJs65xv+/weJLzuZ42brBwAAAABJRU5ErkJggg==// @author       fenda// @match        *://*/*// @grant        GM_getValue// @grant        GM_setValue// @grant        GM_registerMenuCommand// @run-at       document-end// @license      MPL-2.0// ==/UserScript==(function() {'use strict';/*** 添加一个新的样式标签到文档的头部,如果已有同名ID的标签则不执行添加。** @param {string} styleId - 样式标签的ID,用于检查是否已经存在具有相同ID的样式。* @param {string} cssRules - 要添加的CSS规则的字符串表示,用于设置style标签的内容。*/function addStyle(styleId, cssRules) {if (!document.getElementById(styleId)) {const style = document.createElement('style');style.id = styleId;style.setAttribute('type', 'text/css');style.innerHTML = cssRules;document.head.appendChild(style);}}function createElementWithStylesAndAttributes(tag, styles, attributes) {let element = document.createElement(tag);if (styles) {Object.assign(element.style, styles);}if (attributes) {for (const key in attributes) {if (attributes.hasOwnProperty(key)) {if (key in element) {element[key] = attributes[key];} else {element.setAttribute(key, attributes[key]);}}}}return element;}/* ------------------------------- 以下是脚本的设置面板函数 ------------------------------- *//*** 主动画循环。*/function animate() {if (loadingPanel.style.display === 'block') {stats.update();}requestAnimationFrame(animate);}/*** 检查是否有更新。*/function checkForUpdates() {var lastCheckedTime = GM_getValue('lastCheckedTime', 0);var currentTime = Date.now();if (currentTime - lastCheckedTime >= 3600000) {GM_setValue('lastCheckedTime', currentTime);var updateURL = "https://update.greasyfork.org/scripts/493851/%E2%AD%90%E7%BD%91%E9%A1%B5%E7%9E%AC%E9%97%B4%E5%8A%A0%E8%BD%BD%E8%B7%B3%E8%BF%87%E8%BF%9B%E5%BA%A6%E6%9D%A1%E7%9B%B4%E6%8E%A5%E5%8A%A0%E8%BD%BD%E7%BD%91%E9%A1%B5%E2%AD%90.meta.js";fetch(updateURL).then(function(response) {response.text().then(function(text) {var latestVersion = text.match(/@version\s+([^\n]+)/)[1];if (latestVersion) {GM_setValue('latestVersion', latestVersion);}});}).catch(function(error) {console.error('An error occurred while checking for updates:', error);});}}/*** 创建特性列表项。** @param {Array} features - 特性描述列表。* @returns {Array} - 转换为HTML元素列表的数组。*/function createFeatureListItems(features) {return features.map(feature => {let parts = feature.split(',').map(part => part.trim());let listItem = createElementWithStylesAndAttributes('div', { width: '85px', height: '32px', lineHeight: '32px', backgroundColor: '#E0E5EC', margin: '3px 0', borderRadius: '5px', boxShadow: 'inset 2px 2px 4px #BECBD8, inset -2px -2px 4px #FFFFFF', textAlign: 'center', userSelect: 'none', whiteSpace: 'nowrap', fontSize: '14px', }, { innerText: parts[0] });let featureContainer = createElementWithStylesAndAttributes('div', { display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: 'calc(100% - 6px)', marginTop: '3px', marginLeft: '3px', marginRight: '3px', boxSizing: 'border-box' });featureContainer.appendChild(listItem);if (parts.includes('information')) {function parseMarkdown(mdText) {let htmlText = mdText;htmlText = htmlText.replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>"); // 加粗htmlText = htmlText.replace(/\*(.*?)\*/g, "<em>$1</em>"); // 斜体htmlText = htmlText.replace(/##(.*?)\n/g, "<h2>$1</h2>"); // 标题htmlText = htmlText.replace(/\n/g, "<br>"); // 换行htmlText = htmlText.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank">$1</a>'); // 链接return htmlText;}let infoIcon = createElementWithStylesAndAttributes("div", { position: 'relative', cursor: 'pointer', display: 'flex', alignItems: 'left', justifyContent: 'center' }, { innerHTML: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg>` });let infoBox = createElementWithStylesAndAttributes("div", { width: "300px", height: "auto", overflow: "auto", display: "none", position: "absolute", transform: "translateX(-50%)", backgroundColor: "#E0E5EC", borderRadius: "12px", boxShadow: "2px 2px 4px #AEBEC7, -2px -2px 4px #FFFFFF", zIndex: "2000" });let parsedContent = parseMarkdown(parts[4]);let infoText = createElementWithStylesAndAttributes("div", { padding: "10px", margin: "0", fontSize: "15px", fontWeight: "bold", textAlign: "left", textShadow: "2px 2px 3px rgba(0, 0, 0, 0.2)", color: "#4B5563" }, { innerHTML: parsedContent });infoBox.appendChild(infoText);document.body.appendChild(infoBox);document.addEventListener('mousemove', function(e) {const mouseX = e.pageX;const mouseY = e.pageY;const offsetX = 20;const offsetY = 20;infoBox.style.left = `${mouseX + offsetX}px`;infoBox.style.top = `${mouseY + offsetY}px`;});featureContainer.appendChild(infoIcon);infoIcon.addEventListener('mouseover', function() {infoBox.style.display = 'block';});infoIcon.addEventListener('mouseout', function() {infoBox.style.display = 'none';});}if (parts.includes('styleSelector')) {addStyle("neumorphic-checkbox-style", `.neumorphic-checkbox { -webkit-appearance: none; appearance: none; background-color: #e0e5ec; margin: 0; font: inherit; color: currentColor; width: 30px; height: 30px; border: 2px solid #d1d9e6; border-radius: 4px; transform: translateY(-0.075em); display: grid; place-content: center; }.neumorphic-checkbox { background-color: #ff3b3b; /* red for false */ }.neumorphic-checkbox:checked { background-color: #3bff3b; /* green for true */ border-color: #28a745; box-shadow: inset 3px 3px 5px #b8c4d8, inset -3px -3px 5px #ffffff; }.neumorphic-checkbox + span { vertical-align: middle; }`);let Selector = GM_getValue(parts[6]);let styleSelectorCheckbox = createElementWithStylesAndAttributes("input", {}, {type: "checkbox",checked: Selector || false,className: "neumorphic-checkbox"});styleSelectorCheckbox.addEventListener("change", function() {GM_setValue(parts[6], styleSelectorCheckbox.checked);// 将背景颜色设置为红色或绿色取决于复选框的状态styleSelectorCheckbox.style.backgroundColor = styleSelectorCheckbox.checked ? '#3bff3b' : '#ff3b3b';});// 设置初始背景颜色styleSelectorCheckbox.style.backgroundColor = Selector ? '#3bff3b' : '#ff3b3b';let checkboxContainer = createElementWithStylesAndAttributes("label", { display: 'flex', alignItems: 'center', justifyContent: 'space-between' });checkboxContainer.appendChild(styleSelectorCheckbox);featureContainer.appendChild(checkboxContainer);};if (parts.includes('settingButton')) {const settingButtonContainer = createElementWithStylesAndAttributes('div', { display: 'flex', alignItems: 'center', justifyContent: 'center', width: '80px', height: '32px', margin: '5px 0' });const settingButton = createElementWithStylesAndAttributes('div', { cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', width: '24px', height: '24px', }, { innerHTML: `<svg xmlns="http://www.w3.org/2000/svg" height="1.5em" fill="currentColor" viewBox="0 0 512 512"><path d="M 188 37 Q 192 20 205 10 L 205 10 Q 218 0 235 0 L 277 0 Q 294 0 307 10 Q 320 20 324 37 L 332 71 L 333 71 L 363 53 Q 378 44 394 46 Q 410 48 422 60 L 452 90 Q 464 102 466 118 Q 468 134 459 149 L 441 179 L 441 180 L 475 188 Q 492 192 502 205 Q 512 218 512 235 L 512 277 Q 512 294 502 307 Q 492 320 475 324 L 441 332 L 441 333 L 459 363 Q 468 378 466 394 Q 464 410 452 422 L 422 452 Q 410 464 394 466 Q 378 468 363 459 L 333 441 L 332 441 L 324 475 Q 319 492 307 502 Q 294 512 277 512 L 235 512 Q 218 512 205 502 Q 192 492 188 475 L 180 441 L 179 441 L 149 459 Q 134 468 118 466 Q 102 464 90 452 L 60 422 Q 48 410 46 394 Q 44 378 53 363 L 72 333 L 71 332 L 37 324 Q 20 320 10 307 Q 0 294 0 277 L 0 235 Q 0 218 10 205 Q 20 192 37 188 L 71 180 L 71 179 L 53 149 Q 44 134 46 118 Q 48 102 60 90 L 90 60 Q 102 48 118 46 Q 134 44 149 53 L 179 72 L 180 71 L 188 37 L 188 37 Z M 277 48 L 235 48 L 224 95 Q 220 107 208 112 Q 198 115 188 120 Q 176 125 165 119 L 124 94 L 94 124 L 119 165 Q 126 176 120 188 Q 115 198 112 208 Q 107 220 95 224 L 48 235 L 48 277 L 95 288 Q 107 292 112 304 Q 115 314 120 324 Q 125 336 119 347 L 94 388 L 124 418 L 165 393 Q 176 387 188 392 Q 198 397 208 400 Q 220 405 224 417 L 235 464 L 277 464 L 288 417 Q 292 405 304 400 Q 314 397 324 392 Q 336 387 347 393 L 388 418 L 418 388 L 393 347 Q 387 336 392 324 Q 397 314 400 304 Q 405 292 417 288 L 464 277 L 464 235 L 417 224 Q 405 220 400 208 Q 397 198 392 188 Q 387 176 393 165 L 418 124 L 388 94 L 347 119 Q 336 126 324 120 Q 314 115 304 112 Q 292 107 288 95 L 277 48 L 277 48 Z M 292 163 L 260 355 Q 255 373 237 372 Q 219 367 220 349 L 252 157 Q 257 139 275 140 Q 293 145 292 163 L 292 163 Z M 198 230 L 172 256 L 198 282 Q 210 296 198 310 Q 184 322 170 310 L 130 270 Q 118 256 130 242 L 170 202 Q 184 190 198 202 Q 210 216 198 230 L 198 230 Z M 342 202 L 382 242 Q 394 256 382 270 L 342 310 Q 328 322 314 310 Q 302 296 314 282 L 340 256 L 314 230 Q 302 216 314 202 Q 328 190 342 202 L 342 202 Z" /></svg>` });settingButton.addEventListener('click', function() {document.body.style.overflow = 'hidden';const settingParametersPanel = createElementWithStylesAndAttributes('div', { display: 'none', position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', flexDirection: 'column', background: '#E0E5EC', border: '1px solid #BECBD8', borderRadius: '10px', boxShadow: '2px 2px 8px #BECBD8, -2px -2px 8px #FFFFFF', width: '300px', height: '300px', zIndex: '1500' });const settingTitle = createElementWithStylesAndAttributes('div', { fontSize: '16px', fontWeight: 'bold', margin: '10px 0', textAlign: 'center' }, { innerHTML: '重定向调试菜单' });const settingOptions = createElementWithStylesAndAttributes('div', { userSelect: 'none', fontSize: '14px', padding: '10px', textAlign: 'left', whiteSpace: 'nowrap', display: 'flex', flexDirection: 'column', justifyContent: 'space-between', position: 'relative' });const siteLinksOption = createElementWithStylesAndAttributes('div', { cursor: 'pointer', fontSize: '14px', padding: '10px', textAlign: 'left', whiteSpace: 'nowrap', borderBottom: '1px solid #BECBD8' }, { innerHTML: '本站链接' });const parametersOption = createElementWithStylesAndAttributes('div', { cursor: 'pointer', fontSize: '14px', padding: '10px', textAlign: 'left', whiteSpace: 'nowrap' }, { innerHTML: '参数设置' });let count = 1;let preloadedLinks = GM_getValue('preloadedLinks', []);const settingInputBox = createElementWithStylesAndAttributes('div', { fontSize: '13px', id: 'redirectConversionLinks', padding: '10px', flex: '1 1', height: '230px', resize: 'none', borderRadius: '10px', boxShadow: 'inset 2px 2px 4px #a3b1c6, inset -2px -2px 4px #ffffff', overflow: 'auto' }, { innerHTML: preloadedLinks.map(linkData => { return `<div class="styledPanel"> <strong>${count++}.</strong> <br>原链接:${linkData.url} <br>优化后:${linkData.optimizedUrl || linkData.url} <br>重定向参数: ${linkData.redirectParameter} </div> `; }).join('') });addStyle('customDisplayStyles', ` .styledPanel { width: 100%; margin: 5px 0; padding: 10px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); white-space: pre-line; /* 允许长单词换行 */ word-wrap: break-word; } `);const settingOptionsContainer = createElementWithStylesAndAttributes('div', { display: 'flex', flexDirection: 'row', overflow: 'hidden', alignItems: 'top', marginRight: '15px' });const settingCloseButton = createElementWithStylesAndAttributes('div', { cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', width: '24px', height: '24px', position: 'absolute', top: '0', right: '0', margin: '10px 0 20px 10px' }, { innerHTML: `<svg xmlns="http://www.w3.org/2000/svg" height="1em" fill="currentColor" viewBox="0 0 334 334"><path d="M 320 48 Q 334 31 320 14 Q 303 0 286 14 L 167 133 L 48 14 Q 31 0 14 14 Q 0 31 14 48 L 133 167 L 14 286 Q 0 303 14 320 Q 31 334 48 320 L 167 201 L 286 320 Q 303 334 320 320 Q 334 303 320 286 L 201 167 L 320 48 L 320 48 Z" /></svg>` });settingOptionsContainer.appendChild(settingOptions);settingOptionsContainer.appendChild(settingInputBox);settingParametersPanel.appendChild(settingTitle);settingParametersPanel.appendChild(settingOptionsContainer);settingParametersPanel.appendChild(settingCloseButton);document.body.appendChild(settingParametersPanel);settingCloseButton.addEventListener('click', function() {const newQueryItemsText = document.getElementById('queryItemsList').value.split(',');console.log(newQueryItemsText);if (newQueryItemsText) {GM_setValue('queryItemsList', newQueryItemsText);showAlert("重定向参数保存成功");console.log(GM_getValue('queryItemsList'));} else {showAlert("请确保输入参数后再保存!");}settingParametersPanel.style.display = 'none';document.body.style.overflow = 'auto';});const originalContent = settingInputBox.innerHTML;siteLinksOption.addEventListener('click', function() {settingInputBox.innerHTML = originalContent;});parametersOption.addEventListener('click', function() {settingInputBox.innerHTML = '';console.log(GM_getValue('queryItemsList'));const joinQueryItems = GM_getValue('queryItemsList').join(',');settingInputBox.innerHTML = `<textarea id="queryItemsList" class="styledPanel" style="height: calc(100% - 20px); width: calc(100%-10px); overflow: auto ;">${joinQueryItems}</textarea>`;});settingParametersPanel.style.display = 'flex';settingOptions.appendChild(siteLinksOption);settingOptions.appendChild(parametersOption);});settingButtonContainer.appendChild(settingButton);featureContainer.appendChild(settingButtonContainer);}parts.slice(1).forEach((componentType, idx) => {let component;let defaultValue;switch (componentType) {case 'numberPicker':defaultValue = GM_getValue(parts[idx + 2]);component = createUIComponent('numberPicker', { value: defaultValue, min: 0, max: 100, step: 1, key: parts[idx + 2] });break;case 'inputBox':defaultValue = GM_getValue(parts[idx + 2]);component = createUIComponent('inputBox', { type: 'text', value: defaultValue, key: parts[idx + 2] });break;case 'selector':defaultValue = GM_getValue(parts[idx + 2]);component = createUIComponent('selector', { options: optionsArray, key: parts[idx + 2] });break;case 'switch':defaultValue = GM_getValue(parts[idx + 2]);component = createUIComponent('switch', { checked: defaultValue, key: parts[idx + 2] });break;case 'shortcutKeySetting':defaultValue = GM_getValue(parts[idx + 2]);component = createUIComponent('shortcutKeySetting', { value: defaultValue, key: parts[idx + 2] });break;default:break;}if (component) {featureContainer.appendChild(component);}});return featureContainer;});}/*** 创建并初始化特色功能面板。** @param {string} id - 该面板的HTML元素ID。* @param {number} translateX - 初始移动位置的距离。* @returns {HTMLElement} - 创建的特色功能面板元素。*/function createShowcaseFeaturesPanel(id, translateX) {let showcaseFeatures = createElementWithStylesAndAttributes('div', { position: "absolute", width: "250px", height: "270px", borderRadius: "15px", display: "flex", alignItems: "flex-start", flexDirection: "column", justifyContent: "flex-start", background: "#E0E5EC", boxShadow: "2px 2px 8px #BECBD8, -2px -2px 8px #FFFFFF", transition: "transform 0.5s ease", transform: `translateX(${translateX}px)`, overflow: "hidden" });showcaseFeatures.id = id;return showcaseFeatures;}/*** 创建不同的UI组件。** @param {string} type - 组件类型。* @param {Object} options - 用于创建组件的选项。* @param {string} [options.value] - 组件的当前值。* @param {Object} options.min - 组件的最小值。* @param {Object} options.max - 组件的最大值。* @param {Object} options.step - 组件的步长值。* @param {Array} options.options - 下拉选项。* @param {boolean} options.checked - 开关的选中状态。* @returns {HTMLElement} - 相应类型的行内UI组件。*/function createUIComponent(type, options, ) {if (type === 'switch') {addStyle('optimized-switch-style', `.optimizedswitchcontainer input[type="checkbox"] {  width: 0; height: 0; opacity: 0; }.optimizedswitchcontainer { position: relative; display: inline-block; width: 34px; height: 14px; }.optimizedswitchslider { position: absolute; cursor: pointer; top: 0; bottom: 0; left: 0; right: 0; background-color: #ccc; transition: .4s; }.optimizedswitchslider:before { position: absolute; content: ""; height: 20px; width: 20px; left: 0; bottom: -3px; background-color: white; transition: .4s; box-shadow: 0 2px 5px rgba(0,0,0,0.3); }.optimizedswitchcontainer input:checked + .optimizedswitchslider { background-color: #00FF00; }.optimizedswitchcontainer input:focus + .optimizedswitchslider { box-shadow: 0 0 1px #2196F3; }.optimizedswitchcontainer input:checked + .optimizedswitchslider:before { transform: translateX(18px); }`);let switchContainer = createElementWithStylesAndAttributes("label", {}, {className: "optimizedswitchcontainer"});let switchInput = createElementWithStylesAndAttributes("input", {}, {type: "checkbox",checked: options.checked || false,});switchInput.addEventListener("change", function() {GM_setValue(options.key, this.checked);});let switchSlider = createElementWithStylesAndAttributes("span", {}, {className: "optimizedswitchslider"});switchContainer.appendChild(switchInput);switchContainer.appendChild(switchSlider);return switchContainer;} else if (type === 'inputBox') {addStyle("neumorphic-style",`.neu-display-box { font-size: 14px; background: #e0e5ec; border-radius: 10px; box-shadow: 2px 2px 4px #a3b1c6, -2px -2px 4px #ffffff; transition: all 0.3s; display: flex; justify-content: center; align-items: center; cursor: pointer; width: 80px; height: 30px; overflow: hidden; white-space: nowrap; }.neu-input-modal { width: 200px;height: 300px; display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #e0e5ec; border-radius: 10px; box-shadow: 2px 2px 4px #a3b1c6, -2px -2px 4px #ffffff; width: 280px; box-sizing: border-box; justify-content: center; align-items: center; flex-direction: column;z-index: 1500; }.neu-text-input, .button-row button { border: none; background: none; outline: none; }.neu-text-input { padding: 10px;width: 250px; height: 200px; resize: none; margin-bottom: 10px; border-radius: 10px; box-shadow: inset 2px 2px 4px #a3b1c6, inset -2px -2px 4px #ffffff; }.button-row { display: flex; justify-content: space-between; width: calc(100% - 34px); }.button-row button { width: 95px; cursor: pointer; background: #e0e5ec; border-radius: 5px;  box-shadow: 2px 2px 4px #a3b1c6, -2px -2px 4px #ffffff; }.button-row button:hover { box-shadow: inset 2px 2px 4px #a3b1c6, inset -2px -2px 4px #ffffff; }`);let modal = createElementWithStylesAndAttributes("div", {}, {className: "neu-input-modal",});let textInput = createElementWithStylesAndAttributes("textarea", {}, {className: "neu-text-input",value: GM_getValue(options.key) || "",});let valueDisplay = options.value.join(',').length > 5 ? options.value.join(',').substring(0, 5) + '...' : options.value.join(',') || "点击输入";let displayBox = createElementWithStylesAndAttributes("div", { id: "displayBox" }, {className: "neu-display-box",innerHTML: valueDisplay,onclick: function() {modal.style.display = 'flex';textInput.focus();var textLength = textInput.value.length;textInput.setSelectionRange(textLength, textLength);}});let buttonRow = createElementWithStylesAndAttributes("div", {}, {className: "button-row",});let saveButton = createElementWithStylesAndAttributes("button", {}, {innerHTML: '保存',onclick: function() {modal.style.display = 'none';let userInput = textInput.value.trim();let userDomains = userInput ? userInput.split(',') : [];GM_setValue(options.key, userDomains);updateDomainLists();displayBox.textContent = userDomains.join(',').length > 5 ? userDomains.join(',').substring(0, 5) + '...' : userDomains.join(',') || "点击输入";showAlert('域名已保存!');}});let addDomainButton = createElementWithStylesAndAttributes("button", {}, {innerHTML: '添加当前域名到输入框',onclick: function() {var domain = window.location.hostname;var domainList = GM_getValue(options.key, []);if (!domainList.includes(domain)) {domainList.push(domain);GM_setValue(options.key, domainList);updateDomainLists();modal.style.display = 'none';textInput.value = domainList.join(',');displayBox.textContent = domainList.join(',').length > 5 ? domainList.join(',').substring(0, 5) + '...' : domainList.join(',');showAlert('域名已保存!');} else {showAlert('域名已存在!');}}});buttonRow.appendChild(saveButton);buttonRow.appendChild(addDomainButton);modal.appendChild(textInput);modal.appendChild(buttonRow);document.body.appendChild(modal);return displayBox;} else if (type === 'selector') {addStyle("neumorphic-selector-modal-style",`.neu-selector-display {  font-size: 14px; line-height: 32px;height: 32px; width: 80px; background: #e0e5ec; border-radius: 10px; box-shadow: 2px 2px 4px #a3b1c6, -2px -2px 4px #ffffff;cursor: pointer; user-select: none; position: relative; text-align: center; }.neu-selector-modal { display: none; position: absolute; background: #e0e5ec; box-shadow: 2px 2px 4px #a3b1c6, -2px -2px 4px #ffffff; border-radius: 10px; z-index: 1000; flex-direction: column; }.neu-selector-modal-open { display: flex; }.neu-selector-option { font-size: 18px;margin-bottom: 2px;white-space: nowrap; cursor: pointer; user-select: none; text-align: center; width: 70px; box-sizing: border-box; }.neu-selector-option:hover { background-color: #d1d9e6; }`);let selectorDisplay = createElementWithStylesAndAttributes("div", {}, {className: "neu-selector-display"});let modal = createElementWithStylesAndAttributes("div", {}, {className: "neu-selector-modal"});let container = document.createElement("div");container.style.position = "relative";function selectOption(option) {GM_setValue(options.key, option);selectorDisplay.textContent = GM_getValue(options.key);modal.className = "neu-selector-modal";}optionsArray.forEach((option) => {let optionElement = createElementWithStylesAndAttributes("div", {}, {className: "neu-selector-option",textContent: option,onclick: () => selectOption(option)});modal.appendChild(optionElement);});selectorDisplay.addEventListener("click", function(event) {event.stopPropagation();modal.className = modal.className.includes("neu-selector-modal-open") ? "neu-selector-modal" : "neu-selector-modal neu-selector-modal-open";let modalRect = modal.getBoundingClientRect();modal.style.left = `-${selectorDisplay.offsetWidth}px`;modal.style.top = `${(selectorDisplay.offsetHeight - modalRect.height) / 2}px`;});document.addEventListener("click", function() {modal.className = "neu-selector-modal";});container.appendChild(selectorDisplay);container.appendChild(modal);selectorDisplay.textContent = GM_getValue(options.key);return container;} else if (type === 'shortcutKeySetting') {addStyle("shortcutKeySetting-style", `.shortcutKeySetting-displayBox { width: 80px; height: 32px; overflow:auto ;background: #e0e5ec; border-radius: 5px; box-shadow: inset 2px 2px 4px #BECBD8, inset -2px -2px 4px #FFFFFF; border: none;  margin: 5px 0; flex: 1; text-align: center; outline: none; width: 80px; }.shortcutKeySetting-button { width: 60px; height: 32px; margin-left: 10px; background: #e0e5ec; border-radius: 10px; box-shadow: 2px 2px 4px #a3b1c6, -2px -2px 4px #ffffff; border: none; cursor: pointer; user-select: none; }.shortcutKeySetting-container { display: flex; justify-content: space-between; align-items: center; box-sizing: border-box;  }`);let container = createElementWithStylesAndAttributes('div', {}, {className: "shortcutKeySetting-container"});let shortcutKeyValue = GM_getValue(options.key);let displayPlaceholder = shortcutKeyValue ? shortcutKeyValue.toUpperCase() : '快捷键';let displayBox = createElementWithStylesAndAttributes('input', {}, {type: 'text',readOnly: true,placeholder: displayPlaceholder,className: "shortcutKeySetting-displayBox"});let setButton = createElementWithStylesAndAttributes('button', {}, {innerText: '设定',className: "shortcutKeySetting-button"});setButton.addEventListener('click', function() {displayBox.value = '按下任意键...';displayBox.disabled = false;let keySequence = [];let keyDownEvent = function(event) {event.preventDefault();let key = event.key.toLowerCase();if (!keySequence.includes(key)) {keySequence.push(key);displayBox.value = keySequence.join('+').toUpperCase();GM_setValue(options.key, keySequence.join('+'));console.log(GM_getValue(options.key));}};let keyUpEvent = function() {document.removeEventListener('keydown', keyDownEvent);displayBox.disabled = true;document.removeEventListener('keyup', keyUpEvent);};document.addEventListener('keydown', keyDownEvent);document.addEventListener('keyup', keyUpEvent);});container.appendChild(displayBox);container.appendChild(setButton);return container;} else if (type === 'numberPicker') {addStyle("neumorphic-numberPicker-style",`.neu-numberPicker-container { max-width: 121px;width: 100%; height: 32px; display: flex; align-items: center; justify-content: space-between; background: #e0e5ec; border-radius: 10px; box-shadow: 2px 2px 4px #a3b1c6, -2px -2px 4px #ffffff; }.neu-numberPicker-button { background: #e0e5ec; border: none; border-radius: 100%; box-shadow: 2px 2px 4px #a3b1c6, -2px -2px 4px #ffffff; width: 30px; height: 30px; cursor: pointer; font-size: 15px; display: flex; align-items: center; justify-content: center; user-select: none; min-width: 30px;}.neu-numberPicker-button:active {box-shadow: inset 2px 2px 4px #a3b1c6, inset -2px -2px 4px #ffffff; }.neu-numberPicker-value {width: 40px; text-align: center; font-size: 16px; background: transparent; border: none; outline: none; margin: 0 auto;}`);let container = createElementWithStylesAndAttributes("div", {}, {className: "neu-numberPicker-container"});let intervalId = null;const updateValue = (increment) => {let currentValue = parseInt(valueDisplay.value, 10) || 0;let newValue = increment ? currentValue + 1 : currentValue - 1;if (newValue < 1) {newValue = 1; // 最小值限制showAlert('亲,“1”难道还不够小嘛');}valueDisplay.value = newValue;GM_setValue(options.key, valueDisplay.value);};const createContinuousButton = (innerHTML, increment) => {let button = createElementWithStylesAndAttributes("button", {}, {innerHTML: innerHTML,className: "neu-numberPicker-button"});button.addEventListener("mousedown", function() {updateValue(increment);intervalId = setInterval(() => updateValue(increment), 200);});['mouseup', 'mouseleave'].forEach(event => {button.addEventListener(event, function() {clearInterval(intervalId);});});return button;};let currentValue = GM_getValue(options.key, 0);let valueDisplay = createElementWithStylesAndAttributes("input", {}, {type: "text",value: currentValue,className: "neu-numberPicker-value",oninput: function() {this.value = this.value.replace(/[^0-9]/g, '');GM_setValue(options.key, this.value);}});let minusButton = createContinuousButton('➖', false);let plusButton = createContinuousButton('➕', true);container.appendChild(minusButton);container.appendChild(valueDisplay);container.appendChild(plusButton);return container;} else {throw new Error('不支持的UI组件类型');}}/*** 创建显示版本信息的元素,并添加到页面中。** @returns {HTMLElement} - 包含版本信息和更新日志按钮的元素。*/function createVersionInfoElement() {const versionInfo = createElementWithStylesAndAttributes('div', {position: 'relative',left: '20px',width: 'auto',bottom: `5px`,fontSize: '10px',color: '#666',display: 'flex',marginTop: '10px',});const currentVersion = '1.0.15';versionInfo.innerHTML = `<strong>当前版本:${currentVersion}(最新版本:${GM_getValue('latestVersion', '1.0.15')})</strong>`;const updateLogButton = document.createElement('button');updateLogButton.innerHTML = '更新日志';updateLogButton.style.cssText = 'display: flex; flex-direction: row; flex-wrap: wrap; position: relative; right: 0px; background-color: #e0e5ec; border: none; border-radius: 10px; cursor: pointer;';if (updateLogButton) {updateLogButton.onclick = fetchAndDisplayVersionHistory;}versionInfo.appendChild(updateLogButton);return versionInfo;}/*** 显示版本历史面板。** @param {string} versionHistory - 版本历史内容的HTML字符串。*/function displayVersionHistoryPanel(versionHistory) {let versionHistoryPanel = document.getElementById('versionHistoryPanel');if (!versionHistoryPanel) {versionHistoryPanel = document.createElement('div');versionHistoryPanel.id = 'versionHistoryPanel';document.body.appendChild(versionHistoryPanel);} else {versionHistoryPanel.style.display = 'block';}versionHistoryPanel.innerHTML = `<div id="versionHistoryContent" style="padding: 10px; position: relative; width: 300px; height: 300px; overflow: auto; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #e0e5ec; box-shadow: 0 4px 8px 0 rgba(0,0,0,0.4), 0 6px 20px 0 rgba(0,0,0,0.19); border-radius: 15px; box-sizing: border-box; z-index: 10000; display: block; font-family: Arial, sans-serif;"><button id="closeVersionHistory" style="position: absolute; top: 10px; right: 10px; background: none; border: none; cursor: pointer;"><svg xmlns="http://www.w3.org/2000/svg" height="24" fill="currentColor" viewBox="0 0 334 334"><path d="M 320 48 Q 334 31 320 14 Q 303 0 286 14 L 167 133 L 48 14 Q 31 0 14 14 Q 0 31 14 48 L 133 167 L 14 286 Q 0 303 14 320 Q 31 334 48 320 L 167 201 L 286 320 Q 303 334 320 320 Q 334 303 320 286 L 201 167 L 320 48 L 320 48 Z" /></svg></button><h2 style="text-align: center; font-size: 20px; font-weight: bold; color: #333; margin-bottom: 20px; text-shadow: 1px 1px 2px #888;">更新日志</h2>${versionHistory}</div>`;document.getElementById('closeVersionHistory').addEventListener('click', function() {versionHistoryPanel.style.display = 'none';});}/*** 通过Greasy Fork网站获取版本历史信息并显示在自定义面板中。*/async function fetchAndDisplayVersionHistory() {const url = 'https://greasyfork.org/zh-CN/scripts/493851-%E7%BD%91%E9%A1%B5%E7%9E%AC%E9%97%B4%E5%8A%A0%E8%BD%BD-%E8%B7%B3%E8%BF%87%E8%BF%9B%E5%BA%A6%E6%9D%A1%E7%9B%B4%E6%8E%A5%E5%8A%A0%E8%BD%BD%E7%BD%91%E9%A1%B5/versions';try {const response = await fetch(url);const text = await response.text();const parser = new DOMParser();const doc = parser.parseFromString(text, 'text/html');const versionHistory = doc.querySelector('.history_versions');if (versionHistory) {displayVersionHistoryPanel(versionHistory.innerHTML);} else {throw new Error('无法找到更新历史信息的元素');}} catch (error) {console.error('Failed to fetch version history', error);showAlert('无法获取更新历史,请稍后重试。');}}/*** 初始化默认设置并存储。*/function initializeDefaultSettings() {const defaultSettings = {backToThePreviousPage: "shift+r",blacklistDomains: [],blackSelector: true,concurrentLoadingNumber: 5,forward: "shift+f",goToTheCorrespondingPage: "shift+e",lazyLoadImages: false,loadedStyle: "下划线",manipulatorBall: true,mobileGestures: true,previewHoverWindow: false,redirectOptimization: true,setShortcuts: "shift+s",asynchronousResources: true,whitelistDomains: [],whiteSelector: false,maxContentSize: 5,maxStorageItems: 100,dataCleanupInterval: 1,is_loadedStyle: true,monitorRefresh: 2,};Object.keys(defaultSettings).forEach((key) => {let currentValue = GM_getValue(key);if (currentValue === undefined || currentValue === null) {GM_setValue(key, defaultSettings[key]);}});}function replaceDownloadLink() {if (/lanz/.test(window.location.hostname)) {let downloadLinks = document.querySelectorAll('a');downloadLinks.forEach(link => {if (link.textContent.includes('立即下载')) {let scripts = document.querySelectorAll('script');scripts.forEach(script => {let match = script.textContent.match(/var link = '(.*?)';/);if (match) {let newLink = window.location.hostname + '/' + match[1] + "##";console.log(newLink);link.href = '//' + newLink;}});} else if (/下载\(\s*[\d\.]+\s*K\s*\)/.test(link.textContent)) {let scripts = document.querySelectorAll('script');let vkjxld, hyggid;scripts.forEach(script => {let match_vk = script.textContent.match(/var vkjxld = '(.*?)';/);let match_hy = script.textContent.match(/var hyggid = '(.*?)';/);if (match_vk) {vkjxld = match_vk[1];}if (match_hy) {hyggid = match_hy[1];}});if (vkjxld && hyggid) {let newLink = vkjxld + hyggid;console.log(newLink);link.href = newLink;}}});}}/*** 设置当前激活的面板,并对动画进行处理。** @param {string} activePanelId - 要激活的面板ID。*/function setActivePanel(activePanelId) {if (isAnimating) return;isAnimating = true;updateActiveIndicator(activePanelId);const panelIds = ['panel1', 'panel2', 'panel3']; // 面板ID列表按顺序const currentActiveIndex = panelIds.indexOf(currentActivePanelId);const targetActiveIndex = panelIds.indexOf(activePanelId);const direction = targetActiveIndex > currentActiveIndex ? -1 : 1; // 目标在右边则向左(-1), 否则向右(1)// 根据目标和当前激活的面板,计算出移动距离let moveDistance = direction * Math.abs(targetActiveIndex - currentActiveIndex) * 290; // 每个面板间隔250px宽度// 创建移动函数,面板根据方向和距离移动const animatePanel = (panelId, distance) => {const panel = document.getElementById(panelId);let currentTranslateX = parseFloat(panel.style.transform.replace('translateX(', '').replace('px)', '')) || 0;panel.style.transform = `translateX(${currentTranslateX + distance}px)`;};panelIds.forEach(id => {animatePanel(id, moveDistance);});// 动画结束后,重置面板位置并只显示目标面板setTimeout(() => {panelIds.forEach(id => {const panel = document.getElementById(id);panel.style.transform = `translateX(${(panelIds.indexOf(id) - targetActiveIndex) * 270}px)`;});currentActivePanelId = activePanelId;isAnimating = false;}, 500);}/*** 在屏幕上显示一段提示信息。** @param {string} message - 需要展示的消息。*/function showAlert(message) {let alertBox = createElementWithStylesAndAttributes("div", { width: "300px", position: "fixed", bottom: "10px", left: "50%", transform: "translateX(-50%)", backgroundColor: "#E0E5EC", borderRadius: "5px", boxShadow: "2px 2px 2px #AEBEC7, -2px -2px 2px #FFFFFF", zIndex: "2000" });let alertText = createElementWithStylesAndAttributes("div", { margin: "0", fontSize: "16px", fontWeight: "bold", textAlign: "center", textShadow: "2px 2px 3px rgba(0, 0, 0, 0.2)", color: "#4B5563" }, { innerText: message });alertBox.appendChild(alertText);document.body.appendChild(alertBox);setTimeout(function() {alertBox.style.opacity = "1";}, 10);setTimeout(function() {alertBox.style.opacity = "0";alertBox.addEventListener('transitionend', function() {document.body.removeChild(alertBox);}, { once: true });}, 1500);}/*** 性能分析工具的主要类。*/var Stats = function() {var currentMode = 0;var container = createElementWithStylesAndAttributes('div', { position: 'fixed', bottom: '10px', right: '10px', left: '10px', cursor: 'pointer', opacity: '0.9', zIndex: '10000' });container.addEventListener('click', function(event) {event.preventDefault();showPanel(++currentMode % container.children.length);}, false);// 初始化性能监视计时var startTime = (performance || Date).now(),prevTime = startTime;var frames = 0;// 创建并添加面板var fpsPanel = addPanel(new Stats.Panel('FPS', '#0ff', '#002'));var msPanel = addPanel(new Stats.Panel('MS', '#0f0', '#020'));var memPanel;// 判断performance.memory是否可用以监视内存使用if (self.performance && self.performance.memory) {memPanel = addPanel(new Stats.Panel('MB', '#f08', '#201'));}showPanel(0);function addPanel(panel) {container.appendChild(panel.dom);return panel;}function showPanel(mode) {for (var i = 0; i < container.children.length; i++) {container.children[i].style.display = i === mode ? 'block' : 'none';}currentMode = mode;}return {dom: container,addPanel: addPanel,showPanel: showPanel,begin: function() {startTime = (performance || Date).now();},end: function() {frames++;var time = (performance || Date).now();msPanel.update(time - startTime, 200);if (time > prevTime + GM_getValue('monitorRefresh', 2) * 1000) {fpsPanel.update((frames * 1000) / (time - prevTime), 100);prevTime = time;frames = 0;if (memPanel) {var memory = performance.memory;memPanel.update(memory.usedJSHeapSize / 1048576, memory.jsHeapSizeLimit / 1048576);}}return time;},update: function() {startTime = this.end();}};};/*** Stats中的Panel类,用来展示性能数据。** @param {string} name - 面板显示的标题。* @param {string} fg - 前景色。* @param {string} bg - 背景色。*/Stats.Panel = function(name, fg, bg) {var min = Infinity,max = 0;var round = Math.round;var pixelRatio = round(window.devicePixelRatio || 1);var width = 80 * pixelRatio,height = 48 * pixelRatio;var textPadding = 3 * pixelRatio,textHeight = 2 * pixelRatio;var graphX = 3 * pixelRatio,graphY = 15 * pixelRatio;var graphWidth = 74 * pixelRatio,graphHeight = 30 * pixelRatio;var canvas = document.createElement('canvas');canvas.width = width;canvas.height = height;canvas.style.cssText = 'width:80px;height:48px';var context = canvas.getContext('2d');context.font = 'bold ' + (9 * pixelRatio) + 'px Helvetica,Arial,sans-serif';context.textBaseline = 'top';context.fillStyle = bg;context.fillRect(0, 0, width, height);context.fillStyle = fg;context.fillText(name, textPadding, textHeight);context.fillRect(graphX, graphY, graphWidth, graphHeight);context.fillStyle = bg;context.globalAlpha = 0.9;context.fillRect(graphX, graphY, graphWidth, graphHeight);return {dom: canvas,update: function(value, maxValue) {min = Math.min(min, value);max = Math.max(max, value);context.fillStyle = bg;context.globalAlpha = 1;context.fillRect(0, 0, width, graphY);context.fillStyle = fg;context.fillText(round(value) + ' ' + name + ' (' + round(min) + '-' + round(max) + ')', textPadding, textHeight);context.drawImage(canvas, graphX + pixelRatio, graphY, graphWidth - pixelRatio, graphHeight, graphX, graphY, graphWidth - pixelRatio, graphHeight);context.fillRect(graphX + graphWidth - pixelRatio, graphY, pixelRatio, graphHeight);context.fillStyle = bg;context.globalAlpha = 0.9;context.fillRect(graphX + graphWidth - pixelRatio, graphY, pixelRatio, round((1 - value / maxValue) * graphHeight));}};};/*** 更新当前激活面板的指示器样式。** @param {string} activePanelId - 当前激活的面板ID。*/function updateActiveIndicator(activePanelId) {// 首先重置所有按钮的样式[settingsParameters, additionalFeatures, shortcutKeys].forEach(button => {button.style.fontSize = "20px";button.style.textShadow = "none";});// 根据当前激活的面板ID,将对应按钮的字体放大并添加立体效果if (activePanelId === 'panel1') {settingsParameters.style.fontSize = "24px";settingsParameters.style.textShadow = "1px 1px #888888";} else if (activePanelId === 'panel2') {additionalFeatures.style.fontSize = "24px";additionalFeatures.style.textShadow = "1px 1px #888888";} else if (activePanelId === 'panel3') {shortcutKeys.style.fontSize = "24px";shortcutKeys.style.textShadow = "1px 1px #888888";}}/*-------------以下为重定向优化的具体实现函数-------------*//*** 重定向优化的主要参数,每个参数代表重定向的查询参数名称(基本涵盖95%的重定向链接)。*/const queryItems = ['url', 'target', 'href', 'tid', 'u', 'goto', 'link','remoteUrl', 'to', 'redirect', 'iv', 'safecheck', 'black','sinaurl', 'newredirectconfirmcgi', 'view', 'go.shtml', 'link','linkout', 'link2', 'go-wild', 'id', 'jump', 'jump.php', 'web','security', 'r', 'redirect_link', 'youtube.com/redirect',];if (typeof GM_getValue === 'function') {var queryItemsList = GM_getValue('queryItemsList', []);var queryItemsLists = [...new Set([...queryItemsList, ...queryItems])];GM_setValue('queryItemsList', queryItemsLists);}/*** 额外的重定向判断条件。* @param {string} urlObj* @param {HTMLAnchorElement} linkElement* @returns*/function extractTargetUrl(urlObj, linkElement) {if (urlObj.pathname.includes('jump.php')) {extractFromJumpPhp(urlObj, linkElement);return;}for (const item of queryItemsList) {try {const target = urlObj.searchParams.get(item);if (target && isValidHttpUrl(decodeURIComponent(target))) {updateLink(target, linkElement, item);return;}} catch (e) {console.error('URI 解码错误:', e);}}}/*** 单独对jump.php的处理。* @param {string} urlObj* @param {HTMLAnchorElement} linkElement*/function extractFromJumpPhp(urlObj, linkElement) {const fullUrl = urlObj.href;const targetUrl = fullUrl.substring(fullUrl.indexOf('jump.php?') + 9);updateLink(targetUrl, linkElement);}let preloadedLinks = [];/*** 对链接优化的主要函数* @param {string} target* @param {HTMLAnchorElement} linkElement* @param {string} item*/function updateLink(target, linkElement, item) {const originalHref = linkElement.href;const linkName = linkElement.textContent || linkElement.innerText;try {const targetUrl = decodeURIComponent(target);if (isValidHttpUrl(targetUrl)) {linkElement.href = targetUrl;console.log('优化的重定向链接:', originalHref, 'to:', targetUrl);preloadedLinks.push({ redirectParameter: item, name: linkName, url: originalHref, optimizedUrl: targetUrl });GM_setValue('preloadedLinks', preloadedLinks);}} catch (e) {console.error('URI 解码错误:', e);}}function isValidHttpUrl(string) {try {const url = new URL(string);return url.protocol === "http:" || url.protocol === "https:";} catch (_) {return false;}}function optimizeRedirects() {document.querySelectorAll('a[href]').forEach(link => {if (link.dataset.optimized) return;try {const urlObj = new URL(link.href);extractTargetUrl(urlObj, link);link.dataset.optimized = true;} catch (e) {console.error('错误处理链接:', link.href, '; Error:', e);}});}/*** 初始化重定向链接*/function init() {if (GM_getValue('redirectOptimization')) {window.addEventListener('load', () => {optimizeRedirects();replaceDownloadLink();setInterval(replaceDownloadLink, 200); // 每0.5秒执行一次});const observer = new MutationObserver(() => {optimizeRedirects();replaceDownloadLink();});observer.observe(document.body, { childList: true, subtree: true });window.addEventListener('beforeunload', () => observer.disconnect());}}init();/* ----------------------------- 以下为预加载链接的具体代码实现 ---------------------------- *//*** 为链接添加视觉提醒,指示其已被预加载。** @param {HTMLElement} element - 链接元素。*/function addAVisualLinkReminder(element) {var href = element.href;try {var linkURL = new URL(href);var currentOrigin = window.location.origin;if (linkURL.origin === currentOrigin) {if (element.dataset.preloaded && GM_getValue('is_loadedStyle')) {switch (GM_getValue('loadedStyle', "下划线")) {case '下划线':element.style.textDecoration = 'underline';element.style.textDecorationSkipInk = 'none';break;case '高亮':element.style.backgroundColor = 'yellow';break;case '品红':element.style.color = '#FF00FF';break;case '加粗':element.style.fontWeight = 'bold';break;case '边框':element.style.border = '2px solid red';element.style.borderRadius = '4px';break;default:break;}}}} catch (e) {console.error('Error adding visual link reminder:', e);}}/*** 添加可拖动的图标到页面上。*/function addDraggableIcon() {var svgHTML = '<svg id="draggableIcon" style="position: fixed; top: 50%; right: -20px; transform: translateY(-50%); cursor: pointer; z-index: 9999999;" width="50" height="50" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M3.464 20.536C4.93 22 7.286 22 12 22c4.714 0 7.071 0 8.535-1.465C22 19.072 22 16.714 22 12s0-7.071-1.465-8.536C19.072 2 16.714 2 12 2S4.929 2 3.464 3.464C2 4.93 2 7.286 2 12c0 4.714 0 7.071 1.464 8.535" opacity=".5"/><path fill="currentColor" d="M12.03 9.53a.75.75 0 0 0-1.06-1.06l-3 3a.75.75 0 0 0 0 1.06l3 3a.75.75 0 1 0 1.06-1.06L9.56 12z"/><path fill="currentColor" d="M16.03 9.53a.75.75 0 0 0-1.06-1.06l-3 3a.75.75 0 0 0 0 1.06l3 3a.75.75 0 1 0 1.06-1.06L13.56 12z"/></svg>',div = document.createElement('div');div.innerHTML = svgHTML;document.body.appendChild(div.firstChild);function onDrag(e, move) {var startX = ('touches' in e ? e.touches[0] : e).clientX - dragIcon.getBoundingClientRect().left,startY = ('touches' in e ? e.touches[0] : e).clientY - dragIcon.getBoundingClientRect().top;function dragging(ev) {var clientX = ('touches' in ev ? ev.touches[0] : ev).clientX,clientY = ('touches' in ev ? ev.touches[0] : ev).clientY;dragIcon.style.left = clientX - startX + 'px';dragIcon.style.top = clientY - startY + 'px';}function endDrag() {document.removeEventListener(move ? 'mousemove' : 'touchmove', dragging);document.removeEventListener(move ? 'mouseup' : 'touchend', endDrag);document.body.style.overflow = '';dragIcon.style.transition = '';GM_setValue('iconPosition', { left: dragIcon.style.left, top: dragIcon.style.top });}document.addEventListener(move ? 'mousemove' : 'touchmove', dragging);document.addEventListener(move ? 'mouseup' : 'touchend', endDrag);document.body.style.overflow = 'hidden';dragIcon.style.transition = 'none';if (!move) {dragIcon.dataset.pressTimer = setTimeout(endDrag, 500);}}var dragIcon = document.getElementById('draggableIcon');dragIcon.style.display = 'none';var savedPosition = GM_getValue('iconPosition');savedPosition && (dragIcon.style.left = savedPosition.left, dragIcon.style.top = savedPosition.top);dragIcon.ontouchstart = function(e) {onDrag(e, false);};dragIcon.ontouchend = function() {clearTimeout(dragIcon.dataset.pressTimer);};dragIcon.onmousedown = function(e) {e.preventDefault();onDrag(e, true);};}/*** 将一个链接添加到预加载队列中。** @param {string} url - 链接的地址。* @param {HTMLElement} element - 对应的链接元素。*/function addToPreloadQueue(url, element) {// 增加了对集合中存在性的检查if (isInViewport(element) && !preloadSet.has(url)) {preloadSet.add(url);preloadQueue.push({ url: url, element: element });}}/*** 将二进制大对象(blob)转换为Base64编码的字符串。** @param {Blob} blob - 需要转换的blob对象。* @returns {Promise<string>} - 包含Base64编码字符串的Promise。*/function blobToBase64(blob) {return new Promise((resolve, reject) => {const reader = new FileReader();reader.onloadend = () => resolve(reader.r###lt);reader.onerror = e => reject(e);reader.readAsDataURL(blob);});}/*** 取消一个指定链接的预加载。** @param {string} url - 需要取消预加载的链接URL。*/function cancelPreload(url) {if (abortControllers[url]) {abortControllers[url].abort();delete abortControllers[url]; // 删除abortController实例的引用以防内存泄露console.log("Preload cancelled for link out of viewport:", url);currentPreloads--; // 更新计数preloadNext(); // 尝试开始下一个预加载}// 从预加载队列中移除链接preloadQueue = preloadQueue.filter(item => item.url !== url);preloadSet.delete(url); // 从预加载集合中移除链接}/*** 检查预加载的锚点链接并添加相应的视觉提醒。*/function checkAndAddBulletsForPreloadedLinks() {var links = document.querySelectorAll('a');links.forEach(function(link) {if (link.dataset.preloaded) {addAVisualLinkReminder(link);}});}/*** 清理预加载队列,移出不符合条件的链接。*/function cleanPreloadQueue() {// 清理已经预加载或者不在视口内的链接preloadQueue = preloadQueue.filter(item => {if (!(isInViewport(document.querySelector(`a[href="${item.url}"]`)) && !document.querySelector(`a[href="${item.url}"]`).dataset.preloaded)) {preloadSet.delete(item.url); // 如果不满足条件,则从集合中删除return false;}return true;});}/*** 清理已经超时或已经中止的AbortController实例。*/function cleanAbortControllers() {// 获取当前时间var now = Date.now();// 遍历abortControllers对象的属性for (var url in abortControllers) {// 如果请求已经很久没有响应,那么我们认为它可能已经失效,需要删除控制器// 或如果请求已经被中止,亦应删除var controller = abortControllers[url];if ((controller.timestamp && now - controller.timestamp > 30000) || controller.signal.aborted) { // 30秒或已中止delete abortControllers[url];}}}/*** 防抖函数,用于延迟执行并防止函数在短时间内多次触发。** @param {Function} func - 需要防抖的函数。* @param {number} wait - 延迟执行的时间,单位为毫秒。* @param {boolean} immediate - 是否立即执行。* @returns 防抖处理后的函数。*/function debounce(func, wait, immediate) {var timeout, called = false;return function() {var context = this,args = arguments;var later = function() {timeout = null;if (!immediate && !called) func.apply(context, args);called = false; // 重置调用标志};var callNow = immediate && !timeout;if (callNow) {func.apply(context, args);called = true; // 立即执行时,设置调用标志}clearTimeout(timeout);timeout = setTimeout(later, wait);};}/*** 从IndexedDB数据库中删除旧内容。*/function deleteOldContentFromDB() {const now = Date.now();const transaction = db.transaction([dbStoreName], 'readwrite');const store = transaction.objectStore(dbStoreName);var contentRequest = store.getAll();contentRequest.onsuccess = function() {var contents = contentRequest.r###lt;// 如有必要,根据最后访问时间进行排序contents.sort((a, b) => b.timestamp - a.timestamp);// 判断记录是否超出最大存储量或者是否过期,然后执行删除contents.forEach((content, index) => {if (now - content.timestamp > dataCleanupInterval || index >= maxStorageItems) { // 检查每一项是否过期或超出容量限制store.delete(content.url);}});};contentRequest.onerror = function(event) {console.error("Error fetching contents from IndexedDB", event.target.error);};}/*** 显示预加载的内容。** @param {string} base64Content - 预加载内容的Base64编码。* @param {string} url - 内容对应的链接地址。*/function displayPreloadedContent(base64Content, url) {if (base64Content.startsWith('data:')) {var binary = atob(base64Content.split(',')[1]);var array = new Uint8Array(binary.length);for (var i = 0; i < binary.length; i++) {array[i] = binary.charCodeAt(i);}var documentEncoding = document.characterSet || 'UTF-8';var blobContent = new Blob([array], { type: `text/html;charset=${documentEncoding}` });var reader = new FileReader();reader.onload = function() {var existingFullPageDiv = document.getElementById('fullPageDiv');if (existingFullPageDiv) {existingFullPageDiv.parentNode.removeChild(existingFullPageDiv);existingFullPageDiv.remove();}var fullPageDiv = document.createElement('div');fullPageDiv.id = 'fullPageDiv';fullPageDiv.style.cssText = `position: fixed;top: 0;left: 0;width: 100%;height: 100%;overflow: auto;z-index: 1000;background: white;`;fullPageDiv.innerHTML = reader.r###lt;toggleDragIconVisibility(true);document.body.style.overflow = 'hidden';document.body.appendChild(fullPageDiv);if (GM_getValue('asynchronousResources')) {var iframe = document.createElement('iframe');iframe.style.cssText = ' top: 0; left: 0; width: 100%; height: 100%; display: block; visibility: hidden;';iframe.src = url;document.body.appendChild(iframe);fullPageDiv.onscroll = function() {if (iframe.contentWindow) {iframe.contentWindow.scrollTo(0, fullPageDiv.scrollY);iframe.contentWindow.scrollTo(0, fullPageDiv.scrollTop);}};iframe.onload = function() {iframe.contentWindow.onscroll = function() {var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;fullPageDiv.innerHTML = iframeDocument.documentElement.outerHTML; // 更新内容};}}};reader.readAsText(blobContent, documentEncoding);}}/*** 初始化IndexedDB数据库。** @param {Function} success - 数据库就绪后执行的回调函数。*/function initDB(success) {if (!dbReady) {openDB(success);} else if (typeof success === 'function') {success();}}/*** 判断一个元素是否在视口内。** @param {HTMLElement} element - 需要判断的HTML元素。* @returns {boolean} - 元素是否在视口内。*/function isInViewport(element) {var rect = element.getBoundingClientRect();var inViewport = (rect.top >= 0 &&rect.left >= 0 &&rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&rect.right <= (window.innerWidth || document.documentElement.clientWidth));if (!inViewport && element.dataset.preloaded) {cancelPreload(element.href); // 如果链接不在视窗中并且已被标记为预加载,取消它的预加载element.dataset.preloaded = false; // 移除预加载标记}return inViewport;}/*** 判断当前设备是否为移动设备。** @returns {boolean} - 是否为移动设备。*/function isMobileDevice() {return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);}/*** 使用MutationObserver监听DOM变化。*/function observeDOMChanges() {var handledLinks = new Set(); // 用于储存处理过的链接var config = { childList: true, subtree: true };var callback = function(mutationsList, observer) {requestAnimationFrame(function() {mutationsList.forEach(debounce(function(mutation) {if (mutation.type == 'childList' && mutation.addedNodes.length) {mutation.addedNodes.forEach(function(node) {if (node.nodeType === 1 && node.matches('a[href]')) {var href = node.getAttribute('href');if (!preloadSet.has(href) && !handledLinks.has(href)) {preloadLink(href, node);handledLinks.add(href); // 将链接添加到 handledLinks 中进行标记preloadSet.add(href); // 将链接添加到 preloadSet 中}}});}}, 250));preloadVisibleLinks();});};var observer = new MutationObserver(callback);observer.observe(document.body, config);}/*** 打开IndexedDB数据库。** @param {Function} callback - 数据库打开成功的回调函数。*/function openDB(callback) {if (dbInitializationPromise) { // 如果存在初始化的Promise,直接返回它并添加回调dbInitializationPromise.then(callback).catch(err => console.error('IndexedDB init error:', err));return;}// 新建一个Promise来处理初始化过程dbInitializationPromise = new Promise((resolve, reject) => {var request = indexedDB.open(dbName, dbVersion);request.onupgradeneeded = function(event) {var db = event.target.r###lt;if (!db.objectStoreNames.contains(dbStoreName)) {db.createObjectStore(dbStoreName, { keyPath: 'url' });}};request.onsuccess = function(event) {db = event.target.r###lt;dbReady = true;console.log('IndexedDB database opened successfully');db.onerror = function(event) {console.error("Database error: " + event.target.error.message);};resolve(db);};request.onerror = function(event) {console.error('IndexedDB database open error:', event.target.errorCode);dbInitializationPromise = null; // 如果Promise失败,我们重置这个变量reject(event.target.error);};});// 调用传入的回调函数dbInitializationPromise.then(callback).catch(err => console.error('IndexedDB init error:', err));}/*** 将一个链接的属性值视为适当。** @param {string} url - 链接的URL地址。* @returns {string} - 适当的属性值。*/function appropriateAsAttributeValue(url) {if (url.endsWith('.css')) {return 'style';} else if (url.endsWith('.js')) {return 'script';} else if (url.match(/(.jpg|.jpeg|.png|.gif)$/)) {return 'image';} else if (url.endsWith('.json')) {return 'fetch';} else {return 'fetch';}}/*** 预加载指定的链接。** @param {string} url - 需要预加载的链接URL。* @param {HTMLElement} element - 对应的链接元素。*/function preloadLink(url, element) {try {var linkURL = new URL(url);if (linkURL.protocol !== 'http:' && linkURL.protocol !== 'https:') {console.log('Not preloading: Non-HTTP link:', url);return;}if (isBlacklistModeEnabled && blacklistDomains.includes(linkURL.hostname)) {console.log('Not preloading: Blacklisted domain:', linkURL.hostname);return;}// 跳过与当前页面相同或者跨域的URLif (linkURL.hostname !== window.location.hostname || linkURL.href === window.location.href) {console.warn('Not preloading: Same page or cross-origin link:', url);return;}if (preloadSet.has(url) || element.dataset.preloaded) {console.log('Not preloading: Already preloaded or enqueued for preload:', url);return;}if (currentPreloads < maxConcurrentPreloads) {currentPreloads++;let options = {cache: "force-cache", // 使用force-cache可以帮助减少不必要的网络请求as: appropriateAsAttributeValue(url), // 根据不同的链接类型,为 'as' 属性设置适当的值credentials: "include",headers: new Headers(window.headers)};if (element.rel && (element.rel.includes('noreferrer') || element.rel.includes('noopener'))) {options.referrerPolicy = 'no-referrer';}// 创建一个新的abortController实例,并将signal传给fetchvar controller = new AbortController();controller.timestamp = Date.now();var signal = controller.signal;options.signal = signal; // 将signal添加到fetch选项中abortControllers[url] = controller;fetch(linkURL.href, options).then(function(response) {if (!response.ok) {throw new Error('HTTP error, status = ' + response.status);}return response.blob();}).then(function(blob) {saveContentToDB(url, blob);addAVisualLinkReminder(element);}).catch(function(error) {console.error('Preload failed for ', url, ':', error.message);}).finally(function() {currentPreloads--;preloadNext();delete abortControllers[url];});} else {addToPreloadQueue(url, element);return;}} catch (e) {console.error('Error preloading link:', e.message);}}/*** 继续预加载队列中的下一个链接。*/function preloadNext() {if (preloadQueue.length > 0 && currentPreloads < maxConcurrentPreloads) {var nextPreload = preloadQueue.shift();preloadLink(nextPreload.url, nextPreload.element);delete abortControllers[nextPreload.url];}}/*** 预加载所有可见的链接。*/function preloadVisibleLinks() {if (!isMobileDevice()) {return;}var links = document.querySelectorAll('a');var visibleLinks = Array.from(links).filter(function(link) {var href = link.href;return isInViewport(link) && !link.dataset.preloaded && (shouldPreloadMapping[href] !== false);});visibleLinks.sort(function(a, b) {var aRect = a.getBoundingClientRect();var bRect = b.getBoundingClientRect();return (window.innerHeight - aRect.bottom) - (window.innerHeight - bRect.bottom);});var preloadLimit = Math.min(visibleLinks.length, maxConcurrentPreloads - currentPreloads);for (var i = 0; i < preloadLimit; i++) {(function(linkElement) {var href = linkElement.href;if (shouldPreloadMapping[href] === undefined) {// 如果该链接的预加载状态尚未决定,则发起检查shouldPreload(linkElement.href).then(function(should) {shouldPreloadMapping[href] = should;if (should && isInViewport(linkElement)) {preloadLink(linkElement.href, linkElement);linkElement.dataset.preloaded = true;}});} else if (shouldPreloadMapping[href]) {// 如果已经确定需要预加载,则直接预加载,无需重复检查preloadLink(linkElement.href, linkElement);linkElement.dataset.preloaded = true;}})(visibleLinks[i]);}}/*** 处理数据库写入队列。*/function processDBWriteQueue() {if (dbWriteInProgress || dbWriteQueue.length === 0) {return;}dbWriteInProgress = true;var item = dbWriteQueue.shift();blobToBase64(item.blob).then(base64data => {var transaction = db.transaction([dbStoreName], 'readwrite');var objectStore = transaction.objectStore(dbStoreName);// 处理事务完成return new Promise((resolve, reject) => {var request = objectStore.put({ url: item.url, htmlContent: base64data, timestamp: Date.now() });request.onsuccess = () => resolve();request.onerror = () => reject(request.error);});}).then(() => {console.log('Page content saved to IndexedDB for', item.url);dbWriteInProgress = false;processDBWriteQueue(); // 递归处理队列中的下一项}).catch(error => {console.error('IndexedDB save operation failed for', item.url, error);dbWriteQueue.unshift(item); // 发生错误时重新将项目放入队列dbWriteInProgress = false;setTimeout(processDBWriteQueue, 1000); // 延迟重试});}/*** 从数据库中读取内容。** @param {string} url - 内容的URL。* @param {Function} callback - 读取到内容后的回调函数。*/function readContentFromDB(url, callback) {var transaction = db.transaction([dbStoreName], 'readonly');var objectStore = transaction.objectStore(dbStoreName);var request = objectStore.get(url);request.onsuccess = function(event) {callback(event.target.r###lt);};request.onerror = function(event) {console.error('IndexedDB read failed for', url);callback(null);};}/*** 将内容保存到IndexedDB数据库中。** @param {string} url - 内容的URL。* @param {Blob} blob - 包含要保存内容的Blob对象。*/function saveContentToDB(url, blob) {if (!dbReady) {console.error('IndexedDB is not ready for writing data.');return;}if (blob.size > maxContentSize) {console.log('Content size exceeds the maxContentSize limit. Not saving to IndexedDB');return;}dbWriteQueue.push({ url, blob });if (!dbWriteInProgress) {processDBWriteQueue();}}/*** 安排下一次数据库内容清理。*/function scheduleNextCleanup() {// 删除旧内容后,再次调用此函数以依据当前间隔设定继续调度setTimeout(function() {deleteOldContentFromDB();scheduleNextCleanup();}, dataCleanupInterval);}/*** 设置鼠标悬停预加载行为。*/function setupMouseHoverPreload() {document.addEventListener('mouseover', function(event) {var target = event.target.closest('a');if (target && !target.dataset.preloaded) {// 判断链接是否指向图片,如果是,就不进行预加载处理var href = target.getAttribute('href');// 更新正则表达式来匹配 Greasy Fork 的特定图片链接模式if (href.match(/\.(jpeg|jpg|gif|png|webp)$/i) ||href.includes("active_storage/blobs/redirect")) {console.log('Skip preloading for image link', href);return; // 如果链接指向图片,直接返回,不设置预加载}// 鼠标悬停65毫秒以上就启动预加载target.dataset.hoverTimeout = setTimeout(function() {shouldPreload(target.href).then(function(shouldPreloadR###lt) {if (shouldPreloadR###lt && !target.dataset.preloaded) {preloadLink(target.href, target);target.dataset.preloaded = true; // 设置链接已预加载addAVisualLinkReminder(target); // 添加小圆球指示器}});}, 65);}});document.addEventListener('mouseout', function(event) {var target = event.target.closest('a');if (target && target.dataset.hoverTimeout) {// 当鼠标移开时清除定时器clearTimeout(target.dataset.hoverTimeout);target.dataset.hoverTimeout = null;}});}/*** 判断一个链接是否应该被预加载。** @param {string} url - 需要判断的链接URL。* @returns {Promise<boolean>} - 是否应该预加载该链接。*/function shouldPreload(url) {if (!(url instanceof URL)) {var linkURL = new URL(url);}if (signoutLinks.some(link => linkURL.pathname.includes(link))) {console.log('Not preloading: Signout link:', url);return Promise.resolve(false);}var domain = new URL(url).hostname;if (isWhitelistModeEnabled && !whitelistDomains.includes(domain)) {return Promise.resolve(false);}if (isBlacklistModeEnabled && blacklistDomains.includes(domain)) {return Promise.resolve(false);}return fetch(url, { method: 'GET', mode: 'no-cors' }).then(function(response) {return response.text();}).then(function(html) {// 检查页面是否包含跳转脚本var redirectRegex = /window\.location\.href\s*=\s*['"]([^'"]+)['"]/;var match = redirectRegex.exec(html);if (match && match[1]) {// 页面有跳转,打印消息并返回 falseconsole.log('The page has a redirect script. Skipping preload for:', url);return false;}// 页面没有跳转,返回 truereturn true;}).catch(function(error) {console.error('Error fetching page for preload check:', error);return false;});}/*** 切换可拖动图标的显示状态。** @param {boolean} show - 是否显示图标。*/function toggleDragIconVisibility(show) {var dragIcon = document.getElementById('draggableIcon');if (dragIcon) {dragIcon.style.display = show ? 'block' : 'none';}}/*** 开始预加载链接。*/function startLinkPreloading() {initDB(preloadVisibleLinks);}/*** 处理回退导航。*/function handleBackNavigation() {if (currentPreviewIndex > 0) {currentPreviewIndex -= 1;var prevURL = clickedLinks[currentPreviewIndex];readContentFromDB(prevURL, function(data) {if (data) {displayPreloadedContent(data.htmlContent, prevURL);} else {location.href = prevURL;}});} else {var fullPageDiv = document.getElementById('fullPageDiv');if (fullPageDiv) {fullPageDiv.remove();toggleDragIconVisibility(false);document.body.style.overflow = '';}clickedLinks = [];currentPreviewIndex = -1;}}/*** 处理前进导航。*/function handleForwardNavigation() {if (currentPreviewIndex < clickedLinks.length - 1) {currentPreviewIndex += 1;var nextURL = clickedLinks[currentPreviewIndex];readContentFromDB(nextURL, function(data) {if (data) {displayPreloadedContent(data.htmlContent, nextURL);} else {location.href = nextURL;}});}}/*** 导航到URL。*/function navigateToURL() {if (clickedLinks.length > 0 && currentPreviewIndex >= 0) {var currentURL = clickedLinks[currentPreviewIndex];window.location.href = currentURL;}}/*-------------以下为设置面板的具体代码初始化代码-------------*/initializeDefaultSettings();checkForUpdates();var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;var dbVersion = 1;var dbName = 'preloadedPagesDB';var dbStoreName = 'preloadedPages';var maxConcurrentPreloads = GM_getValue('concurrentLoadingNumber', 5);var dataCleanupInterval = GM_getValue('dataCleanupInterval', 1) * 3600000;var maxContentSize = GM_getValue('maxContentSize', 5) * #### * ####;var maxStorageItems = GM_getValue('maxStorageItems', 100);var isWhitelistModeEnabled = GM_getValue('whiteSelector', false);var isBlacklistModeEnabled = GM_getValue('blackSelector', true);var defaultBlacklistDomains = ['www.bilibili.com','www.bing.com','www.huya.com','www.vimeo.com','www.tiktok.com','www.twitch.tv','www.youtube.com','www.dailymotion.com','www.liveleak.com','www.metacafe.com','www.youku.com','www.iqiyi.com','www.netflix.com','www.hulu.com','www.primevideo.com'];const signoutLinks = ['/sign_out', // 一般的 sign out 链接'/logout', // 常见的登出链接'/signoff', // 另一个常见的退出链接'/signout', // 没有下划线的 signout 链接'/logoff', // log off 形式的退出链接'/exit', // exit 链接'/user/logout', // 用户目录下的 logout 链接'/account/signout', // 帐户目录下的 signout 链接'/users/sign_out', // 复数形式 users 的 sign out 链接'/session/logout', // session 目录下的 logout 链接'/auth/logout', // 认证目录下的 logout 链接'/disconnect', // disconnect 形式的退出链接'/member/signout', // 会员目录下的 signout 链接'/user/sign_out', // 单个用户的 sign out 链接'/users/logout', // 复数形式 users 的 logout 链接'/sessions/signout', // sessions 目录下的 signout 链接'/api/logout', // API 目录下的 logout 链接'/app/logout', // APP 目录下的 logout 链接'/dashboard/logout', // 仪表盘目录下的 logout 链接'/home/logout', // 主页目录下的 logout 链接'/profile/logout', // 个人资料目录下的 logout 链接'/log_out', // 带下划线的 log out 链接'/signoff_user', // 带下划线的 sign off user 链接];if (typeof GM_getValue === 'function') {var storedBlacklistDomains = GM_getValue('blacklistDomains', []);var blacklistDomains = [...new Set([...storedBlacklistDomains, ...defaultBlacklistDomains])]; //将检索到的黑名单与默认黑名单合并,确保没有重复项GM_setValue('blacklistDomains', blacklistDomains);var whitelistDomains = GM_getValue('whitelistDomains', []);}function updateDomainLists() {blacklistDomains = GM_getValue('blacklistDomains', []);whitelistDomains = GM_getValue('whitelistDomains', []);}var currentPreloads = 0;var preloadQueue = [];var preloadSet = new Set();var abortControllers = {};var db;var dbReady = false;var clickedLinks = [];var currentPreviewIndex = -1;var dbWriteQueue = [];var dbWriteInProgress = false;var shouldPreloadMapping = {};let touchStartX = 0;let touchStartY = 0;let iconVisible = false;const svgBack = '<svg id="sliderBIcon" style="position: fixed; top: 50%; left: 100%; transform: translateY(-50%); cursor: pointer; z-index: 9999999;" width="100" height="50" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M14.53 7.53a.75.75 0 0 0-1.06-1.06l-5 5a.75.75 0 0 0 0 1.06l5 5a.75.75 0 1 0 1.06-1.06L10.06 12l4.47-4.47Z"/><path fill-rule="evenodd" d="M12 1.25C6.063 1.25 1.25 6.063 1.25 12S6.063 22.75 12 22.75 22.75 17.937 22.75 12 17.937 1.25 12 1.25ZM2.75 12a9.25 9.25 0 1 1 18.5 0 9.25 9.25 0 0 1-18.5 0Z"/></svg>';const svgForward = '<svg id="sliderFIcon" style="position: fixed; top: 50%; right: 100%; transform: translateY(-50%); cursor: pointer; z-index: 9999999;" width="100" height="50" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M10.53 6.47a.75.75 0 1 0-1.06 1.06L13.94 12l-4.47 4.47a.75.75 0 1 0 1.06 1.06l5-5a.75.75 0 0 0 0-1.06l-5-5Z"/><path fill-rule="evenodd" d="M12 1.25C6.063 1.25 1.25 6.063 1.25 12S6.063 22.75 12 22.75 22.75 17.937 22.75 12 17.937 1.25 12 1.25ZM2.75 12a9.25 9.25 0 1 1 18.5 0 9.25 9.25 0 0 1-18.5 0Z"/></svg>';const divBack = document.createElement('div');const divForward = document.createElement('div');divBack.innerHTML = svgBack;divForward.innerHTML = svgForward;document.body.appendChild(divBack);document.body.appendChild(divForward);var dbInitializationPromise = null;let currentActivePanelId = 'panel1';let isAnimating = false;let loadingPanel = createElementWithStylesAndAttributes('div', { position: "fixed", width: "305px", height: "auto", top: "50%", left: "50%", transform: "translate(-50%, -50%)", zIndex: "1001", backgroundColor: "#E0E5EC", borderRadius: "15px", boxShadow: "2px 2px 8px #BECBD8, -2px -2px 8px #FFFFFF", display: "none", flexDirection: "column" }, { className: 'loadingPanel customFontStyle' });let showcaseFeaturesPanel = createElementWithStylesAndAttributes('div', { position: "relative", width: "275px", height: "300px", borderRadius: "15px", display: "flex", alignItems: "center", justifyContent: "center", margin: "10px auto", overflowY: "hidden", overflowX: "hidden", flexWrap: "wrap", background: "#E0E5EC", boxShadow: "inset 9px 9px 16px #BABEC6, inset -9px -9px 16px #FFFFFF" }, { className: "showcaseFeaturesPanel" });const versionInfoElement = createVersionInfoElement();let font_style = `.customFontStyle *:not([class*='icon']):not(.fa):not(.fas):not(i) { font-family: 'PingFang SC', 'Heiti SC', 'myfont', 'Microsoft YaHei', 'Source Han Sans SC', 'Noto Sans CJK SC', 'HanHei SC', 'sans-serif' ,'icomoon','Icons' ,'brand-icons' ,'FontAwesome','Material Icons','Material Icons Extended','Glyphicons Halflings' !important; text-shadow: 1px 1px 10px #c3c3c3 !important; font-weight: bold !important; }`;const parameterFunction = ["并发加载数,numberPicker,concurrentLoadingNumber,information,⑴设计原则: 限制同时加载的页面数量,防止某些网页限制了并发数网站限制如:吾#破解论坛。\n⑵功能: 应对网页限制策略","最大内存项,numberPicker,maxContentSize,information,单位:(MB)\n⑴设计原则: 防止单个预加载页面占用过多内存资源,避免浏览器崩溃或响应缓慢。\n⑵功能: 允许用户设定每个页面预加载内容的内存使用上限,优化资源管理。","最大储存项,numberPicker,maxStorageItems,information,⑴设计原则: 限制缓存预加载内容的数量,以防数据库溢出或过度占用存储空间。\n⑵功能: 用户可自定义预加载内容储存数量上限,以维护存储空间的有效利用。","加载完样式,selector,loadedStyle,information,开关关闭则无提示样式\n⑴设计原则: 增强用户界面友好性,通过视觉反馈让用户明确知晓哪些内容已经被预加载。\n⑵功能: 提供多种可选样式(如下划线、高亮等),用户可以根据个人偏好设置预加载成功后元素的显示方式。,styleSelector,is_loadedStyle","黑名单列表,inputBox,blacklistDomains,information,⑴设计原则: 考虑到不同网页对动态内容加载的特殊要求,通过设定黑名单避免兼容性问题。\n⑵功能: 用户可以指定脚本不适用的网页域名,防止在这些网页上执行可能导致冲突的操作。,styleSelector,blackSelector","白名单列表,inputBox,whitelistDomains,information,⑴设计原则: 为了专注资源和优化特定网站的加载速度,通过白名单机制确保仅在指定域名上启用功能。\n⑵功能: 用户可设定脚本只在特定的网站或页面上运行,从而提高脚本的运行效率和兼容性。,styleSelector,whiteSelector",];const additionalFeaturesFunction = ["清理间隔项,numberPicker,dataCleanupInterval,information,单位:(小时)\n⑴设计原则: 通过定期清理过期或不常用的缓存数据,减少对存储资源的占用率,防止存储溢出和数据膨胀。⑵功能: 网页长时间不用则自动清理内存缓存,节省存储空间。","异步の资源,switch,asynchronousResources,information,建议电脑开启\n⑴设计原则: 对于异步加载的资源进行实时更新,比如:动态加载的图片等。\n⑵功能: 在本模式下,可以加载出一些异步资源,如果你关闭,那么久不会异步加载资源,但是加载会更流畅。","图片懒加载,switch,lazyLoadImages,information,未完善状态,由于效果并不是特别明显,暂且搁置\n⑴设计原则: 一种提高网页加载速度的技术,通过延迟加载图片,只加载当前可见区域的图片,提高页面加载速度。\n⑵功能: 当用户滚动页面时,提前加载屏幕外一个屏幕距离的图片,提升页面整体加载速度。","重定向优化,switch,redirectOptimization,information,⑴设计原则: 无疑重定向链接是重要的,但它有很多问题如:SEO影响、性能影响、重定循环(恶意钓鱼)等。\n⑵基于此,本选项提供删除重定向的功能,默认的重定向参数已经涵盖95%的重定向链接,你可以快捷方便地自己添加参数,settingButton","监控器刷新,numberPicker,monitorRefresh,information,单位:(秒)\n下方性能监控器点击可切换监控内容\n⑴设计原则: 决定下方的网页性能监控的刷新间隔,保证性能\n⑵功能: 设定刷新监控的间隔时间"];const shortcutKeysFunction = ["跳转对应页,shortcutKeySetting,goToTheCorrespondingPage","返回上一页,shortcutKeySetting,backToThePreviousPage","设置快捷键,shortcutKeySetting,setShortcuts","前进快捷键,shortcutKeySetting,forward","手势指示器,switch,mobileGestures,information,⑴移动端手势:本插件提供便捷操作方式,如左向右滑动后退,右向左滑动前进。且会显示一个指示器,关闭此选项后,手势操作仍然有效,但不再显示指示器占用屏幕空间","启用操作球,switch,manipulatorBall,information,操作球显示在屏幕右方且仅在预加载页面显示。\n⑴手机用户默认开启手势\n⑵电脑用户默认启用操作球"];const optionsArray = ['下划线', '无样式', '高亮', '品红', '加粗', '边框'];const title = createElementWithStylesAndAttributes('h1', { color: "#4B5563", textAlign: "center", marginBottom: "10px", marginTop: "10px", fontSize: "24px", fontWeight: "bold", textShadow: "2px 2px 3px rgba(0, 0, 0, 0.2)", userSelect: "none" }, { className: 'title', innerText: '网页瞬间加载' });const closeSetting = createElementWithStylesAndAttributes('span', { cursor: 'pointer', marginLeft: '30px', width: '11px', height: '11px', display: 'inline-block', verticalAlign: 'middle' }, { innerHTML: `<svg xmlns="http://www.w3.org/2000/svg" height="1em" fill="currentColor" viewBox="0 0 334 334"><path d="M 320 48 Q 334 31 320 14 Q 303 0 286 14 L 167 133 L 48 14 Q 31 0 14 14 Q 0 31 14 48 L 133 167 L 14 286 Q 0 303 14 320 Q 31 334 48 320 L 167 201 L 286 320 Q 303 334 320 320 Q 334 303 320 286 L 201 167 L 320 48 L 320 48 Z" /></svg>` });const settingsParameters = createElementWithStylesAndAttributes('div', { color: "#4B5563", textAlign: "center", marginBottom: "10px", fontSize: "24px", textShadow: "1px 1px #888888", fontWeight: "bold", cursor: "pointer", userSelect: "none" }, { className: 'settingsParameters', innerText: '参数' });const additionalFeatures = createElementWithStylesAndAttributes('div', { color: "#4B5563", textAlign: "center", marginBottom: "10px", fontSize: "20px", fontWeight: "bold", cursor: "pointer", userSelect: "none" }, { className: 'additionalFeatures', innerText: '高级' });const shortcutKeys = createElementWithStylesAndAttributes('div', { color: "#4B5563", textAlign: "center", marginBottom: "10px", fontSize: "20px", fontWeight: "bold", cursor: "pointer", userSelect: "none" }, { className: 'shortcutKeys', innerText: '操作' });const selectTheContainer = createElementWithStylesAndAttributes('div', { display: "flex", justifyContent: "space-around" }, {});const showcaseFeaturesPanel1 = createShowcaseFeaturesPanel('panel1', 0);const showcaseFeaturesPanel2 = createShowcaseFeaturesPanel('panel2', 280);const showcaseFeaturesPanel3 = createShowcaseFeaturesPanel('panel3', 560);createFeatureListItems(parameterFunction).forEach(featureElement => {showcaseFeaturesPanel1.appendChild(featureElement);});createFeatureListItems(additionalFeaturesFunction).forEach(featureElement => {showcaseFeaturesPanel2.appendChild(featureElement);});createFeatureListItems(shortcutKeysFunction).forEach(featureElement => {showcaseFeaturesPanel3.appendChild(featureElement);});settingsParameters.addEventListener('click', () => setActivePanel('panel1'));additionalFeatures.addEventListener('click', () => setActivePanel('panel2'));shortcutKeys.addEventListener('click', () => setActivePanel('panel3'));closeSetting.addEventListener('click', () => { loadingPanel.style.display = 'none'; });addStyle('custom-font-style', font_style);var stats = new Stats();stats.dom.style.cssText = 'position: absolute; display: block; bottom: 10px; left: 10px; ';showcaseFeaturesPanel2.appendChild(stats.dom);stats.showPanel(0);settingsParameters.addEventListener('click', () => setActivePanel('panel1'));additionalFeatures.addEventListener('click', () => setActivePanel('panel2'));shortcutKeys.addEventListener('click', () => setActivePanel('panel3'));loadingPanel.appendChild(title);title.appendChild(closeSetting);selectTheContainer.appendChild(settingsParameters);selectTheContainer.appendChild(additionalFeatures);selectTheContainer.appendChild(shortcutKeys);loadingPanel.appendChild(selectTheContainer);loadingPanel.appendChild(showcaseFeaturesPanel);loadingPanel.appendChild(versionInfoElement);showcaseFeaturesPanel.appendChild(showcaseFeaturesPanel1);showcaseFeaturesPanel.appendChild(showcaseFeaturesPanel2);showcaseFeaturesPanel.appendChild(showcaseFeaturesPanel3);document.body.appendChild(loadingPanel);GM_registerMenuCommand('显示/隐藏 参数与功能设置菜单', function() {loadingPanel.style.display = loadingPanel.style.display === 'none' ? 'block' : 'none';});animate();document.addEventListener('touchstart', function(e) {touchStartX = e.changedTouches[0].screenX;touchStartY = e.changedTouches[0].screenY;});if (GM_getValue('mobileGestures', true)) {document.addEventListener('touchmove', function(e) {let touchMoveX = e.changedTouches[0].screenX;let touchMoveY = e.changedTouches[0].screenY;let moveRightDistance = touchMoveX - touchStartX;let moveLeftDistance = touchStartX - touchMoveX;let moveYDistance = Math.abs(touchMoveY - touchStartY);if (moveYDistance > 100) {iconVisible = false;divForward.firstChild.style.right = '100%';divBack.firstChild.style.left = '100%';return;}if (moveRightDistance > 50 && !iconVisible) {iconVisible = true;divBack.firstChild.style.left = '-20px';} else if (moveRightDistance <= 50 && iconVisible) {iconVisible = false;divBack.firstChild.style.left = '100%';}if (iconVisible && moveRightDistance <= 100) {divBack.firstChild.style.left = `${0.8 * (moveRightDistance - 50)}px`;} else if (moveRightDistance > 100) {divBack.firstChild.style.left = '-20px';}if (moveLeftDistance > 50 && !iconVisible) {iconVisible = true;divForward.firstChild.style.right = '-20px';} else if (moveLeftDistance <= 50 && iconVisible) {iconVisible = false;divForward.firstChild.style.right = '100%';}if (iconVisible && moveLeftDistance <= 100) {divForward.firstChild.style.right = `${0.8 * (moveLeftDistance - 50)}px`;} else if (moveLeftDistance > 100) {divForward.firstChild.style.right = '-20px';}});}document.addEventListener('touchend', function(e) {let touchEndX = e.changedTouches[0].screenX;let touchEndY = e.changedTouches[0].screenY;let touchDistance = touchEndX - touchStartX;let touchYDistance = Math.abs(touchEndY - touchStartY);if (touchYDistance > 100) {return;}if (touchDistance > 150) {handleBackNavigation();}if (touchDistance < -150) {handleForwardNavigation();}iconVisible = false;divBack.firstChild.style.left = '100%';divForward.firstChild.style.right = '100%';});document.addEventListener('keydown', function(e) {var returnShortcutKeyString = GM_getValue('backToThePreviousPage', 'shift+r').toLowerCase();var returnShortcutKeys = returnShortcutKeyString.split('+').map(key => key.toLowerCase());var directShortcutKeyString = GM_getValue('goToTheCorrespondingPage', 'shift+e').toLowerCase();var directShortcutKeys = directShortcutKeyString.split('+').map(key => key.toLowerCase());var forwardShortcutKey = GM_getValue('forward', 'shift+f').toLowerCase();var forwardShortcutKeys = forwardShortcutKey.split('+').map(key => key.toLowerCase());var loadingShortcutKey = GM_getValue('setShortcuts', 'shift+s').toLowerCase();var loadingShortcutKeys = loadingShortcutKey.split('+').map(key => key.toLowerCase());var keyPressed = {'alt': e.altKey,'shift': e.shiftKey,'control': e.ctrlKey,'meta': e.metaKey // 对于 Mac 的 Command 键};keyPressed[e.key.toLowerCase()] = true;var returnKeysPressed = returnShortcutKeys.every(key => keyPressed[key]);var directKeysPressed = directShortcutKeys.every(key => keyPressed[key]);var forwardKeysPressed = forwardShortcutKeys.every(key => keyPressed[key]);var loadingKeysPressed = loadingShortcutKeys.every(key => keyPressed[key]);if (returnKeysPressed) {handleBackNavigation(); // 对应的操作函数}if (directKeysPressed) {navigateToURL(); // 对应的操作函数}if (forwardKeysPressed) {handleForwardNavigation(); // 对应的操作函数}if (loadingKeysPressed) {loadingPanel.style.display = loadingPanel.style.display === 'none' ? 'block' : 'none';}});var debouncedScrollHandler = debounce(function() {cleanPreloadQueue();cleanAbortControllers();preloadVisibleLinks();checkAndAddBulletsForPreloadedLinks();}, 10);var debouncedScrollHandlerPC = debounce(function() {cleanPreloadQueue();cleanAbortControllers();checkAndAddBulletsForPreloadedLinks();}, 10);document.addEventListener('click', function(event) {var target = event.target.closest('a');if (target && target.href) {event.preventDefault();if (event.ctrlKey && !event.shiftKey) {// 用户按下了Ctrl键并点击了链接 - 在后台新标签页中打开window.open(target.href);} else if (event.shiftKey) {// 用户按下了Shift键并点击了链接 - 在前台新标签页中打开window.open(target.href, '_blank');} else {// 正常点击 - 不打开新标签页,遵循预加载逻辑以下或直接导航到链接地址if (!clickedLinks.includes(target.href)) {clickedLinks.push(target.href);}currentPreviewIndex = clickedLinks.indexOf(target.href);if (target.dataset.preloaded) {readContentFromDB(target.href, function(data) {if (data) {displayPreloadedContent(data.htmlContent, target.href);} else {location.href = target.href;}});} else {location.href = target.href;}}}});observeDOMChanges();openDB();startLinkPreloading();initDB(function() {deleteOldContentFromDB();scheduleNextCleanup();});if (isMobileDevice()) {GM_setValue('mobileGestures', false);window.addEventListener('touchend', debouncedScrollHandler);if (GM_getValue('manipulatorBall')) {addDraggableIcon();document.getElementById('draggableIcon').onclick = handleBackNavigation;}} else {window.addEventListener('scroll', debouncedScrollHandlerPC);setupMouseHoverPreload();if (GM_getValue('manipulatorBall', true)) {addDraggableIcon();document.getElementById('draggableIcon').onclick = handleBackNavigation;}}})();