您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
自动套转 vpn
// ==UserScript== // @name 自动跳转vpn 公司自用 // @version 2025-7-31 // @description 自动套转 vpn // @author joans // @match https://supnet.menusifu.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=menusifu.com // @grant none // @license MIT // @namespace https://greasyfork.org/users/1368348 // ==/UserScript== (function () { 'use strict' // 配置选项 const config = { buttonName: '搜索', // 要监控的按钮名称 checkInterval: 1000, // 检查间隔(毫秒) maxChecks: 30, // 最大检查次数(0=无限) debug: true, // 显示调试信息 highlightButton: true, // 高亮显示找到的按钮 preventDoubleClick: true, // 防止双击 } // 日志函数 const log = config.debug ? (...args) => console.log('[搜索监控]', ...args) : () => {} log(`开始监控名称为"${config.buttonName}"的按钮...`) let checkCount = 0 let clickHandlerAttached = false // 创建监控定时器 const intervalId = setInterval(() => { if (config.maxChecks > 0 && checkCount >= config.maxChecks) { log(`已达最大检查次数 (${config.maxChecks}),停止监控`) clearInterval(intervalId) return } checkCount++ log(`第 ${checkCount} 次检查`) // 查找所有按钮元素 const buttons = document.querySelectorAll( 'button, input[type="button"], input[type="submit"], a' ) let targetButton = null // 遍历按钮查找目标 for (const button of buttons) { const buttonText = getButtonText(button) if (buttonText.includes(config.buttonName)) { log(`发现目标按钮: "${buttonText}"`) targetButton = button break } } // 如果找到按钮 if (targetButton && !targetButton.dataset.monitored) { // 绑定点击事件 attachClickHandler(targetButton) // 标记按钮已处理 targetButton.dataset.monitored = 'true' // 高亮按钮 if (config.highlightButton) { highlightSearchButton(targetButton) } // 停止监控 clearInterval(intervalId) log('监控结束') } }, config.checkInterval) // 获取按钮文本 function getButtonText(button) { // 不同按钮类型的文本获取方式 if (button.tagName === 'INPUT') { return button.value || '' } else if (button.tagName === 'A') { return button.innerText || button.textContent || '' } else { return button.innerText || button.textContent || button.title || '' } } // 绑定点击事件处理函数 function attachClickHandler(button) { log('绑定点击事件处理函数') // 自定义点击处理逻辑 const customClickHandler = function (event) { log(`"${config.buttonName}"按钮被点击`) // === 在这里添加你的自定义处理逻辑 === var targetNode = document.querySelector('tbody') var delay = null // 创建一个观察者对象 const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (delay) { clearTimeout(delay) } log('2') // 检测到数据更新后,执行相应的逻辑 // 这里可以执行数据更新后的逻辑 const runS = () => { console.log('runS') var ipAddrs = document.querySelectorAll('[title="复制 IP"]') log(ipAddrs) var toBtu = document.querySelectorAll('.toLinkbtn') for (let j = 0; j < toBtu.length; j++) { toBtu[j].remove() } //ipAddr.insertAdjacentHTML("beforeend", "<p>Hello, World!</p>"); for (let i = 0; i < ipAddrs.length; i++) { console.log(ipAddrs[i].parentElement.textContent) console.log( ipAddrs[i].classList.contains('toLinkbtn') ) ipAddrs[i].parentElement.insertAdjacentHTML( 'beforeend', "<button class='toLinkbtn' type='button' style='background: none;border: none;' ><a href='http://" + ipAddrs[i].parentElement.textContent + ":22080/' target='_blank'><svg t='1729050846044' class='icon' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='4593' width='12' height='12'><path d='M590.665387 86.129778v178.119111c-390.144 0-713.386667 129.649778-544.995556 703.260444-26.396444-358.570667 147.456-471.096889 544.995556-471.096889v174.762667a30.606222 30.606222 0 0 0 52.451555 21.959111l371.768889-291.783111a31.232 31.232 0 0 0 0-44.032l-371.768889-293.205333a30.606222 30.606222 0 1 0-52.451555 22.016z' fill='#666666' p-id='4594'></path></svg><a></button>" ) } observer.disconnect() } delay = setTimeout(runS, 500) }) }) // 观察者的配置(观察目标节点的子节点的变化) const configL = { childList: true, subtree: true } // 传入目标节点和观察选项并开始观察 observer.observe(targetNode, configL) // 防止双击 if (config.preventDoubleClick) { button.disabled = true setTimeout(() => { button.disabled = false }, 2000) } } // 绑定事件监听器 button.addEventListener('click', customClickHandler) } // 高亮搜索按钮 function highlightSearchButton(button) { button.style.transition = 'all 0.3s ease' button.style.boxShadow = '0 0 0 3px rgba(66, 133, 244, 0.5)' button.style.border = '2px solid #4285F4' button.style.borderRadius = '4px' // 添加脉动动画 let pulseCount = 0 const pulse = setInterval(() => { pulseCount++ if (pulseCount > 3) { clearInterval(pulse) return } button.style.boxShadow = '0 0 0 8px rgba(66, 133, 244, 0.3)' setTimeout(() => { button.style.boxShadow = '0 0 0 3px rgba(66, 133, 244, 0.5)' }, 500) }, 1000) log('已添加高亮效果') } // 显示通知 function showNotification(message) { const notification = document.createElement('div') notification.textContent = message notification.style.cssText = ` position: fixed; top: 20px; right: 20px; padding: 12px 20px; background: #4285F4; color: white; border-radius: 4px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 10000; font-family: Arial, sans-serif; font-size: 14px; animation: fadeIn 0.3s, fadeOut 0.3s 2.7s; ` // 添加动画样式 const style = document.createElement('style') style.textContent = ` @keyframes fadeIn { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeOut { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(-20px); } } ` document.head.appendChild(style) document.body.appendChild(notification) // 3秒后移除通知 setTimeout(() => { notification.remove() style.remove() }, 3000) } })();