您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
點擊時才偵測 localStorage.KEY,並提供匯出/匯入 JSON 功能(改善 script 延遲載入問題)
// ==UserScript== // @name sniperex168.blogspot.com LocalStorage 選項記錄 匯出/匯入工具 // @namespace http://tampermonkey.net/ // @version 2.1 // @description 點擊時才偵測 localStorage.KEY,並提供匯出/匯入 JSON 功能(改善 script 延遲載入問題) // @author HrJasn // @match *://sniperex168.blogspot.com/* // @grant none // @license GPL3 // @license Copyright HrJasn // ==/UserScript== console.log("載入 sniperex168.blogspot.com LocalStorage 選項記錄 匯出匯入工具"); (function () { console.log("執行 sniperex168.blogspot.com LocalStorage 選項記錄 匯出匯入工具"); // ✅ 只有點擊時才找 script 內的 localStorage key function findLocalStorageKey() { // 在 UserScript 中「共用」的變數 let foundKey = null; // 取得原本的 localStorage 物件 const originalLocalStorage = window.localStorage; // 用 Proxy 包裝整個 localStorage,攔截所有屬性賦值(包括 .ED9Kaidata = ... 這種) const proxyLocalStorage = new Proxy(originalLocalStorage, { set(target, prop, value) { console.log(`✅ localStorage 被修改: key=${String(prop)}, value=${value}`); if (!foundKey) { foundKey = String(prop); console.log(`✅ 找到的 localStorage Key: ${foundKey}`); cleanup(); } target[prop] = value; // 實際執行賦值 return true; } }); // 替換 window.localStorage 為 Proxy 物件 Object.defineProperty(window, 'localStorage', { configurable: true, enumerable: true, get() { return proxyLocalStorage; } }); const confirmElements = document.querySelectorAll('.confirm'); function cleanup() { // 恢復原本的 localStorage Object.defineProperty(window, 'localStorage', { configurable: true, enumerable: true, value: originalLocalStorage }); console.log('🛑 已恢復原本的 localStorage 物件'); } (async function autoTriggerEachConfirm() { for (let el of confirmElements) { if (foundKey) break; const originalChecked = el.checked; // 嘗試改變勾選 el.checked = !el.checked; console.log('🛑 嘗試異動勾選狀態', el, originalChecked, el.checked); el.dispatchEvent(new Event('change', { bubbles: true })); await new Promise(r => setTimeout(r, 100)); // 恢復勾選 console.log('🛑 恢復勾選狀態', el, el.checked, originalChecked); el.checked = originalChecked; el.dispatchEvent(new Event('change', { bubbles: true })); await new Promise(r => setTimeout(r, 100)); if (foundKey) break; } if (!foundKey) { alert('❌ 沒有找到任何 localStorage Key'); cleanup(); } })(); return foundKey; } // 加入樣式 const style = document.createElement('style'); style.textContent = ` #json-buttons { position: fixed !important; bottom: 100px !important; right: 20px !important; display: flex !important; flex-direction: column !important; gap: 10px !important; z-index: 2147483647 !important; } .json-btn { padding: 8px 12px; font-size: 14px; background-color: #777; color: white; border: none; border-radius: 5px; cursor: pointer; } .json-btn:hover { background-color: #000; } `; document.head.appendChild(style); // 建立按鈕區塊 const container = document.createElement('div'); container.id = 'json-buttons'; const exportBtn = document.createElement('button'); exportBtn.className = 'json-btn'; exportBtn.textContent = '匯出選項記錄JSON'; const importBtn = document.createElement('button'); importBtn.className = 'json-btn'; importBtn.textContent = '匯入選項記錄JSON'; const fileInput = document.createElement('input'); fileInput.type = 'file'; fileInput.accept = '.json'; fileInput.style.display = 'none'; container.appendChild(exportBtn); container.appendChild(importBtn); container.appendChild(fileInput); document.body.appendChild(container); // 匯出功能 exportBtn.addEventListener('click', () => { const detectedKey = findLocalStorageKey(); if (!detectedKey) { alert(`找不到 localStorage.Key`); return; } let data = localStorage.getItem(detectedKey); if (!data) { alert(`找不到 localStorage.${detectedKey} 的資料`); return; } let jsondata = JSON.parse(data); jsondata = [...new Set(jsondata)]; jsondata.sort(); data = JSON.stringify(jsondata); // 產生時間戳記 yyyyMMdd-HHmmss const now = new Date(); const pad = (n) => n.toString().padStart(2, '0'); const timestamp = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`; // 網址轉為合法檔名 const urlPart = window.location.href.replace(/[^a-zA-Z0-9]+/g, '_'); // 完整檔名 const filename = `${urlPart}_${detectedKey}-${timestamp}.json`; const blob = new Blob([data], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); }); // 匯入功能 importBtn.addEventListener('click', () => { fileInput.click(); }); fileInput.addEventListener('change', (event) => { const detectedKey = findLocalStorageKey(); if (!detectedKey) return; const file = event.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = (e) => { try { const json = JSON.parse(e.target.result); localStorage.setItem(detectedKey, JSON.stringify(json)); const confirms = document.querySelectorAll('.confirm'); let storagetemp = JSON.parse(localStorage.getItem(detectedKey)); if (storagetemp !== undefined) { confirms.forEach((elem) => { let chkstts = false; storagetemp.forEach((item) => { if (elem.name == item) { chkstts = true; elem.scrollIntoView({ behavior: "smooth", block: "center" // 可選值: "start", "center", "end", "nearest" }); } }); elem.checked = chkstts; }); } storagetemp = [...new Set(storagetemp)]; storagetemp.sort(); console.log(`匯入成功:已寫入 localStorage.${detectedKey}`); } catch (err) { alert('匯入失敗:',err); console.log('匯入失敗:',err); } }; reader.readAsText(file); }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址