Well, just the navigation part.
A Pen by Justin Perry on CodePen.
| <label>Search <input id="search" type="search" placeholder="Enter search term" autocomplete="off" /></label> | |
| <ul class="nav-list"> | |
| <li class="list__item"><a href="http://www.google.co.uk" target="_blank">Link 1</a></li> | |
| <li class="list__item"><a href="http://www.google.co.uk" target="_blank">Link 2</a></li> | |
| <li class="list__item"><a href="http://www.google.co.uk" target="_blank">Link 3</a></li> | |
| <li class="list__item"><a href="http://www.google.co.uk" target="_blank">Link 4</a></li> | |
| <li class="list__item"><a href="http://www.google.co.uk" target="_blank">Link 5</a></li> | |
| <li class="list__item"><a href="http://www.google.co.uk" target="_blank">Link 6</a></li> | |
| </ul> |
| function NavSelector(opts){ | |
| this.opts = opts; | |
| this.$itemsContainer = $(opts.itemsContainer); | |
| this.$items = this.$itemsContainer.find(opts.items); | |
| this.itemLink = opts.itemLink; | |
| this.$itemLinks = this.$items.find(opts.itemLink); | |
| this.$search = $(opts.search); | |
| this.onSelect = opts.onSelect || $.noop; | |
| this.keys = opts.keys || { | |
| up : 38, | |
| down : 40, | |
| select : 13, | |
| esc : 27 | |
| } | |
| } | |
| NavSelector.prototype = { | |
| start : function(){ | |
| var self = this; | |
| $(document).on('keyup', this.opts.itemsContainer, function(e){ | |
| switch(e.which){ | |
| case self.keys.up: | |
| self.updateIndex('up'); | |
| break; | |
| case self.keys.down: | |
| self.updateIndex('down'); | |
| console.log('down'); | |
| break; | |
| case self.keys.select: | |
| self.selectItem(self.currentIndex); | |
| break; | |
| case self.keys.esc: | |
| self.returnToSearch(); | |
| break; | |
| } | |
| }); | |
| }, | |
| show: function(){ | |
| this.$itemsContainer.addClass('is-active'); | |
| }, | |
| hide: function(){ | |
| this.$itemsContainer.removeClass('is-active'); | |
| }, | |
| moveFocus: function(index){ | |
| this.$items.eq(index) | |
| .find(this.itemLink) | |
| .addClass('is-active') | |
| .focus(); | |
| }, | |
| updateIndex: function(dir) { | |
| if( dir === 'up' && this.currentIndex ){ | |
| this.currentIndex--; | |
| } | |
| else if( dir === 'down' && this.currentIndex < this.$items.length ){ | |
| this.currentIndex++; | |
| } | |
| this.moveFocus(this.currentIndex); | |
| }, | |
| selectItem: function(index){ | |
| this.onSelect(index); | |
| }, | |
| focusStart: function(){ | |
| this.$currentItemLink = this.$items.find(this.itemLink).first(); | |
| this.$currentItemLink.focus(); | |
| this.currentIndex = 0; | |
| }, | |
| openNav: function(){ | |
| this.show(); | |
| this.focusStart(); | |
| }, | |
| returnToSearch: function(){ | |
| this.hide(); | |
| this.$search.focus(); | |
| }, | |
| init: function(){ | |
| this.start(); | |
| } | |
| }; | |
| var navSelector = new NavSelector({ | |
| search : '#search', | |
| itemsContainer : '.nav-list', | |
| items : '.list__item', | |
| itemLink : 'a' | |
| }); | |
| navSelector.init(); | |
| $('#search').on('keyup', function(e){ | |
| if( $(this).val().length >= 2 ){ | |
| navSelector.openNav(); | |
| } | |
| }); |
| @import "compass"; | |
| .nav-list{ | |
| border: 1px solid #ccc; | |
| border-radius: 5px; | |
| display: none; | |
| list-style: none; | |
| overflow: auto; | |
| padding: 0; | |
| &.is-active{ | |
| display: block; | |
| } | |
| .list__item{ | |
| a{ | |
| display: block; | |
| padding: 10px; | |
| text-decoration: none; | |
| &:focus{ | |
| background-color: #888; | |
| color: white; | |
| } | |
| &:hover{ | |
| background-color: #d1d1d1; | |
| } | |
| } | |
| } | |
| } |