您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
bring back the keyboard navigation in Google Search
当前为
// ==UserScript== // @name Google Search keyboard navigation // @namespace http://tampermonkey.net/ // @version 2025-05-28-1 // @description bring back the keyboard navigation in Google Search // @author victor141516 // @match https://www.google.com/search?q=* // @icon https://www.google.com/s2/favicons?sz=64&domain=google.com // @grant none // @license MIT // ==/UserScript== (function () { "use strict"; const BASE_CLASS_NAME = "x-keyboard-utils"; const ACTIVE_CLASS_NAME = "x-keyboard-utils-active"; const RESULTS_CONTAINER_SELECTOR = "div[data-async-context^=query]"; function appendCss() { const styles = ` .${BASE_CLASS_NAME}.${ACTIVE_CLASS_NAME}:before { content: ''; z-index: 100; display: block; position: absolute; pointer-events: none; border: 15px solid transparent; border-left-color: blue; left: -20px; } `; const styleElement = document.createElement("style"); styleElement.textContent = styles; document.head.appendChild(styleElement); } (async () => { let activeIndex = 0; /** @type {Array<HTMLElement>} */ let $results = []; document.addEventListener("keydown", (e) => { const isArrowDown = e.key === "ArrowDown"; const isArrowUp = e.key === "ArrowUp"; const isEnter = e.key === "Enter"; if (!isArrowDown && !isArrowUp && !isEnter) return; e.preventDefault(); if (isArrowDown) { activeIndex = Math.min(activeIndex + 1, $results.length - 1); } else if (isArrowUp) { activeIndex = Math.max(activeIndex - 1, 0); } else if (isEnter) { $results[activeIndex].querySelector("a").click(); } updateArrow(); }); function updateArrow() { $results.forEach((e) => { e.classList.remove(ACTIVE_CLASS_NAME); }); $results[activeIndex].classList.add(ACTIVE_CLASS_NAME); $results[activeIndex].scrollIntoView({ behavior: "smooth", block: "center", inline: "center", }); } function initializeResultElements() { $results = Array.from( document.querySelectorAll( `${RESULTS_CONTAINER_SELECTOR} div:has(>div[lang]>div[data-snc])` ) ); $results.forEach(($result) => { if ($result.classList.contains(BASE_CLASS_NAME)) return; $result.classList.add(BASE_CLASS_NAME); }); } const targetNode = document.querySelector(RESULTS_CONTAINER_SELECTOR); const callback = (mutationList) => { for (const mutation of mutationList) { if (mutation.type === "childList") { initializeResultElements(); } } }; const observer = new MutationObserver(callback); observer.observe(targetNode, { attributes: false, childList: true, subtree: false, }); appendCss(); initializeResultElements(); updateArrow(); })(); })();