Overview
Mousetrap is a JavaScript library for handling keyboard shortcuts developed by Craig Campbell. It is a small standalone 4kb file with no external dependencies that can be easily integrated with your Jekyll website on Github pages. That’s what I’ve done here and with a bit of extra code I’ve added navigation for all the sections on this website. It works flawlessly!
How To
Step 1 - Prerequisites
Get both of the following from the author’s website:
- Mousetrap - Download the minified version from here.
- Bind Dictionary - Handy plugin that allows you to bind multiple key events in a single call.
Add the two scripts to your website and create a third one for your code:
<!-- load mousetrap -->
<script type="text/javascript" src="/assets/scripts/mousetrap.min.js">
</script>
<!-- load mousetrap bind dictionary plugin -->
<script type="text/javascript" src="/assets/scripts/mousetrap-bind-dictionary.min.js">
<script>
<!-- load custom keyboard shortcuts -->
<script type="text/javascript" src="/assets/scripts/keyboard.js">
</script>
Step 2 - Add navigation code
Navigation to sub-pages
This is very straight-forward. I’ve the following mnemonics: g h - Go Home, g b - Go Blog, etc.
// Bind keys
Mousetrap.bind({
'g h': function() { window.location.href = "/"; },
'g b': function() { window.location.href = "/blog"; },
'g c': function() { window.location.href = "/cheat-sheets"; },
'g t': function() { window.location.href = "/tips"; },
'g a': function() { window.location.href = "/about"; },
[..]
}
Navigate to next/previous post
You can also navigate between posts or elements from a custom collection. Since I already had links pointing to the previous and next entries, it was just a matter of selecting them from JS:
function blogNav(key) {
if ( key === 'h' ) {
var navPrev = document.querySelectorAll(".PageNavigation .prev")
window.location.href = navPrev[0].href;
} else if (key === 'l' ) {
var navNext = document.querySelectorAll(".PageNavigation .next")
window.location.href = navNext[0].href;
}
}
Navigate through lists
To make keyboard navigation possible within all the sections of the website, I’ve added shortcuts to cycle through post lists and categories entries, Vim-style using h/j/k/l. Developer Tools was really useful to test the JavaScript code and understand the structure of the website and how to locate list elements:
// Navigate previous/next entry VIM style
function entriesNav(key) {
var mainContent = document.getElementById("main_content");
var listEntries = [];
if (document.getElementById("archives")) {
var lists = mainContent.getElementsByTagName("ul");
for (var i=0; i<lists.length; i++){
var currListEntries = [].slice.call(lists[i].getElementsByTagName("li"));
for (var j=0; j<currListEntries.length; j++) {
listEntries.push(currListEntries[j]);
}
}
} else {
var currentList = mainContent.getElementsByTagName("ul")[0];
listEntries = [].slice.call(currentList.getElementsByTagName("li"));
}
var currentClass = mainContent.getElementsByTagName("ul")[0].className;
var idx = -1;
var currentfocus = document.activeElement;
// Get current post index
if ( currentfocus.parentElement.parentElement) {
if ( currentfocus.parentElement.parentElement.className === currentClass ) {
idx = listEntries.indexOf(currentfocus.parentElement)
}
}
// Adjust post index
if ( key === 'j' && idx < listEntries.length - 1 ) {
idx++;
} else if (key === 'k' && idx > 0 ) {
idx--;
}
// Move focus to the link
listEntries[idx].getElementsByTagName("a")[0].focus();
}
Bonus - Overlay help window
You might also want to add a nice overlay window with the shortcuts. I’m not going to include any more code here. Again, Developer Tools is amazing, check the source of the main Blog page :)