您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在页面中添加一个随机密码生成器,可以生成密码并记录历史记录,提供显示/隐藏功能和拖动按钮功能。
// ==UserScript== // @name 随机密码生成器 // @namespace http://tampermonkey.net/ // @version 1.5.1 // @description 在页面中添加一个随机密码生成器,可以生成密码并记录历史记录,提供显示/隐藏功能和拖动按钮功能。 // @author wll // @match *://*/* // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @license AGPL-3.0-or-later // ==/UserScript== /* ### 脚本特点及好处: - **在页面中添加一个随机密码生成器**:生成器可以生成复杂的随机密码。 - **记录历史记录**:生成的密码会记录在历史记录中,并可以删除特定记录。 - **提供显示/隐藏功能**:通过油猴菜单命令控制生成器打开按钮的显示或隐藏状态。 - **拖动按钮功能**:生成器打开按钮可以拖动,并记录其拖动后的位置信息,防止拖动出页面之外。 */ (function() { 'use strict'; const settingsKey = 'passwordGeneratorSettings'; const historyKey = 'passwordGeneratorHistory'; const positionKey = 'buttonPosition'; const buttonVisibleKey = 'buttonVisible'; // 读取设置 function loadSettings() { const settings = GM_getValue(settingsKey, null); return settings ? JSON.parse(settings) : { upper: false, lower: false, numbers: false, special: false, minLength: 8, maxLength: 12, quantity: 1 }; } // 保存设置 function saveSettings(settings) { GM_setValue(settingsKey, JSON.stringify(settings)); } // 读取历史记录 function loadHistory() { const history = GM_getValue(historyKey, null); return history ? JSON.parse(history) : []; } // 保存历史记录 function saveHistory(history) { GM_setValue(historyKey, JSON.stringify(history)); } // 读取按钮位置 function loadPosition() { return GM_getValue(positionKey, { top: '10px', right: '10px' }); } // 保存按钮位置 function savePosition(position) { GM_setValue(positionKey, position); } // 读取按钮可见状态 function loadButtonVisible() { return GM_getValue(buttonVisibleKey, true); } // 保存按钮可见状态 function saveButtonVisible(visible) { GM_setValue(buttonVisibleKey, visible); } const settings = loadSettings(); const history = loadHistory(); let buttonVisible = loadButtonVisible(); // 创建按钮打开密码生成器 const button = document.createElement('button'); button.innerText = '打开密码生成器'; button.style.position = 'fixed'; button.style.zIndex = '1000'; button.style.padding = '10px 20px'; button.style.backgroundColor = '#4CAF50'; button.style.color = 'white'; button.style.border = 'none'; button.style.borderRadius = '5px'; button.style.cursor = 'pointer'; const savedPosition = loadPosition(); button.style.top = savedPosition.top; button.style.right = savedPosition.right; if (buttonVisible) { document.body.appendChild(button); } // 注册(不可用)油猴菜单命令 GM_registerMenuCommand('显示/隐藏菜单按钮', () => { buttonVisible = !buttonVisible; if (buttonVisible) { document.body.appendChild(button); } else { if (button.parentNode) { button.parentNode.removeChild(button); } } saveButtonVisible(buttonVisible); }); // 创建生成器界面 const generatorDiv = document.createElement('div'); generatorDiv.style.display = 'none'; generatorDiv.style.position = 'fixed'; generatorDiv.style.top = '50%'; generatorDiv.style.left = '50%'; generatorDiv.style.transform = 'translate(-50%, -50%)'; generatorDiv.style.padding = '20px'; generatorDiv.style.backgroundColor = 'white'; generatorDiv.style.border = '1px solid #ccc'; generatorDiv.style.zIndex = '1000'; generatorDiv.style.boxShadow = '0px 0px 10px rgba(0,0,0,0.1)'; generatorDiv.style.textAlign = 'center'; generatorDiv.style.width = '300px'; generatorDiv.style.maxHeight = '400px'; generatorDiv.style.overflow = 'auto'; document.body.appendChild(generatorDiv); // 添加选项 generatorDiv.innerHTML = ` <div style="position: relative;"> <h2>随机密码生成器</h2> <button id="close" style="position: absolute; top: 10px; right: 10px; background: none; border: none; font-size: 16px; cursor: pointer;">✖</button> </div> <div style="text-align: left; border-bottom: 1px solid #ccc; padding-bottom: 10px;"> <h3>选项</h3> <label><input type="checkbox" id="upper"> 字母大写</label><br> <label><input type="checkbox" id="lower"> 字母小写</label><br> <label><input type="checkbox" id="numbers"> 数字</label><br> <label><input type="checkbox" id="special"> 特殊字符</label><br> <label>生成长度:<input type="number" id="minLength" value="${settings.minLength}" min="1" style="width: 50px;"> 到 <input type="number" id="maxLength" value="${settings.maxLength}" min="1" style="width: 50px;"></label><br> <label>生成数量:<input type="number" id="quantity" value="${settings.quantity}" min="1" style="width: 50px;"></label><br> <button id="generate" style="margin-top: 10px; padding: 5px 10px; background-color: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer;">生成密码</button><br> </div> <div style="text-align: left; border-bottom: 1px solid #ccc; padding-bottom: 10px; margin-top: 10px;"> <h3>生成的密码</h3> <div id="passwordOutput" style="width: 100%; margin-top: 10px;"></div> </div> <div style="text-align: left; margin-top: 10px;"> <h3>历史记录</h3> <div id="historyOutput" style="width: 100%; margin-top: 10px; max-height: 100px; overflow-y: auto;"></div> </div> `; // 提示框 const toast = document.createElement('div'); toast.style.position = 'fixed'; toast.style.bottom = '20px'; toast.style.right = '20px'; toast.style.backgroundColor = 'rgba(0,0,0,0.7)'; toast.style.color = 'white'; toast.style.padding = '10px'; toast.style.borderRadius = '5px'; toast.style.zIndex = '1001'; toast.style.display = 'none'; document.body.appendChild(toast); // 显示提示 function showToast(message) { toast.innerText = message; toast.style.display = 'block'; setTimeout(() => { toast.style.display = 'none'; }, 3000); } // 生成密码 function generatePassword() { const upper = document.getElementById('upper').checked; const lower = document.getElementById('lower').checked; const numbers = document.getElementById('numbers').checked; const special = document.getElementById('special').checked; const minLength = parseInt(document.getElementById('minLength').value); const maxLength = parseInt(document.getElementById('maxLength').value); const quantity = parseInt(document.getElementById('quantity').value); const upperChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; const lowerChars = 'abcdefghijklmnopqrstuvwxyz'; const numberChars = '0123456789'; const specialChars = '!@#$%^&*()_+[]{}|;:,.<>?'; let allChars = ''; if (upper) allChars += upperChars; if (lower) allChars += lowerChars; if (numbers) allChars += numberChars; if (special) allChars += specialChars; if (allChars === '') { showToast('请至少选择一种复杂度类型!'); return []; } const passwords = []; for (let j = 0; j < quantity; j++) { const passwordLength = Math.floor(Math.random() * (maxLength - minLength + 1)) + minLength; let password = ''; for (let i = 0; i < passwordLength; i++) { password += allChars.charAt(Math.floor(Math.random() * allChars.length)); } passwords.push(password); } return passwords; } // 复制到剪贴板 function copyToClipboard(text) { const textarea = document.createElement('textarea'); textarea.value = text; document.body.appendChild(textarea); textarea.select(); document.execCommand('copy'); document.body.removeChild(textarea); showToast('密码已复制到剪贴板!'); } // 更新UI function updateOutput(passwords) { const output = document.getElementById('passwordOutput'); output.innerHTML = passwords.map((pwd, index) => ` <div style="display: flex; justify-content: space-between; align-items: center;"> <span>${pwd}</span> <button class="copy" data-password="${pwd}" style="background: none; border: none; color: blue; cursor: pointer;">复制</button> </div> `).join(''); } function updateHistoryOutput() { const output = document.getElementById('historyOutput'); output.innerHTML = history.map((pwd, index) => ` <div style="display: flex; justify-content: space-between; align-items: center;"> <span>${pwd}</span> <button class="delete" data-index="${index}" style="background: none; border: none; color: red; cursor: pointer;">删除</button> </div> `).join(''); } // 点击事件 button.addEventListener('click', () => { generatorDiv.style.display = generatorDiv.style.display === 'none' ? 'block' : 'none'; }); document.getElementById('close').addEventListener('click', () => { generatorDiv.style.display = 'none'; }); document.getElementById('generate').addEventListener('click', () => { const passwords = generatePassword(); updateOutput(passwords); // 保存设置 const settings = { upper: document.getElementById('upper').checked, lower: document.getElementById('lower').checked, numbers: document.getElementById('numbers').checked, special: document.getElementById('special').checked, minLength: parseInt(document.getElementById('minLength').value), maxLength: parseInt(document.getElementById('maxLength').value), quantity: parseInt(document.getElementById('quantity').value) }; saveSettings(settings); }); document.getElementById('passwordOutput').addEventListener('click', (e) => { if (e.target.classList.contains('copy')) { const password = e.target.getAttribute('data-password'); copyToClipboard(password); history.push(password); saveHistory(history); updateHistoryOutput(); } }); document.getElementById('historyOutput').addEventListener('click', (e) => { if (e.target.classList.contains('delete')) { const index = parseInt(e.target.getAttribute('data-index')); history.splice(index, 1); saveHistory(history); updateHistoryOutput(); } }); // 使按钮可拖动 button.addEventListener('mousedown', (e) => { e.preventDefault(); let offsetX = e.clientX - button.getBoundingClientRect().left; let offsetY = e.clientY - button.getBoundingClientRect().top; function mouseMoveHandler(e) { let newX = e.clientX - offsetX; let newY = e.clientY - offsetY; let maxX = window.innerWidth - button.offsetWidth; let maxY = window.innerHeight - button.offsetHeight; newX = Math.max(0, Math.min(newX, maxX)); newY = Math.max(0, Math.min(newY, maxY)); button.style.left = `${newX}px`; button.style.top = `${newY}px`; button.style.right = 'auto'; } function mouseUpHandler() { savePosition({ top: button.style.top, left: button.style.left }); document.removeEventListener('mousemove', mouseMoveHandler); document.removeEventListener('mouseup', mouseUpHandler); } document.addEventListener('mousemove', mouseMoveHandler); document.addEventListener('mouseup', mouseUpHandler); }); // 初始化 document.getElementById('upper').checked = settings.upper; document.getElementById('lower').checked = settings.lower; document.getElementById('numbers').checked = settings.numbers; document.getElementById('special').checked = settings.special; document.getElementById('minLength').value = settings.minLength; document.getElementById('maxLength').value = settings.maxLength; document.getElementById('quantity').value = settings.quantity; updateHistoryOutput(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址