您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Shortcuts for Google Search result. j/k to move focus, l/h to open in new/background tab.
当前为
- // ==UserScript==
- // @name HjklNavigation
- // @namespace com.gmail.fujifruity.greasemonkey
- // @version 1.5.3
- // @description Shortcuts for Google Search result. j/k to move focus, l/h to open in new/background tab.
- // @author fujifruity
- // @include https://www.google.com/search*
- // @grant GM.openInTab
- // @license MIT
- // ==/UserScript==
- {
- const items = [...document.querySelectorAll('#rso .g')].filter(
- e => e.querySelectorAll(':scope > div').length == 1
- )
- const open = inForeground => {
- const url = findCurrentItem().querySelector('a').href
- GM.openInTab(url, inForeground)
- }
- const tag = "hjklNavigationCurrentItem"
- const findCurrentItem = () => items.find(e => e.hasAttribute(tag))
- const moveCursor = step => {
- const currentItem = findCurrentItem()
- const r = currentItem.getBoundingClientRect();
- const isVisible = 0 < r.top && r.top < window.innerHeight || 0 < r.bottom && r.bottom < window.innerHeight
- if (!isVisible) {
- const dist = e => {
- const r = e.getBoundingClientRect()
- return Math.abs(window.innerHeight - (r.top + r.bottom))
- }
- const nearest = items.reduce((acc,e) => dist(acc) < dist(e) ? acc : e )
- select(nearest)
- return
- }
- const nextIdx = (items.indexOf(currentItem) + step + items.length) % items.length
- select(items[nextIdx])
- }
- const highlight = e => {
- e.style.backgroundColor = 'WhiteSmoke'
- e.setAttribute(tag, '')
- }
- const select = item => {
- // deselect current item
- const currentItem = findCurrentItem()
- currentItem?.setAttribute('style', "background-color: null;")
- currentItem?.removeAttribute(tag)
- highlight(item)
- item.scrollIntoView({ behavior: "smooth", block: "center" })
- }
- highlight(items[0])
- window.addEventListener('keydown', event => {
- if (event.target.tagName == "INPUT" || event.ctrlKey || event.altKey) return
- switch (event.key) {
- case 'j': {
- moveCursor(+1)
- break
- }
- case 'k': {
- moveCursor(-1)
- break
- }
- case 'l': {
- open(true)
- break
- }
- case 'h': {
- open(false)
- break
- }
- }
- })
- }