diff --git a/README.md b/README.md index bbc3376..4e81953 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Notice -The script needs some bugfixing. Until then I reccomend not using it. +The script needs some bugfixing. Until then I reccomend not using it. Pull request will be appreciated ;) diff --git a/bower.json b/bower.json index ae42988..aad1dd1 100644 --- a/bower.json +++ b/bower.json @@ -2,9 +2,10 @@ "name": "tabs", "main": "tabs.js", "version": "2.0.2", - "homepage": "https://github.com/markusfalk/tabs", + "homepage": "https://github.com/SpikeShape/tabs", "authors": [ - "Markus Falk " + "Markus Falk ", + "Spike Shape " ], "description": "Simple Tab Script", "keywords": [ diff --git a/tabs.js b/tabs.js index c8dac67..9c3d4e2 100644 --- a/tabs.js +++ b/tabs.js @@ -1,14 +1,22 @@ -define(['jquery'], function($) { +/** + * An accessible tab module with anmated content and autoplay + * @module Tabs + * @requires jquery + * @author Markus Falk, Rodger Rüdiger + */ + +define(['jquery'], function() { 'use strict'; - /************************************************************ - @description Eigenes Accordion Script ermöglicht das gleichzeitige - öffnen mehrerer Accordion-Einträge - *************************************************************/ var Tabs = { - animation: {}, //animation timeout @see Tabs.start_animation + animation: {}, //animation timeout @see Tabs._start_animation skip_anim: 0, // skip first call of animation_start(); + /** + * Caches all jQuery Objects for later use. + * @function _cacheElements + * @private + */ _cacheElements: function() { this.$animatedTabs = $('.animated-tabs'); @@ -42,61 +50,76 @@ define(['jquery'], function($) { this.$tabs = $('.tab-content > div'); this.$toggle_animation_items = $('body'); }, + /** + * Initiates the module. + * @function init + * @public + */ init: function() { // Defaults - this.autoplay_speed = 5000; - this.fade_speed = 200; - this.tab_number = 1; + Tabs.autoplay_speed = 5000; + Tabs.fade_speed = 200; + Tabs.tab_number = 1; // Functions - this.cacheElements(); - this.bindEvents(); - this.addARIAlabels(); + Tabs._cacheElements(); + Tabs._bindEvents(); + Tabs._addARIAlabels(); // Animation bei Tabs starten // $('.animated-tabs').mf_DoItIfNeeded(function(){ // - Tabs.start_animation(); + // Tabs._start_animation(); // }); // events - this.$tab_element.each(function() { + Tabs.$tab_element.each(function() { $(this).trigger('tabs.initialized'); }); }, + /** + * Binds all events to jQuery DOM objects. + * @function _bindEvents + * @private + */ _bindEvents: function() { - // mouse und enter events - this.$tab_links.on('keydown', function(event) { - if (event.keyCode === 13) { + // mouse and keyboard events + Tabs.$tab_links.on('keydown', function(event) { + if (event.keyCode === 13) { // ENTER var $target_tab = $(this).attr('data-rel'); - Tabs.nextTab($(this).closest('.tabs'), $('#' + $target_tab), $(this)); + Tabs._nextTab($(this).closest('.tabs'), $('#' + $target_tab), $(this)); } }); - this.$tab_links.on('click', function(event) { + Tabs.$tab_links.on('click', function(event) { event.preventDefault(); var $target_tab = $(this).attr('data-rel'); - Tabs.nextTab($(this).closest('.tabs'), $('#' + $target_tab), $(this)); + Tabs._nextTab($(this).closest('.tabs'), $('#' + $target_tab), $(this)); }); - // Animation anhalten bei hover und bei Focus auf einem Tab + // stop animations when hovering of focusing a tab $('.main-theme').mouseenter(function() { - Tabs.stop_animation(); + Tabs._stop_animation(); }); - this.$tab_links.on('focus', function(event) { - Tabs.stop_animation(); + Tabs.$tab_links.on('focus', function(event) { + Tabs._stop_animation(); }); - // Animation wieder abspielen + // resume animation $('.main-theme').on('mouseleave', function(event) { Tabs.skip_anim = 0; //Set timeout for next tab - Tabs.start_animation(); + Tabs._start_animation(); }); }, + /** + * Sets ARIA attributes. + * @function _addARIAlabels + * @private + */ _addARIAlabels: function() { - this.$tab_element.each(function(index) { + Tabs.$tab_element.each(function(index) { var $tab_nav = $(this).find('> .tab-nav'), $tab_content = $(this).find('> .tab-content'); @@ -117,6 +140,14 @@ define(['jquery'], function($) { }); }, + /** + * Selects tab + * @function _nextTab + * @param {jQuery object} parent tab container + * @param {jQuery object} tab content of next tab + * @param {jQuery object} tab head of next tab + * @private + */ _nextTab: function($tab_element, $target_tab, $target_tab_nav) { var $current_tab = $tab_element.find('> div > .current-tab'), @@ -124,17 +155,17 @@ define(['jquery'], function($) { tabs_amount = $tab_element.find('> .tab-content > div').length; if (!$target_tab) { - // @description Setzt bei Autoplay die nächste Folie und den nächsten Navigationpunkt. - // Setzt bei Klick den Zähler für das Autoplay auf den index des geklickten Tabs. + // enable next tab if autoplay enabled + // on tab click set autoplay to index of clicked tab if (Tabs.tab_number < tabs_amount) { - // Ende noch nicht erreicht + // check if current tab is the last $target_tab = $current_tab.next(); $target_tab_nav = $current_tab_nav.next(); Tabs.tab_number = Tabs.tab_number + 1; } else { - // Ende erreicht, beginne von vorn + // start over $target_tab = $tab_element.find('> .tab-content > div:first-child'); $target_tab_nav = $tab_element.find('.tab-nav > .tab-header:first-child'); Tabs.tab_number = 1; @@ -143,27 +174,26 @@ define(['jquery'], function($) { } else { - // @description Setzt bei Klick den Zähler für das Autoplay auf den index des geklickten Tabs. + // set autoplay counter to index of clicked tab if($tab_element.hasClass('animated-tabs')) { Tabs.tab_number = $target_tab_nav.index() + 1; } } - // @description Setzt 'current'-Status auf den nächsten Eintrag. - $current_tab.fadeOut(this.fade_speed, function() { + // set current state to next tab + $current_tab.stop().fadeOut(this.fade_speed, function() { - // tab inhalt status ändern + // change state of tab content $current_tab.removeClass('current-tab') .attr('aria-expanded', 'false') .attr('aria-hidden', 'true'); - // navi status ändern + // change state of tab head $current_tab_nav.removeClass('current-tab-nav') .attr('tabindex', '0') - .attr('aria-selected', 'false') - .addClass('green'); + .attr('aria-selected', 'false'); - // neuen tab status ändern + // set new tab state to current $target_tab.fadeIn(this.fade_speed, function() { // events $target_tab.trigger('tabs.opened', [$target_tab_nav, $target_tab]); @@ -172,61 +202,72 @@ define(['jquery'], function($) { .attr('aria-hidden', 'false') .addClass('current-tab'); - // prev next Klassen entfernen + // remove classes for previous and next tab $current_tab_nav.prev().removeClass('prev-tab'); $current_tab_nav.next().removeClass('next-tab'); - // aktuellen navi status ändern + // change current tab state $target_tab_nav.addClass('current-tab-nav') .removeAttr('tabindex') - .attr('aria-selected', 'true') - .removeClass('green'); + .attr('aria-selected', 'true'); - // prev next Klassen neu erstellen + // set classes for previous and next tab $target_tab_nav.next().addClass('next-tab'); $target_tab_nav.prev().addClass('prev-tab'); - // Inhalte animieren/einblenden - Tabs.animate_content($target_tab); + // animate tab content + Tabs._animate_content($target_tab); }); }, + /** + * Starts animation of tabs. + * @function _start_animation + * @private + */ _start_animation: function() { - // initialen aufruf durch .animated-tabs verhindern + // check if first animation should be skipped if (Tabs.skip_anim > 0) { Tabs.$animatedTabs.each(function() { var that = $(this); - Tabs.nextTab(that); + Tabs._nextTab(that); that.trigger('tabs.animated', that); }); } - // timeout erstellen und skip erhöhen damit if ausgeführt wird - Tabs.animation = setTimeout(Tabs.start_animation, Tabs.autoplay_speed); + // set timeout for animation and increases skip_anim to animate following tab changes + Tabs.animation = setTimeout(Tabs._start_animation, Tabs.autoplay_speed); Tabs.skip_anim = Tabs.skip_anim + 1; }, + /** + * Clears timeout of tab animation + * @function _stop_animation + * @private + */ _stop_animation: function() { clearTimeout(Tabs.animation); }, - /************************************************************ - @description Inhalte im Tab animieren - *************************************************************/ + /** + * Animates tab content. + * @function _animate_content + * @private + */ _animate_content: function($target_tab) { - $target_tab.children().hide().delay(0).fadeIn(200); + $target_tab.children().hide().delay(0).stop().fadeIn(200); } }; - return { + return /** @alias module:Tabs */ { + /** init */ init: Tabs.init }; - });