jQuery Herotabs
A tiny, fully accessible tab switcher for jQuery.
Useful for standard tabs and also 'hero' style tabs often found at the top of websites to display content.
Demo
https://codepen.io/simonsmith/full/wdYRva/
Features
- Fade between tabs using CSS3 transitions with
.animate()
fallback - Tested with jQuery 1.12.0+
- Keyboard navigation
- WAI-ARIA (via http://www.accessibleculture.org/articles/2010/08/aria-tabs/)
- Focus on tab contents
- Touch events
- Flexible HTML
- Rotate tabs with a delay
Installation
npm
It's recommended to require
/import
the plugin as part of an existing webpack or browserify setup:
npm install jquery jquery.herotabs --save
// index.js const $ = require('jquery'); require('jquery.herotabs'); $('#tabs').herotabs();
Herotabs relies on jQuery as a peerDependency
so ensure it is installed in your application.
Manual
Clone the repository and run npm install && npm run build
. This will generate a UMD version of the plugin in ./build
that can be dropped into a project however you want.
<script src="http://code.jquery.com/jquery-latest.js"></script> <script src="jquery.herotabs.js"></script>
Usage
JS
$('.tabs').herotabs({ // options });
HTML
A simple example of markup.
<div class="tabs"> <ul class="js-herotabs-nav"> <li class="js-herotabs-nav-item"><a href="#tab1">Item 1</a></li> <li class="js-herotabs-nav-item"><a href="#tab2">Item 2</a></li> <li class="js-herotabs-nav-item"><a href="#tab3">Item 3</a></li> </ul> <div class="js-herotabs-tab" id="tab1"> <p>content 1</p> </div> <div class="js-herotabs-tab" id="tab2"> <p>content 2</p> </div> <div class="js-herotabs-tab" id="tab3"> <p>content 3</p> </div> </div>
Herotabs depends on classnames rather than a specific structure so feel free to nest and shuffle your HTML as necessary. JS prefixed classnames are the default, but are not compulsory.
The only expectation it has is that your tab navigation will be contained by an element structure like the following:
<ul class="js-herotabs-nav"> <li class="js-herotabs-nav-item"><a href="#tab1">Item 1</a></li> <li class="js-herotabs-nav-item"><a href="#tab2">Item 2</a></li> <li class="js-herotabs-nav-item"><a href="#tab3">Item 3</a></li> </ul> <div class="js-herotabs-nav"> <span class="js-herotabs-nav-item"><a href="#tab1">Item 1</a></span> <span class="js-herotabs-nav-item"><a href="#tab2">Item 2</a></span> <span class="js-herotabs-nav-item"><a href="#tab3">Item 3</a></span> </div>
Note Your navigation anchors must link to the tab content IDs (tab behaviour), or be fully-qualified URLs (follow link behaviour).
Options
- delay - (number) How long between each tab change. If set to 0 no timed change will happen default
0
- duration - (number) If set to greater than zero, then this will decide how long it takes to fade transition between tabs otherwise it will be instant default
0
- easing - (string) Easing type, works only with CSS3 capable browsers default
ease-in-out
- startOn - (number) Index of the tab to show first default
0
- reverse - (boolean) Will reverse display order of tabs when on a timed delay default
false
- interactEvent - (string) Event to interact with the tab navigation. Possible values are
click
orhover
defaultclick
- useTouch - (boolean) - If the browser supports touch then Herotabs will try to use it instead of the
interactEvent
above defaulttrue
- useKeys - (boolean) - Attach key events default
true
- onReady - (function) - Called when the plugin has successfully instantiated. default
null
- onSetup - (function) - Called before the plugin has begun grabbing elements, setting up events etc. default
null
- css (object) Classes applied to the HTML structure
- active (string) - Added to the container when the plugin has setup default
is-active
- current (string) - Added to the current visible tab panel default
is-current-pane
- navCurrent (string) - Added to current visible nav item default
is-current-nav
- navId (string) - id to add to each nav link. Becomes
herotabs1
,herotabs2
etc defaultherotabs
- active (string) - Added to the container when the plugin has setup default
- selectors (object) - CSS selectors to grab the HTML
- tab (string) The tab panel containing the content default
.js-herotabs-tab
- nav (string) The nav container default
.js-herotabs-nav
- navItem (string) Each navigation item default
.js-herotabs-nav-item
- tab (string) The tab panel containing the content default
- zIndex (object) z-index values applied to the tabs
- bottom (number) Applied to all tabs default
1
- top (number) Applied to the currently visible tab default
2
- bottom (number) Applied to all tabs default
Overriding defaults for all instances
If you have multiple instances of Herotabs on one page then defaults used by all of them can be accessed via $.fn.herotabs.defaults
:
$.fn.herotabs.defaults.css.current = 'this-is-the-current-class'; // Create some instances $('.tabs').herotabs(); $('.other-tabs').herotabs(); // Both will use `this-is-the-current-class`
Events
Herotabs fires various events that you can listen to. They are fired off the element that herotabs
is instantiated on.
const $tabs = $('.tabs').herotabs(); $tabs.on('herotabs.show', function() { // Do something when the tab shows! }); $tabs.on('herotabs.show', function() { // Do something else when the tab has shown! });
Event parameters
Every event handler receives the jQuery event object and also the current visible tab, the index and the current selected nav item.
- tab - (jQuery object) The currently visible tab
- index - (number) The index of the currently visible tab
- nav - (jQuery object) The current selected nav item
var $tabs = $('.tabs').herotabs(); $tabs.on('herotabs.show', function(event, $tab, $index, $nav) { $tab.addClass('currently-visible-tab'); $('body').text('The current tab index is ' + $index); $nav.text('I am the current nav element'); });
herotabs.show
Fired when a tab is shown
herotabs.hide
Fired when the current tab is hidden
herotabs.next
Fired when the next tab is shown
herotabs.prev
Fired when the previous tab is shown
herotabs.start
Fired after the tabs have begun cycling on a timed delay
herotabs.stop
Fired after the tabs have stopped cycling
herotabs.mouseenter
Fired when the mouse enters the container of the tabs
herotabs.mouseleave
Fired when the mouse leaves the container of the tabs
Methods
You can get at the Herotabs instance by accessing it from the elements .data
method
const instance = $('.tabs').herotabs().data('herotabs'); instance.nextTab();
showTab
Shows a tab. Accepts a zero based index or a jQuery element
instance.showTab(2) // Index instance.showTab($('.js-herotabs-tab').eq(1)) // jQuery element
nextTab
Shows the next tab. If the current tab is the last in the set it will show the first.
instance.nextTab()
prevTab
Shows the previous tab. If the current tab is the first in the set it will show the last.
instance.prevTab()
start
If a delay is set in the options, then it will begin cycling through the tabs.
instance.start()
stop
If the tabs are currently cycling, it will stop them
instance.stop()
triggerEvent
Manually invoke a Herotabs event. Accepts an event name and jQuery object/index
instance.triggerEvent('herotabs.show', 2); // Use an index instance.triggerEvent('herotabs.show', $('.a-single-tab')); // Or a jQuery object
Due to the events being attached after the plugin has initialised, this method might be useful if you have events that need to fire immediately or from somewhere else.
Chaining
All methods return the instance so you can chain as many calls as you wish
instance.showTab(2).nextTab().nextTab();
Accessing the constructor
If for any reason you need to override or add your own methods then you can access the Herotabs prototype before initialising it:
const Herotabs = $.fn.herotabs.Herotabs; Herotabs.prototype.newMethod = function() { // Something new! }; const instance = $('.tabs').herotabs().data('herotabs'); instance.newMethod();
CommonJS
const Herotabs = require('jquery.herotabs'); Herotabs.prototype.newMethod = function() { // Something new! }; var instance = $('.tabs').herotabs().data('herotabs'); instance.newMethod();
Example
$('.tabs') .herotabs({ useTouch: false, duration: 400, interactEvent: 'hover', selectors: { tab: '.tab-panel', navItem: '.tab-nav-item', nav: '.tab-nav-container' }, onSetup: function() { // Do some setup work here // e.g. generate some markup dynamically for Herotabs to attach to } }) .on('herotabs.show', function(event, $tab) { $tab.text('You are looking at a tab!'); });
Contributing
If you find a bug or need a feature added, please open an issue first.
Running the tests
npm install npm test