您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds single-key hotkeys that jump to specific text (or anchors) on a page.
当前为
// ==UserScript== // @name Jump to Text // @namespace https://github.com/theborg3of5/Userscripts/ // @version 1.4 // @description Adds single-key hotkeys that jump to specific text (or anchors) on a page. // @author Gavin Borg // @require https://greasyfork.org/scripts/28536-gm-config/code/GM_config.js?version=184529 // @match https://greasyfork.org/en/scripts/395551-jump-to-text // @grant GM_registerMenuCommand // @grant GM_getValue // @grant GM_setValue // ==/UserScript== var configOpen = false; // Whether the config window is open, for our close-config hotkey (Escape). var config = GM_config; var maxNumHotkeys = 15; // How many hotkeys are configurable per site. (function() { 'use strict'; var site = getMatchingSite(); var siteClean = cleanSite(site); initConfig(site); document.onkeyup = function(e) { //console.log("Key caught: " + e.key); // Special cases: Ctrl+Comma (,) triggers config, Escape closes it if (e.ctrlKey && e.key === ",") { configOpen = true; config.open(); } if (e.key === "Escape" && configOpen) { config.close(); } // Otherwise, only single-button hotkeys are supported if (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey) { return; } // If there's a matching anchor name, jump to that anchor by updating the URL hash. var anchorName = getAnchorNameForKey(siteClean, e.key); //console.log("Anchor name found: " + anchorName); if(anchorName !== "") { // Make sure the anchor name starts with a hash (because that's how it's formatted in window.location.hash) if (!anchorName.startsWith("#")) { anchorName = "#" + anchorName; } // If the URL is already pointed to the spot we're interested in, remove it so we can re-add it and jump there again. if (window.location.hash == anchorName) { window.location.hash = ""; } window.location.hash = anchorName; return; } // Otherwise try to find the first instance of the configured text var text = getTextForKey(siteClean, e.key); //console.log("Text found: " + text); if(text !== "") { var firstElement = document.evaluate("//*[contains(text(), '" + text + "')]").iterateNext(); if(firstElement) { firstElement.scrollIntoView(); return; } } } })(); function getMatchingSite() { // Get sites that user has chosen to include or match (because that's what hotkeys are keyed to, not direct URLs) var sites = GM_info.script.options.override.use_matches; sites.concat(GM_info.script.options.override.use_includes); // Find matching site var currentURL = window.location.href; for (var site of sites) { // Use a RegExp to determine which of the user's includes/matches is currently open, since we allow different hotkeys/anchors per each of those. var siteRegex = new RegExp(site.replace(/\*/g, "[^ ]*")); // Replace * wildcards with regex-style [^ ]* wildcards if (siteRegex.test(currentURL)) { return site; // First match always wins } } } function initConfig(site) { var siteClean = cleanSite(site); // Build the fields for each of the available hotkeys var fields = {}; for (var i = 1; i <= maxNumHotkeys; i++) { fields[keyField(siteClean, i)] = { label: "Key(s) to press:", title: "The single key(s) to press to jump to this anchor/text. To have multiple keys jump to the same place, separate keys with a space (i.e. \"a r\" for both \"a\" and \"r\" keys ).", type: "text", labelPos: "above" }; fields[anchorNameField(siteClean, i)] = { label: "Anchor name:", title: "The name or id of the anchor to jump to", type: "text" }; fields[textField(siteClean, i)] = { label: "Text to jump to:", title: "We'll jump to the first instance of this text on the page. Ignored if anchor name is specified.", type: "text" }; } config.init({ id: 'JumpToTextConfig' + siteClean, title: "Jump to Text Config for: " + site, fields: fields, events: { 'open': function() { configOpen = true; }, 'close': function() { configOpen = false; }, 'save': function() { config.close(); } } }); // Add a menu item to the menu to launch the config GM_registerMenuCommand('Configure hotkeys for this site', () => { config.open(); }) } function cleanSite(site) { return site.replace(/[\*/:]/g, ""); // Drop */: characters from site for use in ID } function getAnchorNameForKey(site, key) { for (var i = 1; i <= maxNumHotkeys; i++) { var keyAry = config.get(keyField(site, i).split(" ")); if (keyAry.includes(key)) { return config.get(anchorNameField(site, i)); } } return ""; } function getTextForKey(site, key) { for (var i = 1; i <= maxNumHotkeys; i++) { var keyAry = config.get(keyField(site, i).split(" ")); if (keyAry.includes(key)) { return config.get(textField(site, i)); } } return ""; } // We use the site as part of these IDs so that the configuration is separate per site. function keyField(site, index) { return site + "_Keys_" + index; } function anchorNameField(site, index) { return site + "_AnchorName_" + index; } function textField(site, index) { return site + "_Text_" + index; }