|
// ==UserScript== |
|
// @name YouTube Keyboard Navigation |
|
// @namespace http://tampermonkey.net/ |
|
// @version 1.1 |
|
// @description Navigate YouTube videos with Vim-style keys and open with Enter or Cmd+Enter |
|
// @match https://www.youtube.com/* |
|
// @match https://www.youtube.com/feed/* |
|
// @grant none |
|
// ==/UserScript== |
|
|
|
/** |
|
* YouTube Keyboard Navigation |
|
* |
|
* Navigate YouTube like a pro using Vim-style keys: |
|
* |
|
* - Ctrl-H / Ctrl-L → Move left/right |
|
* - Ctrl-J / Ctrl-K → Move down/up a row (no wraparound) |
|
* - Ctrl-A → Jump to the first video |
|
* - Ctrl-E → Jump to the last video |
|
* - Enter → Open selected video |
|
* - Cmd+Enter → Open selected video in a new tab |
|
* |
|
* Tested in Safari with UserScripts. Should also work in Chrome or Firefox. |
|
*/ |
|
|
|
(function () { |
|
'use strict'; |
|
|
|
let selectedIndex = 0; |
|
|
|
function getVideoItems() { |
|
const isSearchPage = window.location.pathname.startsWith('/results'); |
|
const selector = isSearchPage ? 'ytd-video-renderer' : 'ytd-rich-item-renderer'; |
|
return Array.from(document.querySelectorAll(selector)).filter(el => |
|
el.offsetParent !== null |
|
); |
|
} |
|
|
|
function getVideosPerRow() { |
|
const items = getVideoItems(); |
|
if (items.length < 2) return 1; |
|
|
|
const firstTop = items[0].offsetTop; |
|
return items.findIndex(item => item.offsetTop !== firstTop) || items.length; |
|
} |
|
|
|
function scrollToAndHighlight(index) { |
|
const items = getVideoItems(); |
|
if (!items[index]) return; |
|
|
|
items.forEach(item => (item.style.outline = '')); |
|
const target = items[index]; |
|
target.scrollIntoView({ behavior: 'smooth', block: 'center' }); |
|
target.style.outline = '3px solid #3ea6ff'; |
|
} |
|
|
|
function selectVideoByOffset(offset, isVertical = false, allowWrap = true) { |
|
const items = getVideoItems(); |
|
if (!items.length) return; |
|
|
|
const step = isVertical ? getVideosPerRow() : 1; |
|
const newIndex = selectedIndex + offset * step; |
|
|
|
if (newIndex < 0 || newIndex >= items.length) { |
|
if (allowWrap) { |
|
selectedIndex = (newIndex + items.length) % items.length; |
|
} |
|
return; // Don't move if disallowed |
|
} |
|
|
|
selectedIndex = newIndex; |
|
scrollToAndHighlight(selectedIndex); |
|
} |
|
|
|
function jumpToVideo(index) { |
|
const items = getVideoItems(); |
|
if (items[index]) { |
|
selectedIndex = index; |
|
scrollToAndHighlight(index); |
|
} |
|
} |
|
|
|
function activateSelectedVideo(openInNewTab = false) { |
|
const items = getVideoItems(); |
|
const item = items[selectedIndex]; |
|
if (!item) return; |
|
|
|
const isSearchPage = window.location.pathname.startsWith('/results'); |
|
const linkSelector = isSearchPage ? 'a#video-title' : 'a#video-title-link'; |
|
const link = item.querySelector(linkSelector); |
|
|
|
if (link) { |
|
if (openInNewTab) { |
|
window.open(link.href, '_blank'); |
|
} else { |
|
link.click(); |
|
} |
|
} else { |
|
item.click(); // Fallback |
|
} |
|
} |
|
|
|
document.addEventListener('keydown', (e) => { |
|
const key = e.key.toLowerCase(); |
|
if (!e.ctrlKey && !e.metaKey && key !== 'enter') return; |
|
|
|
if (e.ctrlKey) { |
|
switch (key) { |
|
case 'h': |
|
e.preventDefault(); |
|
return selectVideoByOffset(-1); |
|
case 'l': |
|
e.preventDefault(); |
|
return selectVideoByOffset(1); |
|
case 'j': |
|
e.preventDefault(); |
|
return selectVideoByOffset(1, true, false); // no wrap |
|
case 'k': |
|
e.preventDefault(); |
|
return selectVideoByOffset(-1, true, false); // no wrap |
|
case 'a': |
|
e.preventDefault(); |
|
return jumpToVideo(0); |
|
case 'e': |
|
e.preventDefault(); |
|
return jumpToVideo(getVideoItems().length - 1); |
|
} |
|
} |
|
|
|
if (key === 'enter') { |
|
e.preventDefault(); |
|
activateSelectedVideo(e.metaKey); |
|
} |
|
}); |
|
|
|
// Initial selection |
|
setTimeout(() => scrollToAndHighlight(selectedIndex), 1000); |
|
})(); |
🎬 YouTube Vim-style Navigation with Tampermonkey
This UserScript lets you browse YouTube using your keyboard, inspired by Vim-style navigation. Perfect for navigating your YouTube experience without touching the mouse.
✨ Features
📍 Supported Pages
🔧 Notes
Enjoy navigating YouTube without leaving the keyboard! 😎