您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
-:指している要素をオートフォーカス場所&Escで戻る場所に登録 Shift+-:Escで戻る場所だけ登録 Esc:そこに戻る
当前为
// ==UserScript== // @name -で指定した要素をオートフォーカス // @description -:指している要素をオートフォーカス場所&Escで戻る場所に登録 Shift+-:Escで戻る場所だけ登録 Esc:そこに戻る // @match *://*/* // @run-at document-idle // @version 0.3 // @grant GM_addStyle // @namespace https://gf.qytechs.cn/users/181558 // ==/UserScript== (function() { const maxLines = 5; // 一度に提案する最大数調整 大きいほど少ない(maxLines/縦解像度) const TryMulti = 15; // 一度に生成する試行回数調整 増やすと沢山試す=遅い代わりに結果が増える var excludeRE = "@data|@href=|width|height|@title=|@alt=|@src="; //"@href=|text\\(\\)|@title=|@alt=|@src="; // o,pキーではこれを含むXPath式は除外する 例:/href|text\(\)/ or /\0/ var requireRE = ""; var requireHits = 1; const CancelStyle = /box-shadow: none;|\@style=\"\"|(\sand\s)\sand\s|\[\]|\sand\s(\])/gmi; const cancelrep = "$1$2"; var mousex = 0; var mousey = 0; document.addEventListener('keydown', function(e) { if (/input|textarea/i.test(e.target.tagName) == false) { if (!e.getModifierState("Alt") && !e.getModifierState("Control") && !e.getModifierState("Shift") && (e.key == "Escape")) { // esc loadfocus2("esc"); } if (!e.getModifierState("Alt") && !e.getModifierState("Control") && !e.getModifierState("Shift") && (e.key == "-")) { // - var ele = document.elementFromPoint(mousex, mousey); if (/input|textarea/i.test(ele.tagName) == false) ele.focus() var xp = mark("ar", ele); e.preventDefault(); } if (!e.getModifierState("Alt") && !e.getModifierState("Control") && e.getModifierState("Shift") && (e.key == "=")) { // shift+- var ele = document.elementFromPoint(mousex, mousey); if (/input|textarea/i.test(ele.tagName) == false) ele.focus() var xp = mark("r", ele); e.preventDefault(); } } }, false); document.addEventListener("mousemove", function(e) { mousex = e.clientX; mousey = e.clientY; }, false); setTimeout(() => { loadfocus() }, 100) return; function loadfocus(times = 0) { let xp = localStorage.getItem("mAutoFocusXPath") || ""; if (!xp || times > 5000) return false; if (eleget0(xp)) { setTimeout(() => { loadfocus2(); }, 200); return; } else setTimeout(() => { loadfocus(times + 200); }, 200) } function loadfocus2(mode = "init") { var xp = mode == "init" ? localStorage.getItem("mAutoFocusXPath") : localStorage.getItem("mAutoFocusXPathr") || localStorage.getItem("mAutoFocusXPath") || ""; if (!xp) return; var ele = eleget0(xp); if (ele) { GM_addStyle(":focus {outline: rgba(0, 250,0,0.7) solid 4px !important;}") ele.focus(); if (!location.href.match(/cavelis|live.?\.nicovideo/)) ele.scrollIntoView({ behavior: "smooth", block: "center", inline: "center" }); } return ele; } function mark(mode, ele = document.elementFromPoint(mousex, mousey)) { if (mode == "ar") var ls = localStorage.getItem("mAutoFocusXPath") || ""; if (mode == "r") var ls = localStorage.getItem("mAutoFocusXPathr") || ""; var xp0 = getElementXPath0(ele); if (ls.indexOf(xp0) > -1) var teianxp = ls; else var teianxp = (ls == "" ? xp0 : (ls + "|." + xp0)); var xp = promptHE(ls, (mode == "ar" ? "オートフォーカスする場所とEscで戻る場所" : "Escで戻る場所") + "をXpathで指定してください\n|で区切って記述すると複数をOR指定できます\n\n指した要素:\n" + xp0 + "\n\n現在の設定値:\n" + ls + "\n\n空欄にすると削除します ", teianxp); console.log(xp); if (xp === null) return; if (xp === "") { if (mode == "ar") localStorage.removeItem("mAutoFocusXPath", xp); if (mode == "r") localStorage.removeItem("mAutoFocusXPathr", xp); return; } var ele = eleget0(xp); if (ele) { if (mode == "ar") localStorage.setItem("mAutoFocusXPath", xp); if (mode == "r") localStorage.setItem("mAutoFocusXPathr", xp); loadfocus2(); } else { alert(xp + "\n" + "要素が見つかりませんでした\n設定は変更しません\n"); // if (mode == "ar") localStorage.removeItem("mAutoFocusXPath", xp); // if (mode == "r") localStorage.removeItem("mAutoFocusXPathr", xp); return; } } function str2numMinMax(str, min, max) { var ans = Number(str.replace(/[A-Za-z0-9.]/g, function(s) { return String.fromCharCode(s.charCodeAt(0) - 65248); }).replace(/[^-^0-9^\.]/g, "")); if (ans > max) ans = max; if (ans < min) ans = min; return ans; } function getElementXPath0(ele) { // var path = ""; var paths = makecontent(0, ele); var path = paths[0]; for (let p of paths) { if (p.match(/@class|@id=/)) { path = p; break; } } // path = "/" + ele.tagName + (!ele.tagName.match(/html|body/gi) ? "[" + idx + "]" : "") + path; return path; } function makecontent(mode, ele) { var retStr = []; var maxline = 3000; //window.innerHeight / maxLines; var maxtrial = 3000; //maxline * TryMulti * (mode != 9 ? 32 : 3) * (requireRE > "\0" ? 3 : 1) * ((mode == 0 && requireHits == 1) ? 3 : 1); var retStrl = 0; hajime(); for (var i = 0; i < maxtrial && retStrl < maxline; i++) { var xp = getElementXPath(mode, ele); if (xp && !(mode !== 9 && RegExp(excludeRE, "i").test(xp))) { retStr.push(xp); var retStr = retStr.sort().reduce(function(previous, current) { if (previous[previous.length - 1] !== current) { previous.push(current); } return previous; }, []).sort(function(a, b) { return a.length - b.length < 0 ? -1 : 1; }); // 重複を削除&ソート retStrl = retStr.length; if (xp.length < 60 && xp.match(/@class|@id=/)) { console.log(xp); i += 600 } } } owari(); console.log("trymax:" + maxtrial + "\nmakemax:" + maxline + "\ntried:" + i + "\nmake:" + retStr.length); // 1つは全属性を記述しただけのもの if (getAttrOfEle(mode, ele, true)) { var path = "//" + ele.tagName + "[" + getAttrOfEle(mode, ele, true) + ""; retStr.push(path.replace(CancelStyle, cancelrep).replace(CancelStyle, cancelrep)); } // 1つはフルパスを辿っただけのもの retStr.push(getElementXPathFullPath(ele).replace(CancelStyle, cancelrep).replace(CancelStyle, cancelrep)); // 1つはフルパス全属性を辿っただけのもの retStr.push(getElementXPathFullpathAndFullproperty(mode, ele).replace(CancelStyle, cancelrep).replace(CancelStyle, cancelrep)); return retStr; } function getElementXPath(mode, ele) { var path = ""; var origele = ele; for (let i = 0; i == 0 || (ele && ele.nodeType == 1 && Math.random() > 0.5); ele = ele.parentNode, i++) { //兄弟番号を調べる var ps = getPrevSib(ele); var ns = getNextSib(ele); var idx = 0; var arg = ""; if (!ns && ps && Math.random() > 0.2) { var arg = "[last()]"; } else if (!ps && ns && Math.random() > 0.2) { var arg = "[1]"; } else { for (var idx = 1, sib = getPrevSib(ele); sib; sib = getPrevSib(sib)) { idx++; } } //属性を調べる var att = getAttrOfEle(mode, ele); if (att) att = "[" + att; //背番号かfirst/lastか属性か何も付けないかを32,32,32,4%ずつ var rnd = Math.random(); if ((rnd > 0.68) && arg) var opt = arg; else if ((rnd > 0.36) && idx > 1) var opt = "[" + idx + "]"; else if ((rnd > 0.04) && att) var opt = att; else var opt = ""; path = "/" + ele.tagName.toLowerCase() + (opt) + path; } if (!path) return ""; path = "/" + path; path = path.replace(CancelStyle, cancelrep).replace(CancelStyle, cancelrep); if (requireRE > "" && !(RegExp(requireRE, "i").test(path))) return ""; let hits = elegeta(path).length; // 検算 if (hits == 0 || (mode == 8 && hits < 2) || (mode == 0 && requireHits != hits)) return false; return path; } function getAttrOfEle(mode, ele, allFlag = false) { if (ele.tagName.match(/html|body/gmi)) return ""; let attrs = ele.attributes; let xp = ""; let att2 = []; for (let att of attrs) { if (att.value.length < 100) { if (att.name == "class" && Math.random() > 0.9 && !allFlag) { att2.push({ name: "contains(@class,", value: "\"" + att.value + "\")" }) } else { att2.push({ name: "@" + att.name + "=", value: "\"" + att.value + "\"" }) } } } //text if (!allFlag) { if (Math.random() > (0.7)) { if (ele.innerText && !ele.innerText.match(/[\r\n]/)) { att2.push({ name: "text()=", value: "\"" + ele.innerText + "\"" }) } } else { if (ele.innerText && !ele.innerText.match(/[\r\n]/)) { att2.push({ name: "contains(text(),", value: "\"" + ele.innerText + "\")" }) } } } for (let j = 0; j < att2.length; j++) { if ((Math.random() > (allFlag ? 0 : att2[j].name.match(/href/) ? 0.7 : 0.5))) { xp += att2[j].name + att2[j].value + " and "; } } xp = xp.replace(/ and $/, "]").replace(/^(.*)\[$/, "$1"); return xp; } function getElementXPathFullPath(ele) { var path = ""; for (; ele && ele.nodeType == 1; ele = ele.parentNode) { for (var idx = 1, sib = ele.previousSibling; sib; sib = sib.previousSibling) { if (sib.nodeType == 1 && sib.tagName == ele.tagName) idx++ } path = "/" + ele.tagName + (!ele.tagName.match(/html|body/gi) ? "[" + idx + "]" : "") + path; } return path; } function getElementXPathFullpathAndFullproperty(mode, ele) { var path = ""; for (; ele && ele.nodeType == 1; ele = ele.parentNode) { if (getAttrOfEle(mode, ele, true)) { path = "/" + ele.tagName + "[" + getAttrOfEle(mode, ele, true) + path; } else { path = "/" + ele.tagName + path; } } path = "/" + path; return path; } function str2numMinMax(str, min, max) { var ans = Number(str.replace(/[A-Za-z0-9.]/g, function(s) { return String.fromCharCode(s.charCodeAt(0) - 65248); }).replace(/[^-^0-9^\.]/g, "")); if (ans > max) ans = max; if (ans < min) ans = min; return ans; } function eleget0(xpath) { try { var ele = document.evaluate(xpath, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null) } catch (err) { return ""; } var ele = document.evaluate(xpath, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); return ele.snapshotLength > 0 ? ele.snapshotItem(0) : ""; } function eleget1(xpath) { if (!xpath) return "Err"; try { var ele = document.evaluate(xpath, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null) } catch (err) { return "Err"; } return ele.snapshotLength > 0 ? ele.snapshotItem(0) : ele; } function elegeta(xpath, node = document) { try { var ele = document.evaluate("." + xpath, node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null) } catch (err) { var ele = "err"; } var array = []; for (var i = 0; i < ele.snapshotLength; i++) array[i] = ele.snapshotItem(i); return array; } function getNextSib(ele) { // 同じタグの弟ノードを走査 if (!ele.nextElementSibling) return null; let orgtag = ele.tagName; do { ele = ele.nextElementSibling; if (!ele) return null; if (ele.tagName == orgtag) return ele; } while (1) return null; } function getPrevSib(ele) { // 同じタグの兄ノードを走査 if (!ele.previousElementSibling) return null; let orgtag = ele.tagName; do { ele = ele.previousElementSibling; if (!ele) return null; if (ele.tagName == orgtag) return ele; } while (1) return null; } function proInput(prom, defaultval, min, max = Number.MAX_SAFE_INTEGER) { return Math.min(Math.max( Number(window.prompt(prom, defaultval).replace(/[A-Za-z0-9]/g, function(s) { return String.fromCharCode(s.charCodeAt(0) - 65248); }).replace(/[^-^0-9^\.]/g, "")), min), max); } var start_ms; function hajime() { start_ms = new Date().getTime(); } function owari() { var elapsed_ms = new Date().getTime() - start_ms; console.log('処理時間:' + elapsed_ms / 1000 + "秒"); } function promptHE(present, text, shoki) { // prompt with handling esc let str = prompt(text, shoki); console.log(str) if (str === null) return present; else return str; } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址