Вход Регистрация
Файл: CLOUDME-HTML-RTL-SUPPORT/js/vendor/jquery.responsiveTabs.js
Строк: 893
<?php
/*!
 *  Project: jquery.responsiveTabs.js
 *  Description: A plugin that creates responsive tabs, optimized for all devices
 *  Author: Jelle Kralt (jelle@jellekralt.nl)
 *  Version: 1.4.5
 *  License: MIT
 */

;(function ( $, windowundefined ) {

    
/** Default settings */
    
var defaults = {
        
activenull,
        
event'click',
        
disabled: [],
        
collapsible'accordion',
        
startCollapsedfalse,
        
rotatefalse,
        
setHashfalse,
        
animation'default',
        
animationQueuefalse,
        
duration500,
        
scrollToAccordionfalse,
        
activate: function(){},
        
deactivate: function(){},
        
load: function(){},
        
activateState: function(){},
        
classes: {
            
stateDefault'r-tabs-state-default',
            
stateActive'r-tabs-state-active',
            
stateDisabled'r-tabs-state-disabled',
            
stateExcluded'r-tabs-state-excluded',
            
tab'r-tabs-tab',
            
anchor'r-tabs-anchor',
            
panel'r-tabs-panel',
            
accordionTitle'r-tabs-accordion-title'
        
}
    };

    
/**
     * Responsive Tabs
     * @constructor
     * @param {object} element - The HTML element the validator should be bound to
     * @param {object} options - An option map
     */
    
function ResponsiveTabs(elementoptions) {
        
this.element element// Selected DOM element
        
this.$element = $(element); // Selected jQuery element

        
this.tabs = []; // Create tabs array
        
this.state ''// Define the plugin state (tabs/accordion)
        
this.rotateInterval 0// Define rotate interval
        
this.$queue = $({});

        
// Extend the defaults with the passed options
        
this.options = $.extend( {}, defaultsoptions);

        
this.init();
    }


    
/**
     * This function initializes the tab plugin
     */
    
ResponsiveTabs.prototype.init = function () {
        var 
_this this;

        
// Load all the elements
        
this.tabs this._loadElements();
        
this._loadClasses();
        
this._loadEvents();

        
// Window resize bind to check state
        
$(window).on('resize', function(e) {
            
_this._setState(e);
        });

        
// Hashchange event
        
$(window).on('hashchange', function(e) {
            var 
tabRef _this._getTabRefBySelector(window.location.hash);
            var 
oTab _this._getTab(tabRef);

            
// Check if a tab is found that matches the hash
            
if(tabRef >= && !oTab._ignoreHashChange && !oTab.disabled) {
                
// If so, open the tab and auto close the current one
                
_this._openTab(e_this._getTab(tabRef), true);
            }
        });

        
// Start rotate event if rotate option is defined
        
if(this.options.rotate !== false) {
            
this.startRotation();
        }

        
// --------------------
        // Define plugin events
        //

        // Activate: this event is called when a tab is selected
        
this.$element.bind('tabs-activate', function(eoTab) {
            
_this.options.activate.call(thiseoTab);
        });
        
// Deactivate: this event is called when a tab is closed
        
this.$element.bind('tabs-deactivate', function(eoTab) {
            
_this.options.deactivate.call(thiseoTab);
        });
        
// Activate State: this event is called when the plugin switches states
        
this.$element.bind('tabs-activate-state', function(estate) {
            
_this.options.activateState.call(thisestate);
        });

        
// Load: this event is called when the plugin has been loaded
        
this.$element.bind('tabs-load', function(e) {
            var 
startTab;

            
_this._setState(e); // Set state

            // Check if the panel should be collaped on load
            
if(_this.options.startCollapsed !== true && !(_this.options.startCollapsed === 'accordion' && _this.state === 'accordion')) {

                
startTab _this._getStartTab();

                
// Open the initial tab
                
_this._openTab(estartTab); // Open first tab

                // Call the callback function
                
_this.options.load.call(thisestartTab); // Call the load callback
            
}
        });
        
// Trigger loaded event
        
this.$element.trigger('tabs-load');
    };
    
    
//
    // PRIVATE FUNCTIONS
    //

    /**
     * This function loads the tab elements and stores them in an array
     * @returns {Array} Array of tab elements
     */
    
ResponsiveTabs.prototype._loadElements = function() {
        var 
_this this;
        var 
$ul this.$element.children('ul');
        var 
tabs = [];
        var 
id 0;

        
// Add the classes to the basic html elements
        
this.$element.addClass('r-tabs'); // Tab container
        
$ul.addClass('r-tabs-nav'); // List container

        // Get tab buttons and store their data in an array
        
$('li'$ul).each(function() {
            var 
$tab = $(this);
            var 
isExcluded $tab.hasClass(_this.options.classes.stateExcluded);
            var 
$anchor$panel$accordionTab$accordionAnchorpanelSelector;

            
// Check if the tab should be excluded
            
if(!isExcluded) {

                
$anchor = $('a'$tab);
                
panelSelector $anchor.attr('href');
                
$panel = $(panelSelector);
                
$accordionTab = $('<div></div>').insertBefore($panel);
                
$accordionAnchor = $('<a></a>').attr('href'panelSelector).html($anchor.html()).appendTo($accordionTab);

                var 
oTab = {
                    
_ignoreHashChangefalse,
                    
idid,
                    
disabled: ($.inArray(id_this.options.disabled) !== -1),
                    
tab: $(this),
                    
anchor: $('a'$tab),
                    
panel$panel,
                    
selectorpanelSelector,
                    
accordionTab$accordionTab,
                    
accordionAnchor$accordionAnchor,
                    
activefalse
                
};

                
// 1up the ID
                
id++;
                
// Add to tab array
                
tabs.push(oTab);
            }
        });
        return 
tabs;
    };


    
/**
     * This function adds classes to the tab elements based on the options
     */
    
ResponsiveTabs.prototype._loadClasses = function() {
        for (var 
i=0i<this.tabs.lengthi++) {
            
this.tabs[i].tab.addClass(this.options.classes.stateDefault).addClass(this.options.classes.tab);
            
this.tabs[i].anchor.addClass(this.options.classes.anchor);
            
this.tabs[i].panel.addClass(this.options.classes.stateDefault).addClass(this.options.classes.panel);
            
this.tabs[i].accordionTab.addClass(this.options.classes.accordionTitle);
            
this.tabs[i].accordionAnchor.addClass(this.options.classes.anchor);
            if(
this.tabs[i].disabled) {
                
this.tabs[i].tab.removeClass(this.options.classes.stateDefault).addClass(this.options.classes.stateDisabled);
                
this.tabs[i].accordionTab.removeClass(this.options.classes.stateDefault).addClass(this.options.classes.stateDisabled);
           }
        }
    };

    
/**
     * This function adds events to the tab elements
     */
    
ResponsiveTabs.prototype._loadEvents = function() {
        var 
_this this;

        
// Define activate event on a tab element
        
var fActivate = function(e) {
            var 
current _this._getCurrentTab(); // Fetch current tab
            
var activatedTab e.data.tab;

            
e.preventDefault();

            
// Make sure this tab isn't disabled
            
if(!activatedTab.disabled) {

                
// Check if hash has to be set in the URL location
                
if(_this.options.setHash) {
                    
// Set the hash using the history api if available to tackle Chromes repaint bug on hash change
                    
if(history.pushState) {
                        
history.pushState(nullnullactivatedTab.selector);
                    } else {
                        
// Otherwise fallback to the hash update for sites that don't support the history api
                        
window.location.hash activatedTab.selector;
                    }
                }

                
e.data.tab._ignoreHashChange true;

                
// Check if the activated tab isnt the current one or if its collapsible. If not, do nothing
                
if(current !== activatedTab || _this._isCollapisble()) {
                    
// The activated tab is either another tab of the current one. If it's the current tab it is collapsible
                    // Either way, the current tab can be closed
                    
_this._closeTab(ecurrent);

                    
// Check if the activated tab isnt the current one or if it isnt collapsible
                    
if(current !== activatedTab || !_this._isCollapisble()) {
                        
_this._openTab(eactivatedTabfalsetrue);
                    }
                }
            }
        };

        
// Loop tabs
        
for (var i=0i<this.tabs.lengthi++) {
            
// Add activate function to the tab and accordion selection element
            
this.tabs[i].anchor.on(_this.options.event, {tab_this.tabs[i]}, fActivate);
            
this.tabs[i].accordionAnchor.on(_this.options.event, {tab_this.tabs[i]}, fActivate);
        }
    };

    
/**
     * This function gets the tab that should be opened at start
     * @returns {Object} Tab object
     */
    
ResponsiveTabs.prototype._getStartTab = function() {
        var 
tabRef this._getTabRefBySelector(window.location.hash);
        var 
startTab;
        
        
// Check if the page has a hash set that is linked to a tab
        
if(tabRef >= && !this._getTab(tabRef).disabled) {
            
// If so, set the current tab to the linked tab
            
startTab this._getTab(tabRef);
        } else if(
this.options.active && !this._getTab(this.options.active).disabled) {
            
startTab this._getTab(this.options.active);
        } else {
            
// If not, just get the first one
            
startTab this._getTab(0);
        }

        return 
startTab;
    };

    
/**
     * This function sets the current state of the plugin
     * @param {Event} e - The event that triggers the state change
     */
    
ResponsiveTabs.prototype._setState = function(e) {
        var 
$ul = $('ul'this.$element);
        var 
oldState this.state;
        var 
startCollapsedIsState = (typeof this.options.startCollapsed === 'string');
        var 
startTab;

        
// The state is based on the visibility of the tabs list
        
if($ul.is(':visible')){
            
// Tab list is visible, so the state is 'tabs'
            
this.state 'tabs';
        } else {
            
// Tab list is invisible, so the state is 'accordion'
            
this.state 'accordion';
        }

        
// If the new state is different from the old state
        
if(this.state !== oldState) {
            
// If so, the state activate trigger must be called
            
this.$element.trigger('tabs-activate-state', {oldStateoldStatenewStatethis.state});

            
// Check if the state switch should open a tab
            
if(oldState && startCollapsedIsState && this.options.startCollapsed !== this.state && this._getCurrentTab() === undefined) {
                
// Get initial tab
                
startTab this._getStartTab(e);
                
// Open the initial tab
                
this._openTab(estartTab); // Open first tab
            
}
        }
    };

    
/**
     * This function opens a tab
     * @param {Event} e - The event that triggers the tab opening
     * @param {Object} oTab - The tab object that should be opened
     * @param {Boolean} closeCurrent - Defines if the current tab should be closed
     * @param {Boolean} stopRotation - Defines if the tab rotation loop should be stopped
     */
    
ResponsiveTabs.prototype._openTab = function(eoTabcloseCurrentstopRotation) {
        var 
_this this;

        
// Check if the current tab has to be closed
        
if(closeCurrent) {
            
this._closeTab(ethis._getCurrentTab());
        }

        
// Check if the rotation has to be stopped when activated
        
if(stopRotation && this.rotateInterval 0) {
            
this.stopRotation();
        }

        
// Set this tab to active
        
oTab.active true;
        
// Set active classes to the tab button and accordion tab button
        
oTab.tab.removeClass(_this.options.classes.stateDefault).addClass(_this.options.classes.stateActive);
        
oTab.accordionTab.removeClass(_this.options.classes.stateDefault).addClass(_this.options.classes.stateActive);

        
// Run panel transiton
        
_this._doTransition(oTab.panel_this.options.animation'open', function() {
            
// When finished, set active class to the panel
            
oTab.panel.removeClass(_this.options.classes.stateDefault).addClass(_this.options.classes.stateActive);
          
           
// And if enabled and state is accordion, scroll to the accordion tab
            
if(_this.getState() === 'accordion' && _this.options.scrollToAccordion && (!_this._isInView(oTab.accordionTab) || _this.options.animation !== 'default')) {
                
// Check if the animation option is enabled, and if the duration isn't 0
                
if(_this.options.animation !== 'default' && _this.options.duration 0) {
                    
// If so, set scrollTop with animate and use the 'animation' duration
                    
$('html, body').animate({
                        
scrollTopoTab.accordionTab.offset().top
                    
}, _this.options.duration);
                } else {
                    
//  If not, just set scrollTop
                    
$('html, body').scrollTop(oTab.accordionTab.offset().top);
                }
            }
        });

        
this.$element.trigger('tabs-activate'oTab);
    };

    
/**
     * This function closes a tab
     * @param {Event} e - The event that is triggered when a tab is closed
     * @param {Object} oTab - The tab object that should be closed
     */
    
ResponsiveTabs.prototype._closeTab = function(eoTab) {
        var 
_this this;
        var 
doQueueOnState typeof _this.options.animationQueue === 'string';
        var 
doQueue;

        if(
oTab !== undefined) {
            if(
doQueueOnState && _this.getState() === _this.options.animationQueue) {
                
doQueue true;
            } else if(
doQueueOnState) {
                
doQueue false;
            } else {
                
doQueue _this.options.animationQueue;
            }

            
// Deactivate tab
            
oTab.active false;
            
// Set default class to the tab button
            
oTab.tab.removeClass(_this.options.classes.stateActive).addClass(_this.options.classes.stateDefault);

            
// Run panel transition
            
_this._doTransition(oTab.panel_this.options.animation'close', function() {
                
// Set default class to the accordion tab button and tab panel
                
oTab.accordionTab.removeClass(_this.options.classes.stateActive).addClass(_this.options.classes.stateDefault);
                
oTab.panel.removeClass(_this.options.classes.stateActive).addClass(_this.options.classes.stateDefault);
            }, !
doQueue);

            
this.$element.trigger('tabs-deactivate'oTab);
        }
    };

    
/**
     * This function runs an effect on a panel
     * @param {Element} panel - The HTML element of the tab panel
     * @param {String} method - The transition method reference
     * @param {String} state - The state (open/closed) that the panel should transition to
     * @param {Function} callback - The callback function that is called after the transition
     * @param {Boolean} dequeue - Defines if the event queue should be dequeued after the transition
     */
    
ResponsiveTabs.prototype._doTransition = function(panelmethodstatecallbackdequeue) {
        var 
effect;
        var 
_this this;

        
// Get effect based on method
        
switch(method) {
            case 
'slide':
                
effect = (state === 'open') ? 'slideDown' 'slideUp';
                break;
            case 
'fade':
                
effect = (state === 'open') ? 'fadeIn' 'fadeOut';
                break;
            default:
                
effect = (state === 'open') ? 'show' 'hide';
                
// When default is used, set the duration to 0
                
_this.options.duration 0;
                break;
        }

        
// Add the transition to a custom queue
        
this.$queue.queue('responsive-tabs',function(next){
            
// Run the transition on the panel
            
panel[effect]({
                
duration_this.options.duration,
                
complete: function() {
                    
// Call the callback function
                    
callback.call(panelmethodstate);
                    
// Run the next function in the queue
                    
next();
                }
            });
        });

        
// When the panel is openend, dequeue everything so the animation starts
        
if(state === 'open' || dequeue) {
            
this.$queue.dequeue('responsive-tabs');
        }

    };

    
/**
     * This function returns the collapsibility of the tab in this state
     * @returns {Boolean} The collapsibility of the tab
     */
    
ResponsiveTabs.prototype._isCollapisble = function() {
        return (
typeof this.options.collapsible === 'boolean' && this.options.collapsible) || (typeof this.options.collapsible === 'string' && this.options.collapsible === this.getState());
    };

    
/**
     * This function returns a tab by numeric reference
     * @param {Integer} numRef - Numeric tab reference
     * @returns {Object} Tab object
     */
    
ResponsiveTabs.prototype._getTab = function(numRef) {
        return 
this.tabs[numRef];
    };

    
/**
     * This function returns the numeric tab reference based on a hash selector
     * @param {String} selector - Hash selector
     * @returns {Integer} Numeric tab reference
     */
    
ResponsiveTabs.prototype._getTabRefBySelector = function(selector) {
        
// Loop all tabs
        
for (var i=0i<this.tabs.lengthi++) {
            
// Check if the hash selector is equal to the tab selector
            
if(this.tabs[i].selector === selector) {
                return 
i;
            }
        }
        
// If none is found return a negative index
        
return -1;
    };

    
/**
     * This function returns the current tab element
     * @returns {Object} Current tab element
     */
    
ResponsiveTabs.prototype._getCurrentTab = function() {
        return 
this._getTab(this._getCurrentTabRef());
    };

    
/**
     * This function returns the next tab's numeric reference
     * @param {Integer} currentTabRef - Current numeric tab reference
     * @returns {Integer} Numeric tab reference
     */
    
ResponsiveTabs.prototype._getNextTabRef = function(currentTabRef) {
        var 
tabRef = (currentTabRef || this._getCurrentTabRef());
        var 
nextTabRef = (tabRef === this.tabs.length 1) ? tabRef 1;
        return (
this._getTab(nextTabRef).disabled) ? this._getNextTabRef(nextTabRef) : nextTabRef;
    };

    
/**
     * This function returns the previous tab's numeric reference
     * @returns {Integer} Numeric tab reference
     */
    
ResponsiveTabs.prototype._getPreviousTabRef = function() {
        return (
this._getCurrentTabRef() === 0) ? this.tabs.length this._getCurrentTabRef() - 1;
    };

    
/**
     * This function returns the current tab's numeric reference
     * @returns {Integer} Numeric tab reference
     */
    
ResponsiveTabs.prototype._getCurrentTabRef = function() {
        
// Loop all tabs
        
for (var i=0i<this.tabs.lengthi++) {
            
// If this tab is active, return it
            
if(this.tabs[i].active) {
                return 
i;
            }
        }
        
// No tabs have been found, return negative index
        
return -1;
    };

    
//
    // HELPER FUNCTIONS
    // 

    
ResponsiveTabs.prototype._isInView = function($element) {
        var 
docViewTop = $(window).scrollTop(),
            
docViewBottom docViewTop + $(window).height(),
            
elemTop $element.offset().top,
            
elemBottom elemTop $element.height();
        return ((
elemBottom <= docViewBottom) && (elemTop >= docViewTop));
    };

    
//
    // PUBLIC FUNCTIONS
    //

    /**
     * This function activates a tab
     * @param {Integer} tabRef - Numeric tab reference
     * @param {Boolean} stopRotation - Defines if the tab rotation should stop after activation
     */
    
ResponsiveTabs.prototype.activate = function(tabRefstopRotation) {
        var 
jQuery.Event('tabs-activate');
        var 
oTab this._getTab(tabRef);
        if(!
oTab.disabled) {
            
this._openTab(eoTabtruestopRotation || true);
        }
    };

    
/**
     * This function deactivates a tab
     * @param {Integer} tabRef - Numeric tab reference
     */
    
ResponsiveTabs.prototype.deactivate = function(tabRef) {
        var 
jQuery.Event('tabs-dectivate');
        var 
oTab this._getTab(tabRef);
        if(!
oTab.disabled) {
            
this._closeTab(eoTab);
        }
    };

    
/**
     * This function enables a tab
     * @param {Integer} tabRef - Numeric tab reference
     */
    
ResponsiveTabs.prototype.enable = function(tabRef) {
        var 
oTab this._getTab(tabRef);
        if(
oTab){
            
oTab.disabled false;
            
oTab.tab.addClass(this.options.classes.stateDefault).removeClass(this.options.classes.stateDisabled);
            
oTab.accordionTab.addClass(this.options.classes.stateDefault).removeClass(this.options.classes.stateDisabled);
        }
    };

    
/**
     * This function disable a tab
     * @param {Integer} tabRef - Numeric tab reference
     */
    
ResponsiveTabs.prototype.disable = function(tabRef) {
        var 
oTab this._getTab(tabRef);
        if(
oTab){
            
oTab.disabled true;
            
oTab.tab.removeClass(this.options.classes.stateDefault).addClass(this.options.classes.stateDisabled);
            
oTab.accordionTab.removeClass(this.options.classes.stateDefault).addClass(this.options.classes.stateDisabled);
        }
    };

    
/**
     * This function gets the current state of the plugin
     * @returns {String} State of the plugin
     */
    
ResponsiveTabs.prototype.getState = function() {
        return 
this.state;
    };

    
/**
     * This function starts the rotation of the tabs
     * @param {Integer} speed - The speed of the rotation
     */
    
ResponsiveTabs.prototype.startRotation = function(speed) {
        var 
_this this;
        
// Make sure not all tabs are disabled
        
if(this.tabs.length this.options.disabled.length) {
            
this.rotateInterval setInterval(function(){
                var 
jQuery.Event('rotate');
                
_this._openTab(e_this._getTab(_this._getNextTabRef()), true);
            }, 
speed || (($.isNumeric(_this.options.rotate)) ? _this.options.rotate 4000) );
        } else {
            throw new 
Error("Rotation is not possible if all tabs are disabled");
        }
    };

    
/**
     * This function stops the rotation of the tabs
     */
    
ResponsiveTabs.prototype.stopRotation = function() {
        
window.clearInterval(this.rotateInterval);
        
this.rotateInterval 0;
    };

    
/**
     * This function can be used to get/set options
     * @return {any} Option value
     */
    
ResponsiveTabs.prototype.option = function(keyvalue) {
        if(
value) {
            
this.options[key] = value;
        }
        return 
this.options[key];
    };

    
/** jQuery wrapper */
    
$.fn.responsiveTabs = function ( options ) {
        var 
args arguments;
        if (
options === undefined || typeof options === 'object') {
            return 
this.each(function () {
                if (!$.
data(this'responsivetabs')) {
                    $.
data(this'responsivetabs', new ResponsiveTabsthisoptions ));
                }
            });
        } else if (
typeof options === 'string' && options[0] !== '_' && options !== 'init') {
            return 
this.each(function () {
                var 
instance = $.data(this'responsivetabs');

                if (
instance instanceof ResponsiveTabs && typeof instance[options] === 'function') {
                    
instance[options].applyinstance, Array.prototype.slice.callargs) );
                }

                
// Allow instances to be destroyed via the 'destroy' method
                
if (options === 'destroy') {
                    
// TODO: destroy instance classes, etc
                    
$.data(this'responsivetabs'null);
                }
            });
        }
    };

}(
jQuerywindow));
?>
Онлайн: 2
Реклама