I wrote a userscript for gelbooru, so I can move around and open images with the keyboard, to enhance my cooming™ experience. Any feedback is welcome. // UserScript // @name Keyboard controls for Gelbooru // @namespace Booru // @match https://gelbooru.com/index.php?page=* // @grant none // @version 1.0 // @author anon // @description // /UserScript const markedBorder = 'solid black 2px'; const search = document.getElementById('tags-search'); const images = document.getElementsByClassName('thumbnail-preview'); const imageHeight = images[0].clientHeight; let selectedIndex = 0; const getImagesPerRow = () => { const baseOffset = images[0].getBoundingClientRect().y; for(let i = 1; i baseOffset) return i; } return -1; }; const isOutsideViewPort = (img) => { const rect = img.getBoundingClientRect(); return (rect.top > (window.innerHeight document.documentElement.clientHeight)) (rect.bottom { // if we're above images.length - 1, then images[selectedIndex].style.border = ''; // update the indices selectedIndex = i; images[selectedIndex].style.border = markedBorder; if(isOutsideViewPort(images[selectedIndex])) images[selectedIndex].scrollIntoView(false); }; const openSelected = () => { const link = images[selectedIndex].getElementsByTagName('a')[0].href; window.open(link); }; document.addEventListener('keydown', (event) => { if(document.activeElement ! search) { if(event.ctrlKey) { const paginator = document.getElementById('paginator'); const links = Array.from(paginator.children); // there's only one b element const currentPageIndex = links.findIndex(elem => elem.tagName = 'B'); console.log(currentPageIndex); let pageToGoTo = currentPageIndex; switch(event.key) { case 'ArrowLeft': case 'a': case 'h': pageToGoTo--; if(pageToGoTo >= 0 && parseInt(links[pageToGoTo]) !== NaN) window.location = links[pageToGoTo].href; break; case 'ArrowRight': case 'd': case 'l': pageToGoTo++; if(pageToGoTo = 0 ? selectedIndex - 1 : selectedIndex); break; case 'ArrowRight': case 'd': case 'l': markSelected(selectedIndex + 1 = 0 ? selectedIndex - imagesPerRow : selectedIndex); break; case 'ArrowDown': case 's': case 'j': markSelected(selectedIndex + imagesPerRow < images.length ? selectedIndex + imagesPerRow : images.length - 1); break; case 'Enter': openSelected(); default: break;