Greasy Fork

Greasy Fork is available in English.

HjklNavigation

Introduces (h)jkl navigation into Google Search result. (As an example. You can easily customize this script for other websites.)

目前为 2020-10-25 提交的版本。查看 最新版本

// ==UserScript==
// @name         HjklNavigation
// @namespace    com.gmail.fujifruity.greasemonkey
// @version      0.1
// @description  Introduces (h)jkl navigation into Google Search result. (As an example. You can easily customize this script for other websites.)
// @author       fujifruity
// @include      https://www.google.com/search*
// @grant        GM.openInTab
// ==/UserScript==

(() => {
    function log(...msg) { return console.log("HjklNavigation:", ...msg) }
    function cssOf(elem) { return document.defaultView.getComputedStyle(elem, '') }

    let focusedIdx = null

    const googleUrl = "www.google.com"
    // add another one here

    const results = (() => {
        switch (location.hostname) {
            case googleUrl: return document.getElementsByClassName('rc')
            // add another one here
            default: return null
        }
    })()

    function open(result) {
        switch (location.hostname) {
            case googleUrl: {
                const url = result.firstChild.firstChild.href
                GM.openInTab(url, false)
                break
            }
            // add another one here
        }
    }

    function refocus(nextIdx) {
        if (focusedIdx == null) {
            focusedIdx = 0
        } else {
            results[focusedIdx].style.backgroundColor = null
            focusedIdx = nextIdx
        }
        results[focusedIdx].style.backgroundColor = 'lightyellow'
        results[focusedIdx].scrollIntoView({ behavior: "smooth", block: "center" })
    }

    function handler(event) {
        if (event.target.tagName == "INPUT" || event.ctrlKey || event.altKey) return
        const result = results[focusedIdx]
        switch (event.key) {
            case 'j': {
                log('j: down')
                refocus((focusedIdx + 1) % results.length)
                break
            }
            case 'k': {
                log('k: up')
                refocus((focusedIdx - 1 + results.length) % results.length)
                break
            }
            case 'g': {
                log('g: home')
                refocus(0)
                break
            }
            case 'G': {
                log('G: end')
                refocus(results.length-1)
                break
            }
            case 'l': {
                log('l: open')
                open(result)
                break
            }
        }
    }

    window.addEventListener('keydown', handler)
})()