您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Navigate 4chan threads with vim-style keybindings
// ==UserScript== // @name 4chan Vim Navigation // @namespace http://tampermonkey.net/ // @version 0.1 // @description Navigate 4chan threads with vim-style keybindings // @match *://boards.4chan.org/* // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; const threads = Array.from(document.querySelectorAll('.thread')); let index = 0; let buffer = ''; // For capturing gg if (threads.length === 0) return; function highlightThread(i) { threads.forEach(t => t.style.outline = ''); const thread = threads[i]; if (thread) { thread.scrollIntoView({behavior: "smooth", block: "center"}); thread.style.outline = '3px solid #4cafef'; } } highlightThread(index); document.addEventListener('keydown', (e) => { // Ignore when typing in inputs/textareas if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.isContentEditable) { return; } if (e.key === 'j') { index = Math.min(index + 1, threads.length - 1); highlightThread(index); buffer = ''; } else if (e.key === 'k') { index = Math.max(index - 1, 0); highlightThread(index); buffer = ''; } else if (e.key === 'o') { const link = threads[index].querySelector('a[href*="/thread/"]'); if (link) window.location.href = link.href; buffer = ''; } else if (e.key === 'O') { const link = threads[index].querySelector('a[href*="/thread/"]'); if (link) window.open(link.href, '_blank'); buffer = ''; } else if (e.key === 'g') { if (buffer === 'g') { index = 0; highlightThread(index); buffer = ''; } else { buffer = 'g'; setTimeout(() => buffer = '', 500); // reset if not pressed quickly } } else if (e.key === 'G') { index = threads.length - 1; highlightThread(index); buffer = ''; } }); })();