您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
监听网页内的键盘事件和鼠标事件,抓取捕获这些鼠标、键盘消息的网页节点的源代码和坐标。ctrl+shift+F9,启动或停用脚本;ctrl+shift+F10,显示选项菜单;ctrl+shift+F11,显示抓取到的源代码;ctrl+shift+F12获取当前焦点的源代码。
// ==UserScript== // @name 监听网页操作 // @namespace // @version 0.3 // @description 监听网页内的键盘事件和鼠标事件,抓取捕获这些鼠标、键盘消息的网页节点的源代码和坐标。ctrl+shift+F9,启动或停用脚本;ctrl+shift+F10,显示选项菜单;ctrl+shift+F11,显示抓取到的源代码;ctrl+shift+F12获取当前焦点的源代码。 // @author 流水 // @include * // @grant unsafeWindow // ==/UserScript== window.setTimeout(function() { let canUseHotkey = false; let needGetCode = false; let manyTimesHandle = false; let allNodeCode = false; let needGetHotkeyMessage = false; let needGetMouseMessage = false; let onlyOneNodeCode = false; let manyTimesCode = ""; let observer1 = null; if (MutationObserver != null) { observer1 = new MutationObserver(function(mutationList, observer) { let str = ""; for (let mutation of mutationList) { if (mutation.target.nodeName) { if (str == mutation.target.outerHTML) continue; else { str = mutation.target.outerHTML; GetPartSourceCode(mutation.target, "新增加或内容发生变化的元素"); } } } }) } document.addEventListener("click", function(event) { if ((needGetMouseMessage === true) || (needGetHotkeyMessage === true)) GetMessageType(event); else GetPartSourceCode(event.srcElement, "被点击的元素"); }) document.addEventListener("dblclick", function(event) { if (needGetMouseMessage === true) GetMessageType(event); }) document.addEventListener("mousedown", function(event) { if (needGetMouseMessage === true) GetMessageType(event); }) document.addEventListener("mouseout", function(event) { if (needGetMouseMessage === true) GetMessageType(event); }) document.addEventListener("mouseover", function(event) { if (needGetMouseMessage === true) GetMessageType(event); }) document.addEventListener("mouseup", function(event) { if (needGetMouseMessage === true) GetMessageType(event); }) document.addEventListener("mousemove", function(event) { if (needGetMouseMessage === true) GetMessageType(event); }) document.addEventListener("keydown", function(event) { if (needGetHotkeyMessage === true) GetMessageType(event); if (window.event.keyCode === 120 && !window.event.altKey && window.event.shiftKey && window.event.ctrlKey) { if (!canUseHotkey) { canUseHotkey = true; ChooseMode(); } else { canUseHotkey = false; needGetCode = false; manyTimesCode = ""; if (observer1 != null) observer1.disconnect(); alert("脚本抓取源码的快捷键已禁用"); } } if (window.event.keyCode === 121 && !window.event.altKey && window.event.shiftKey && window.event.ctrlKey && canUseHotkey) { ChooseMode(); } if (window.event.keyCode === 123 && !window.event.altKey && window.event.shiftKey && window.event.ctrlKey && canUseHotkey) { GetPartSourceCode(event.srcElement); } if (window.event.keyCode === 122 && !window.event.altKey && window.event.shiftKey && window.event.ctrlKey && canUseHotkey) { CreateSourceCodeTextarea(); } }) function GetMessageType(event) { if ((needGetHotkeyMessage === false) && (needGetMouseMessage === false)) return false; let node = event.srcElement; let str = "鼠标、键盘消息为:"; str += event.type; str += ("\r\n" + GetPosition(event)); if (needGetHotkeyMessage) str += GetKeyCode(event); str += "\r\n"; manyTimesCode += str; GetPartSourceCode(node); } function GetPosition(event) { let str = ""; if (event.screenX && event.screenY) str += ("屏幕坐标为:" + "x:" + event.screenX + "," + "y:" + event.screenY + "\r\n"); if (event.clientX && event.clientY) str += ("客户区坐标位置为:" + "x:" + event.clientX + "," + "y:" + event.clientY + "\r\n"); if (event.pageX && event.pageY) str += ("页面坐标位置为:" + "x:" + event.pageX + "," + "y:" + event.pageY + "\r\n"); return str; } function GetKeyCode(event) { let str = ""; if (!needGetHotkeyMessage || !window.event.keyCode) return str; str += "快捷键为:"; if (window.event.altKey) str += "alt+"; if (window.event.shiftKey) str += "shift+"; if (window.event.ctrlKey) str += "ctrl+"; str += (window.event.keyCode + "\r\n"); return str; } function GetPartSourceCode(node, headStr = "") { if (needGetCode === false) return; if (!node) return; let str = ""; let index = 0; while ((node.nodeName != null) && (node.nodeName != "HTML")) { if (index === 0) if (headStr === "") str += ("被操作的元素node" + index + "的名称为" + node.nodeName + "\r\n"); else str += (headStr + "node" + index + "的名称为" + node.nodeName + "\r\n"); else str += ("node" + (index - 1) + "的父元素node" + index + "的名称为" + node.nodeName + "\r\n"); let attributes = node.attributes; if (attributes != null) { if (index === 0) str += "node" + index + "的属性为:\r\n"; else str += "node" + index + "的属性为:\r\n"; for(let element of attributes) { if (element != null) str += (element.name + " = " + element.value + "\r\n"); } } else { if (index === 0) str += "node" + index + "的属性为空\r\n"; else str += "node" + index + "的属性为空\r\n"; } if (node.innerHTML != "") { if (index === 0) str += ("node" + index + "的内容为" + node.innerHTML + "\r\n\r\n"); if ((index === 1) || (allNodeCode === true && index > 1)) str += ("node" + index + "的内容为" + node.innerHTML + "\r\n\r\n"); } else { if (index === 0) str += ("node" + index + "的内容为空" + "\r\n\r\n"); else str += ("node" + index + "的内容为空" + "\r\n\r\n"); } str += "\r\n"; if (onlyOneNodeCode === true) break; ++index; node = node.parentNode; } manyTimesCode += str; if (!manyTimesHandle) needGetCode = false; PrintCode(); } function CreateSourceCodeTextarea() { needGetCode = false; needGetHotkeyMessage = false; needGetMouseMessage = false; if (observer1 != null) observer1.disconnect(); let sourceCodeTextarea = document.getElementById("sourceCodeTextarea"); if (!sourceCodeTextarea) { sourceCodeTextarea = document.createElement('textarea'); sourceCodeTextarea.setAttribute("id", "sourceCodeTextarea"); sourceCodeTextarea.setAttribute("title", "网页源代码"); sourceCodeTextarea.setAttribute("readonly", "readonly"); document.getElementsByTagName('body')[0].appendChild(sourceCodeTextarea); sourceCodeTextarea.onblur = function() { document.getElementsByTagName('body')[0].removeChild(this); } } sourceCodeTextarea.innerHTML = manyTimesCode; sourceCodeTextarea.focus(); } function ChooseMode() { manyTimesCode = ""; if (observer1 != null) observer1.disconnect(); let selectNode = document.getElementsByName("selectForCHooseMode"); if (!selectNode[0]) { selectNode = document.createElement("select"); selectNode.setAttribute("name", "selectForCHooseMode"); selectNode.innerHTML = ("<option value=\"-1\">请选择</option>" + "<option value=\"0\">获取一次被点击元素的源码(只获取前两层元素的完整源代码)</option>" + "<option value=\"1\">连续获取被点击元素的源码(只获取前两层元素的完整源代码)</option>" + "<option value=\"2\">获取一次被点击元素的源码(获取直到根节点的完整源代码)</option>" + "<option value=\"3\">连续获取被点击元素的源码(获取直到根节点的完整源代码)</option>" + "<option value=\"4\">获取完整网页源代码</option>" + "<option value=\"5\">侦听鼠标、键盘消息</option>" + "<option value=\"6\">只侦听鼠标消息</option>" + "<option value=\"7\">只侦听键盘消息</option>" + "<option value=\"8\">只侦听鼠标消息并只获取第一层节点的内容</option>" + "<option value=\"9\">只侦听键盘消息并只获取第一层节点的内容</option>" + "<option value=\"10\">侦听鼠标、键盘消息并只获取第一层节点的内容</option>" + "<option value=\"11\">获取新增节点内容</option>" + "<option value=\"12\">获取新增节点内容,并只获取第一层节点</option>" + "<option value=\"13\">获取新增节点及被改变文本的内容</option>" + "<option value=\"14\">获取新增节点及被改变文本的内容,并只获取第一层节点</option>"); document.getElementsByTagName('body')[0].appendChild(selectNode); selectNode.focus(); selectNode.onblur = function() { manyTimesCode = ""; needGetCode = true; needGetHotkeyMessage = false; needGetMouseMessage = false; onlyOneNodeCode = false; let value = this.value; document.getElementsByTagName('body')[0].removeChild(this); if (value == 0) { manyTimesHandle = false; allNodeCode = false; } if (value == 1) { manyTimesHandle = true; allNodeCode = false; } if (value == 2) { manyTimesHandle = false; allNodeCode = true; } if (value == 3) { manyTimesHandle = true; allNodeCode = true; } if (value == 4) { let htmlString = document.getElementsByTagName('html')[0].innerHTML.replace(/\n/g, '\r\n'); htmlString += ("\r\n\r\n" + window.location.href); manyTimesCode += htmlString; PrintCode(); } if (value == 5) { needGetHotkeyMessage = true; needGetMouseMessage = true; manyTimesHandle = true; allNodeCode = false; } if (value == 6) { needGetMouseMessage = true; manyTimesHandle = true; allNodeCode = false; } if (value == 7) { needGetHotkeyMessage = true; manyTimesHandle = true; allNodeCode = false; } if (value == 8) { needGetMouseMessage = true; manyTimesHandle = true; allNodeCode = false; onlyOneNodeCode = true; } if (value == 9) { needGetHotkeyMessage = true; manyTimesHandle = true; allNodeCode = false; onlyOneNodeCode = true; } if (value == 10) { needGetHotkeyMessage = true; needGetMouseMessage = true; manyTimesHandle = true; allNodeCode = false; onlyOneNodeCode = true; } if (value == 11) { if (observer1 != null) observer1.observe(document.body, {childList:true, subtree:true}); manyTimesHandle = true; allNodeCode = false; onlyOneNodeCode = false; } if (value == 12) { if (observer1 != null) observer1.observe(document.body, {childList:true, subtree:true}); manyTimesHandle = true; allNodeCode = false; onlyOneNodeCode = true; } if (value == 13) { if (observer1 != null) observer1.observe(document.body, {attributes:true, childList:true, subtree:true, characterData:true}); manyTimesHandle = true; allNodeCode = false; onlyOneNodeCode = false; } if (value == 14) { if (observer1 != null) observer1.observe(document.body, {attributes:true, childList:true, subtree:true, characterData:true}); manyTimesHandle = true; allNodeCode = false; onlyOneNodeCode = true; } } } } function PrintCode() { if (window.location.href.search(/^http:\/\/.+/i) == -1) { navigator.clipboard.writeText(manyTimesCode); if ((needGetHotkeyMessage === false) && (needGetMouseMessage === false)) window.setTimeout(function() { alert("源代码已复制"); }, 1000) } else { if (!manyTimesHandle) window.setTimeout(function() { CreateSourceCodeTextarea(); },1000) } } }, 0)