您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
记录网站密码信息并自动填充
// ==UserScript== // @name 记录账号和密码 // @version 0.5.5 // @description 记录网站密码信息并自动填充 // @author niweizhuan // @match *://*/* // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_listValues // @grant GM_addStyle // @grant unsafeWindow // @license MIT // @namespace https://bbs.tampermonkey.net.cn/ // ==/UserScript== (function() { 'use strict'; // 是否自动填充密码 var autoFillEnabled = true; // 当前显示的页面索引 var currentPageIndex = 0; // 显示区域的 DOM 元素 var displayAreaDiv; // 当前网站域名 var currentDomain = getCurrentDomain(); //上下页按钮 var prevPageButton; var nextPageButton; //---------------------------------------------- // 获取当前网站的域名 function getCurrentDomain() { return window.location.hostname; } // 获取存储 function getStoredData(domain) { var data = GM_getValue(domain); if (!data) return { accounts: [], priority: 0 }; // 如果没有数据,返回默认值 try { data = JSON.parse(data); } catch (error) { alert("记录账号和密码:数据解析错误: “", error , "”已删除该条数据"); GM_deleteValue(domain); // 删除无效的存储数据 return { accounts: [], priority: 0 }; // 如果解析失败,返回默认值 } // 处理旧版本数据(如果 data 是一个数组,则将其包装成包含 priority 的对象) if (Array.isArray(data)) { data = { accounts: data, priority: 0 }; } // 确保优先级字段存在 if (typeof data.priority === 'undefined') { data.priority = 0; } // 检查 accounts 的格式是否正确 if (!Array.isArray(data.accounts)) { alert("记录账号和密码:accounts 格式不正确,已删除无效数据"); GM_deleteValue(domain); // 删除无效的存储数据 return { accounts: [], priority: data.priority }; // 格式不正确,返回默认 accounts } // 验证每个账户的格式,确保有 username 和 password data.accounts = data.accounts.filter(account => { if (typeof account.username === 'string' && typeof account.password === 'string') { return true; // 格式正确,保留此账户 } else { alert("记录账号和密码:账户数据格式错误,已删除: ", account); GM_deleteValue(domain); // 删除无效的存储数据 return false; // 格式不正确,删除此账户 } }); return data; } // 设置存储 function setStoredData(domain, data) { GM_setValue(domain, JSON.stringify(data)); // 将数据存储为 JSON 字符串 } //---------------------------------------------- // 创建按钮 function createButton(text, clickHandler) { var button = document.createElement("button"); button.textContent = text; button.style.cursor = "pointer"; button.style.backgroundColor = "transparent"; button.style.border = "none"; button.style.fontSize = "inherit"; button.style.color = "#333"; button.style.margin = "0 5px"; button.style.padding = "3px 5px"; button.onclick = clickHandler; // 绑定点击事件 button.ontouchend = clickHandler; // 兼容触摸事件 return button; } // 创建标签 function createLabel(text) { var label = document.createElement("p"); label.textContent = text; label.style.margin = "0"; // 无外边距 return label; } // 创建文字 function createValue(text) { var value = document.createElement("p"); value.textContent = text; value.style.margin = "0 5px"; // 设置左右间距 return value; } // 创建复制按钮 function createCopyButton(text, copyText) { var button = document.createElement("button"); button.textContent = text; button.style.cursor = "pointer"; button.style.backgroundColor = "transparent"; button.style.border = "none"; button.style.fontSize = "inherit"; button.style.color = "#333"; button.style.marginLeft = "5px"; // 左侧间距 button.style.padding = "3px 5px"; button.onclick = function() { copyTextToClipboard(copyText, button); // 点击时复制文本 }; button.ontouchend = button.onclick; // 兼容触摸事件 return button; } // 复制文本 function copyTextToClipboard(text, button) { navigator.clipboard.writeText(text).then(function() { var originalText = button.textContent; button.textContent = "已复制"; // 显示已复制状态 setTimeout(function() { button.textContent = originalText; // 恢复按钮文本 }, 2000); }).catch(function(err) { console.error('复制失败:', err); // 复制失败时输出错误 }); } //---------------------------------------------- // 显示界面初始化 function createDisplayArea() { if (displayAreaDiv) { document.body.removeChild(displayAreaDiv); // 移除现有显示区域 } // 创建新的显示区域 displayAreaDiv = document.createElement("div"); displayAreaDiv.setAttribute("class", "passwordDisplayArea"); displayAreaDiv.style.display = "none"; // 初始隐藏 displayAreaDiv.style.position = "fixed"; displayAreaDiv.style.bottom = "70px"; displayAreaDiv.style.right = "20px"; displayAreaDiv.style.background = "skyblue"; displayAreaDiv.style.padding = "5px"; displayAreaDiv.style.border = "1px solid #ccc"; displayAreaDiv.style.zIndex = "2147483647"; // 确保显示在最上层 displayAreaDiv.style.maxWidth = "250px"; displayAreaDiv.style.fontSize = "14px"; var topButtons = document.createElement("div"); topButtons.style.display = "flex"; topButtons.style.justifyContent = "space-between"; topButtons.style.marginBottom = "5px"; // 添加关闭按钮 topButtons.appendChild(createButton("关闭", function() { displayAreaDiv.style.display = "none"; // 隐藏显示区域 })); // 添加编辑按钮 topButtons.appendChild(createButton("编辑", function() { displayAreaDiv.style.display = "none"; // 隐藏显示区域 var storedData = getStoredData(currentDomain); var accountInfo = storedData.accounts[currentPageIndex]; showEditPage(accountInfo); // 显示编辑页面 })); // 添加新建按钮 topButtons.appendChild(createButton("新建", function() { displayAreaDiv.style.display = "none"; // 隐藏显示区域 showNewPage(); // 显示新建页面 })); displayAreaDiv.appendChild(topButtons); // 显示当前网站域名 var domainContainer = document.createElement("div"); domainContainer.style.display = "flex"; domainContainer.style.alignItems = "center"; domainContainer.appendChild(createLabel("当前网站:")); domainContainer.appendChild(createValue(currentDomain)); displayAreaDiv.appendChild(domainContainer); // 创建账号信息容器 var accountContainer = document.createElement("div"); accountContainer.setAttribute("class", "accountContainer"); displayAreaDiv.appendChild(accountContainer); // 创建页面控制按钮 var pageControls = document.createElement("div"); pageControls.style.display = "flex"; pageControls.style.justifyContent = "center"; pageControls.style.marginTop = "5px"; // 上一页按钮 prevPageButton = createButton("<", function() { if (currentPageIndex > 0) { currentPageIndex--; // 转到上一页 updateAccountDisplay(); } }); pageControls.appendChild(prevPageButton); // 显示当前页数的标签 var pageLabel = document.createElement("span"); pageLabel.setAttribute("class", "pageLabel"); pageLabel.style.margin = "0 10px"; pageControls.appendChild(pageLabel); nextPageButton = createButton(">", function() { var storedData = getStoredData(currentDomain); if ((currentPageIndex + 1) < storedData.accounts.length) { // 确保不要超过帐户数量 currentPageIndex++; // 转到下一页 updateAccountDisplay(); } }); pageControls.appendChild(nextPageButton); displayAreaDiv.appendChild(pageControls); // 将页面控制按钮添加到显示区域 document.body.appendChild(displayAreaDiv); // 将显示区域添加到页面 updateAccountDisplay(); // 更新账号信息显示 } // 显示页面 function showNewPage() { var newDiv = document.createElement("div"); newDiv.setAttribute("class", "passwordEditArea"); newDiv.style.position = "fixed"; newDiv.style.bottom = "70px"; newDiv.style.right = "20px"; newDiv.style.background = "white"; newDiv.style.padding = "10px"; newDiv.style.border = "1px solid #ccc"; newDiv.style.zIndex = "2147483647"; // 确保显示在最上层 newDiv.style.maxWidth = "250px"; newDiv.style.fontSize = "14px"; newDiv.innerHTML = ` <p><label>账号:<input type="text" id="newUsername" style="width: 100%;"></label></p> <p><label>密码:<input type="password" id="newPassword" style="width: 100%;"></label></p> <div style="display: flex; justify-content: space-between; margin-top: 10px;"> <button id="cancelNew">取消</button> <button id="saveNew">创建</button> </div> `; document.body.appendChild(newDiv); // 取消按钮事件处理程序 document.getElementById("cancelNew").onclick = function() { document.body.removeChild(newDiv); // 关闭新建页面 }; // 保存按钮事件处理程序 document.getElementById("saveNew").onclick = function() { var username = document.getElementById("newUsername").value.trim(); // 获取用户名 var password = document.getElementById("newPassword").value; // 获取密码 if (!validateInput(username, password)) { // 验证输入 return; } var storedData = getStoredData(currentDomain); // 获取存储数据 storedData.accounts.push({ username, password }); // 添加新账号信息 setStoredData(currentDomain, storedData); // 保存数据 document.body.removeChild(newDiv); // 关闭新建页面 currentPageIndex = 0; // 重置页面索引 updateAccountDisplay(); // 更新显示 }; } // 无账号密码单独界面 function createNoInfoText(text) { var noInfoText = document.createElement("p"); noInfoText.textContent = text; noInfoText.style.margin = "0"; // 无外边距 return noInfoText; } //-------------------------------------------------------- // 编辑页面默认填充 function populateEditFieldsWithCurrentAccount() { var storedData = getStoredData(currentDomain); var currentAccount = storedData.accounts[currentPageIndex]; var usernameField = document.getElementById("editUsername"); var passwordField = document.getElementById("editPassword"); usernameField.value = currentAccount.username || ""; // 填充用户名 passwordField.value = currentAccount.password || ""; // 填充密码 } // 更新显示界面账号 function updateAccountDisplay() { var storedData = getStoredData(currentDomain); var accountContainer = displayAreaDiv.querySelector(".accountContainer"); accountContainer.innerHTML = ""; // 清空当前显示内容 if (storedData.accounts.length > 0) { var accountInfo = storedData.accounts[currentPageIndex]; var accountRow = document.createElement("div"); accountRow.style.display = "flex"; accountRow.style.justifyContent = "space-between"; accountRow.appendChild(createLabel("账号:")); // 账号标签 accountRow.appendChild(createCopyButton("复制", accountInfo.username || "[无账号信息]")); // 复制按钮 accountContainer.appendChild(accountRow); accountContainer.appendChild(createValue(accountInfo.username || "[无账号信息]")); // 显示账号 var passwordRow = document.createElement("div"); passwordRow.style.display = "flex"; passwordRow.style.justifyContent = "space-between"; passwordRow.appendChild(createLabel("密码:")); // 密码标签 passwordRow.appendChild(createCopyButton("复制", accountInfo.password)); // 复制按钮 accountContainer.appendChild(passwordRow); accountContainer.appendChild(createValue(accountInfo.password)); // 显示密码 // 新增:优先级复选框 var priorityRow = document.createElement("div"); priorityRow.style.display = "flex"; // 确保子元素按行排列 priorityRow.style.alignItems = "center"; // 垂直居中对齐 var priorityCheckbox = document.createElement("input"); priorityCheckbox.type = "checkbox"; // 设置复选框的初始状态 priorityCheckbox.checked = storedData.priority === currentPageIndex + 1; priorityCheckbox.onchange = function() { // 修改优先级 if (priorityCheckbox.checked) { storedData.priority = currentPageIndex + 1; } else { storedData.priority = 0; // 取消勾选时,设置优先级为0 } setStoredData(currentDomain, storedData); // 保存修改后的数据 updateAccountDisplay(); // 更新显示 }; priorityRow.appendChild(priorityCheckbox); priorityRow.appendChild(createLabel("自动填入此页面")); // 优先级标签 accountContainer.appendChild(priorityRow); fillCredentials(accountInfo.username, accountInfo.password); // 填充账号和密码 } else { // 无账户信息情况 accountContainer.appendChild(createLabel("账号:")); accountContainer.appendChild(createNoInfoText("[无账号信息]")); // 显示无账号信息 accountContainer.appendChild(createLabel("密码:")); accountContainer.appendChild(createNoInfoText("[无密码信息]")); // 显示无密码信息 } // 更新页码显示 displayAreaDiv.querySelector(".pageLabel").textContent = (currentPageIndex + 1) + "/" + Math.ceil(storedData.accounts.length); prevPageButton.style.display = currentPageIndex > 0 ? "inline" : "none"; // 显示或隐藏上一页按钮 nextPageButton.style.display = (currentPageIndex + 1) < storedData.accounts.length ? "inline" : "none"; // 显示或隐藏下一页按钮 } // 编辑页面 function showEditPage(accountInfo) { var editDiv = document.createElement("div"); editDiv.setAttribute("class", "passwordEditArea"); editDiv.style.position = "fixed"; editDiv.style.bottom = "70px"; editDiv.style.right = "20px"; editDiv.style.background = "white"; editDiv.style.padding = "10px"; editDiv.style.border = "1px solid #ccc"; editDiv.style.zIndex = "2147483647"; // 确保显示在最上层 editDiv.style.maxWidth = "250px"; editDiv.style.fontSize = "14px"; editDiv.innerHTML = ` <p><label>账号:<input type="text" id="editUsername" style="width: 100%;" value="${accountInfo.username}"></label></p> <p><label>密码:<input type="password" id="editPassword" style="width: 100%;" value="${accountInfo.password}"></label></p> <div style="display: flex; justify-content: space-between; margin-top: 10px;"> <button id="cancelEdit">取消</button> <button id="saveEdit">保存</button> <button id="deleteEntry">删除</button> </div> `; document.body.appendChild(editDiv); // 添加编辑页面 // 取消按钮事件处理程序 document.getElementById("cancelEdit").onclick = function() { document.body.removeChild(editDiv); // 关闭编辑页面 }; // 保存按钮事件处理程序 document.getElementById("saveEdit").onclick = function() { var username = document.getElementById("editUsername").value.trim(); // 获取用户名 var password = document.getElementById("editPassword").value; // 获取密码 if (!validateInput(username, password)) { // 验证输入 return; } var storedData = getStoredData(currentDomain); // 获取存储数据 storedData.accounts[currentPageIndex] = { username, password }; // 更新账号信息 setStoredData(currentDomain, storedData); // 保存数据 document.body.removeChild(editDiv); // 关闭编辑页面 currentPageIndex = 0; // 重置页面索引 updateAccountDisplay(); // 更新显示 }; // 删除按钮事件处理程序 document.getElementById("deleteEntry").onclick = function() { var storedData = getStoredData(currentDomain); // 获取存储数据 // 检查当前条目是否为优先级条目 if (storedData.priority === currentPageIndex + 1) { if (storedData.accounts.length > 1) { storedData.priority = Math.max(1, currentPageIndex); // 设置优先级为当前条目的索引 } else { storedData.priority = 0; // 删除唯一条目时,优先级重置为0 } } storedData.accounts.splice(currentPageIndex, 1); // 删除当前条目 setStoredData(currentDomain, storedData); // 保存修改后的数据 document.body.removeChild(editDiv); // 关闭编辑页面 currentPageIndex = 0; // 重置页面索引 updateAccountDisplay(); // 更新显示 }; } // 验证输入 function validateInput(username, password) { return true; // 暂时不使用详细的验证逻辑 } //--------------------------------------------------- // 加载时匹配填充 function autoFillOnLoad() { var storedData = getStoredData(currentDomain); // 获取存储数据 if (storedData.priority > 0) { // 如果优先级大于0,则填充优先级账号 var priorityAccount = storedData.accounts[storedData.priority - 1]; fillCredentials(priorityAccount.username, priorityAccount.password); // 自动填充账号和密码 } } // 自动填充账号密码 function fillCredentials(username, password) { if (autoFillEnabled) { // 检查是否启用自动填充 var editAreaExists = document.querySelector(".passwordEditArea"); if (editAreaExists) { return; // 如果编辑区域已存在,则不执行填充 } var storedData = getStoredData(currentDomain); // 获取存储数据 if (storedData.priority > 0) { // 如果优先级大于0,则填充优先级账号 var priorityAccount = storedData.accounts[storedData.priority - 1]; username = priorityAccount.username; password = priorityAccount.password; } // 填充输入框 var usernameField = document.querySelector("input[type='text'], input[type='email']"); var passwordField = document.querySelector("input[type='password']"); if (usernameField && passwordField) { usernameField.value = username; passwordField.value = password; } } } //---------------------------------------------- // 创建主按钮 function createControlButton() { var controlButton = document.createElement("button"); controlButton.textContent = "显示账号和密码"; controlButton.style.position = "fixed"; controlButton.style.bottom = "10px"; controlButton.style.right = "10px"; controlButton.style.fontSize = "10px"; // 设置字体大小 controlButton.style.cursor = "pointer"; // 设置鼠标指针为手形 controlButton.style.zIndex = "2147483647"; // 确保显示在最上层 controlButton.onclick = function() { // 检测模块是否存在 if (typeof GM_getValue === 'undefined' || typeof GM_setValue === 'undefined' || typeof GM_deleteValue === 'undefined' || typeof GM_listValues === 'undefined' || typeof GM_addStyle === 'undefined') { // 提示用户,提前退出 confirm("记录账号和密码\n脚本出现错误:\n某些必要的模块不存在,无法继续执行操作。请确保浏览器包含本脚本需要的脚本支持库。"); return; } controlButton.onclick = function() { if (!displayAreaDiv) { createDisplayArea(); // 仅在首次点击时创建显示区域 } displayAreaDiv.style.display = displayAreaDiv.style.display === "none" ? "block" : "none"; // 切换显示状态 if (displayAreaDiv.style.display === "block") { updateAccountDisplay(); // 更新显示 } }; document.body.appendChild(controlButton); // 添加控制按钮 }; document.body.appendChild(controlButton); // 添加控制按钮 } //----------------------------------------- createControlButton(); // 创建控制按钮 autoFillOnLoad(); // 页面加载时自动填充 })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址