// ==UserScript== // @name click it for you // @name:zh-TW click it for you // @name:ja あなたのためにクリック // @name:en click it for you // @name:ko 당신을 위해 클릭 // @name:es Clic automático para ti // @description 在符合正則表達式的網址上自動點擊指定的元素。 // @description:zh-TW 在符合正則表達式的網址上自動點擊指定的元素。 // @description:ja 正規表現に一致するURLで指定された要素を自動的にクリックします。 // @description:en Automatically clicks specified elements on URLs matching a regular expression. // @description:ko 정규 표현식과 일치하는 URL에서 지정된 요소를 자동으로 클릭합니다. // @description:es Hace clic automáticamente en elementos especificados en URLs que coinciden con una expresión regular. // @author Max // @namespace https://github.com/Max46656 // @match *://*/* // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // @grant GM_info // @version 1.0.0 // @license MPL2.0 // @downloadURL none // ==/UserScript== class AutoClickManager { constructor() { this.clickRules = GM_getValue('clickRules', []); this.init(); } clickRules; init(){ this.registerMenu(); this.runAutoClicks(); } // 儲存組態至本地存儲 saveConfigs() { GM_setValue('clickRules', this.clickRules); } // 根據選擇器類型獲取元素 getElements(selectorType, selector) { if (selectorType === 'xpath') { const nodes = document.evaluate(selector, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); const elements = []; for (let i = 0; i < nodes.snapshotLength; i++) { elements.push(nodes.snapshotItem(i)); } return elements; } else if (selectorType === 'css') { return Array.from(document.querySelectorAll(selector)); } return []; } // 執行單條規則的自動點擊 autoClick(rule) { const urlRegex = new RegExp(rule.urlPattern); if (!urlRegex.test(window.location.href)) { return; } const elements = this.getElements(rule.selectorType, rule.selector); if (elements.length === 0) { console.warn(`${GM_info.script.name}:"${rule.ruleName}" 未找到符合元素:`, rule.selector); return; } if (rule.nthElement < 1 || rule.nthElement > elements.length) { console.warn(`${GM_info.script.name}:"${rule.ruleName}" 的 nthElement 無效:${rule.nthElement},找到 ${elements.length} 個元素`); return; } const targetElement = elements[rule.nthElement - 1]; if (targetElement) { console.log(`${GM_info.script.name}:"${rule.ruleName}" 點擊元素:`, targetElement); targetElement.click(); } else { console.warn(`${GM_info.script.name}:"${rule.ruleName}" 未找到目標元素`); } } // 執行所有符合規則的自動點擊 runAutoClicks() { this.clickRules.rules.forEach((rule, index) => { if (rule.urlPattern && rule.selector) { setTimeout(() => this.autoClick(rule), rule.clickDelay || 1000); } else { console.warn(`${GM_info.script.name}:"${rule.ruleName}" 無效(索引 ${index}):缺少 urlPattern 或 selector`); } }); } // 創建組態選單 createMenu() { const menu = document.createElement('div'); menu.style.position = 'fixed'; menu.style.top = '10px'; menu.style.right = '10px'; menu.style.background = 'rgb(36, 36, 36)'; menu.style.color = 'rgb(204, 204, 204)'; menu.style.border = '1px solid rgb(80, 80, 80)'; menu.style.padding = '10px'; menu.style.zIndex = '10000'; menu.style.maxWidth = '400px'; menu.style.boxShadow = '0 0 10px rgba(0,0,0,0.5)'; menu.innerHTML = `

設定自動點擊

新增規則

`; document.body.appendChild(menu); // 更新規則列表 this.updateRulesList(); // 新增規則按鈕事件 document.getElementById('addRule').addEventListener('click', () => { const newRule = { ruleName: document.getElementById('ruleName').value || `規則 ${this.clickRules.rules.length + 1}`, urlPattern: document.getElementById('urlPattern').value, selectorType: document.getElementById('selectorType').value, selector: document.getElementById('selector').value, nthElement: parseInt(document.getElementById('nthElement').value) || 1, clickDelay: parseInt(document.getElementById('clickDelay').value) || 1000 }; this.clickRules.rules.push(newRule); this.saveConfigs(); this.updateRulesList(); document.getElementById('ruleName').value = ''; document.getElementById('urlPattern').value = ''; document.getElementById('selector').value = ''; document.getElementById('nthElement').value = '1'; document.getElementById('clickDelay').value = '1000'; }); // 關閉選單按鈕事件 document.getElementById('closeMenu').addEventListener('click', () => { menu.remove(); }); } // 更新規則列表(僅顯示當前網址符合的規則) updateRulesList() { const rulesList = document.getElementById('rulesList'); rulesList.innerHTML = '

符合的規則

'; const currentUrl = window.location.href; const matchingRules = this.clickRules.rules.filter(rule => { try { return new RegExp(rule.urlPattern).test(currentUrl); } catch (e) { console.error(`${GM_info.script.name}:規則 "${rule.ruleName}" 的正則表達式無效:`, rule.urlPattern); return false; } }); if (matchingRules.length === 0) { rulesList.innerHTML += '

當前網址無符合的規則。

'; return; } matchingRules.forEach((rule, index) => { const globalIndex = this.clickRules.rules.indexOf(rule); const ruleDiv = document.createElement('div'); ruleDiv.innerHTML = `
${rule.ruleName || `規則 ${globalIndex + 1}`}
`; rulesList.appendChild(ruleDiv); // 為規則標題添加點擊事件(縮小/展開) document.getElementById(`ruleHeader${globalIndex}`).addEventListener('click', () => { const details = document.getElementById(`ruleDetails${globalIndex}`); details.style.display = details.style.display === 'none' ? 'block' : 'none'; }); // 為刪除按鈕添加點擊事件 document.getElementById(`deleteRule${globalIndex}`).addEventListener('click', () => { this.clickRules.rules.splice(globalIndex, 1); this.saveConfigs(); this.updateRulesList(); }); }); } // 註冊選單命令 registerMenu() { GM_registerMenuCommand('組態自動點擊', () => this.createMenu()); } } const johnTheYubisaku = new AutoClickManager();