1;(function ( $, window, undefined ) { 2 3 /** Default settings */ 4 var defaults = { 5 active: null, 6 event: 'click', 7 disabled: [], 8 collapsible: 'accordion', 9 startCollapsed: false, 10 rotate: false, 11 setHash: false, 12 animation: 'default', 13 animationQueue: false, 14 duration: 500, 15 fluidHeight: true, 16 scrollToAccordion: false, 17 scrollToAccordionOnLoad: true, 18 scrollToAccordionOffset: 0, 19 accordionTabElement: '<div></div>', 20 accordionAnchorHTML:'htmlAccordion', 21 click: function(){}, 22 activate: function(){}, 23 deactivate: function(){}, 24 load: function(){}, 25 activateState: function(){}, 26 classes: { 27 stateDefault: 'r-tabs-state-default', 28 stateActive: 'r-tabs-state-active', 29 stateDisabled: 'r-tabs-state-disabled', 30 stateExcluded: 'r-tabs-state-excluded', 31 container: 'r-tabs', 32 ul: 'r-tabs-nav', 33 tab: 'r-tabs-tab', 34 anchor: 'r-tabs-anchor', 35 panel: 'r-tabs-panel', 36 accordionTitle: 'r-tabs-accordion-title', 37 38 } 39 }; 40 41 /** 42 * Responsive Tabs 43 * @constructor 44 * @param {object} element - The HTML element the validator should be bound to 45 * @param {object} options - An option map 46 */ 47 function ResponsivePostTabs(element, options) { 48 this.element = element; // Selected DOM element 49 this.$element = $(element); // Selected jQuery element 50 51 this.tabs = []; // Create tabs array 52 this.state = ''; // Define the plugin state (tabs/accordion) 53 this.rotateInterval = 0; // Define rotate interval 54 this.$queue = $({}); 55 this.isClicked = false 56 57 // Extend the defaults with the passed options 58 this.options = $.extend( {}, defaults, options); 59 60 this.init(); 61 } 62 63 64 /** 65 * This function initializes the tab plugin 66 */ 67 ResponsivePostTabs.prototype.init = function () { 68 var _this = this; 69 70 // Load all the elements 71 this.tabs = this._loadElements(); 72 this._loadClasses(); 73 this._loadEvents(); 74 75 // Window resize bind to check state 76 $(window).on('resize', function(e) { 77 _this._setState(e); 78 if(_this.options.fluidHeight !== true) { 79 _this._equaliseHeights(); 80 } 81 }); 82 83 // Hashchange event 84 $(window).on('hashchange', function(e) { 85 var tabRef = _this._getTabRefBySelector(window.location.hash); 86 var oTab = _this._getTab(tabRef); 87 88 // Check if a tab is found that matches the hash 89 if(tabRef >= 0 && !oTab._ignoreHashChange && !oTab.disabled) { 90 // If so, open the tab and auto close the current one 91 _this._openTab(e, _this._getTab(tabRef), true); 92 } 93 }); 94 95 // Start rotate event if rotate option is defined 96 if(this.options.rotate !== false) { 97 this.startRotation(); 98 } 99 100 101 // Set fluid height 102 if(this.options.fluidHeight !== true) { 103 _this._equaliseHeights(); 104 } 105 106 // -------------------- 107 // Define plugin events 108 // 109 110 // Activate: this event is called when a tab is selected 111 this.$element.bind('tabs-click', function(e, oTab) { 112 _this.options.click.call(this, e, oTab); 113 }); 114 115 // Activate: this event is called when a tab is selected 116 this.$element.bind('tabs-activate', function(e, oTab) { 117 _this.options.activate.call(this, e, oTab); 118 }); 119 // Deactivate: this event is called when a tab is closed 120 this.$element.bind('tabs-deactivate', function(e, oTab) { 121 _this.options.deactivate.call(this, e, oTab); 122 }); 123 // Activate State: this event is called when the plugin switches states 124 this.$element.bind('tabs-activate-state', function(e, state) { 125 _this.options.activateState.call(this, e, state); 126 }); 127 128 // Load: this event is called when the plugin has been loaded 129 this.$element.bind('tabs-load', function(e) { 130 131 var startTab; 132 133 _this._setState(e); // Set state 134 135 var isDesktopBeakpoint = window.matchMedia("(min-width: " + _this.options.breakpoint + "px)"); 136 137 function openFirstItem(firstTab){ 138 139 if(!firstTab) 140 startTab = _this._getStartTab(); 141 else 142 startTab = _this._getTab(0); 143 144 // Open the initial tab 145 _this._openTab(e, startTab, true); // Open first tab 146 147 // Call the callback function 148 _this.options.load.call(this, e, startTab); // Call the load callback 149 } 150 151 // Check if the panel should be collapsed on load 152 if(_this.options.startCollapsed == 'none' && !(_this.options.startCollapsed === 'accordion' && _this.state === 'accordion')){ 153 154
155 if(_this.getState() === 'tabs'){ 156 _this._getTab(0).tab.removeClass(_this.options.classes.stateDefault).addClass(_this.options.classes.stateActive); 157 } 158 159 if(_this.getState() === 'accordion'){ 160 _this._getTab(0).accordionTab.removeClass(_this.options.classes.stateDefault).addClass(_this.options.classes.stateActive); 161 } 162 openFirstItem(); 163 } 164 165 // Check if the panel should be collapsed on load 166 if(_this.options.startCollapsed == 'mobile' && !(_this.options.startCollapsed === 'accordion' && _this.state === 'accordion')) { 167 168 if(isDesktopBeakpoint.matches == true) 169 openFirstItem(); 170 171 } 172 173 if(window.location.hash && _this.options.startCollapsed != 'none' && _this.options.setHash == true){ 174 175 var tabRef = _this._getTabRefBySelector(window.location.hash); 176 startTab = _this._getTab(tabRef); 177 178 if(tabRef >= 0 && !startTab.disabled) 179 openFirstItem(); 180 } 181 182 183 }); 184 185 // Trigger loaded event 186 this.$element.trigger('tabs-load'); 187 }; 188 189 // 190 // PRIVATE FUNCTIONS 191 // 192 193 /** 194 * This function loads the tab elements and stores them in an array 195 * @returns {Array} Array of tab elements 196 */ 197 ResponsivePostTabs.prototype._loadElements = function() { 198 var _this = this; 199 var $ul = this.$element.children('ul:first'); 200 var tabs = []; 201 var id = 0; 202 var objIcons = this.options.accordionAnchorHTML; 203 204 // Add the classes to the basic html elements 205 this.$element.addClass(_this.options.classes.container); // Tab container 206 $ul.addClass(_this.options.classes.ul); // List container 207 208 // Get tab buttons and store their data in an array 209 $('li', $ul).each(function() { 210 var $tab = $(this); 211 var isExcluded = $tab.hasClass(_this.options.classes.stateExcluded); 212 var $anchor, $panel, $accordionTab, $accordionAnchor, panelSelector; 213 214 // Check if the tab should be excluded 215 if(!isExcluded) { 216 217 $anchor = $('a', $tab); 218 panelSelector = $anchor.attr('href'); 219 $panel = $(panelSelector); 220 $accordionTab = $(_this.options.accordionTabElement).insertBefore($panel); 221 $accordionAnchor = $('<a></a>').attr('href', panelSelector).html($anchor.html()).appendTo($accordionTab); 222 223 //append icon to accordion tab 224 225 226 $accordionAnchor.append(objIcons) 227 228 var oTab = { 229 _ignoreHashChange: false, 230 id: id, 231 disabled: ($.inArray(id, _this.options.disabled) !== -1), 232 tab: $(this), 233 anchor: $('a', $tab), 234 panel: $panel, 235 selector: panelSelector, 236 accordionTab: $accordionTab, 237 accordionAnchor: $accordionAnchor, 238 active: false 239 }; 240 241 // 1up the ID 242 id++; 243 // Add to tab array 244 tabs.push(oTab); 245 } 246 }); 247 return tabs; 248 }; 249 250 251 /** 252 * This function adds classes to the tab elements based on the options 253 */ 254 ResponsivePostTabs.prototype._loadClasses = function() { 255 for (var i=0; i<this.tabs.length; i++) { 256 this.tabs[i].tab.addClass(this.options.classes.stateDefault).addClass(this.options.classes.tab); 257 this.tabs[i].anchor.addClass(this.options.classes.anchor); 258 this.tabs[i].panel.addClass(this.options.classes.stateDefault).addClass(this.options.classes.panel); 259 this.tabs[i].accordionTab.addClass(this.options.classes.accordionTitle); 260 this.tabs[i].accordionAnchor.addClass(this.options.classes.anchor); 261 if(this.tabs[i].disabled) { 262 this.tabs[i].tab.removeClass(this.options.classes.stateDefault).addClass(this.options.classes.stateDisabled); 263 this.tabs[i].accordionTab.removeClass(this.options.classes.stateDefault).addClass(this.options.classes.stateDisabled); 264 } 265 } 266 }; 267 268 /** 269 * This function adds events to the tab elements 270 */ 271 ResponsivePostTabs.prototype._loadEvents = function() { 272 var _this = this; 273 274 // Define activate event on a tab element 275 var fActivate = function(e) { 276 277 //allow only one click at a time 278 if(_this.isClicked == true) 279 return(true); 280 281 _this.isClicked = true; 282 setTimeout(function(){ 283 _this.isClicked = false; 284 },100) 285 286 var current = _this._getCurrentTab(); // Fetch current tab 287 var activatedTab = e.data.tab; 288 289 e.preventDefault(); 290 291 // Trigger click event for whenever a tab is clicked/touched even if the tab is disabled 292 activatedTab.tab.trigger('tabs-click', activatedTab); 293 294 // Make sure this tab isn't disabled 295 if(!activatedTab.disabled) { 296 297 // Check if hash has to be set in the URL location 298 if(_this.options.setHash) { 299 // Set the hash using the history api if available to tackle Chromes repaint bug on hash change 300 if(history.pushState) { 301 history.pushState(null, null, window.location.origin + window.location.pathname + window.location.search + activatedTab.selector); 302 } else { 303 // Otherwise fallback to the hash update for sites that don't support the history api 304 window.location.hash = activatedTab.selector; 305 } 306 } 307 308 e.data.tab._ignoreHashChange = true; 309 310 // Check if the activated tab isnt the current one or if its collapsible. If not, do nothing 311 if(current !== activatedTab || _this._isCollapisble()) { 312 // The activated tab is either another tab of the current one. If it's the current tab it is collapsible 313 // Either way, the current tab can be closed 314 _this._closeTab(e, current); 315 316 // Check if the activated tab isnt the current one or if it isnt collapsible 317 if(current !== activatedTab || !_this._isCollapisble()) { 318 _this._openTab(e, activatedTab, false, true); 319 } 320 } 321 } 322 }; 323 324 // Loop tabs 325 for (var i=0; i<this.tabs.length; i++) { 326 327 // Add activate function to the tab and accordion selection element 328 this.tabs[i].anchor.on(_this.options.event, {tab: _this.tabs[i]}, fActivate); 329 this.tabs[i].accordionAnchor.on(_this.options.event, {tab: _this.tabs[i]}, fActivate); 330 331 } 332 }; 333 334 /** 335 * This function gets the tab that should be opened at start 336 * @returns {Object} Tab object 337 */ 338 ResponsivePostTabs.prototype._getStartTab = function() { 339 var tabRef = this._getTabRefBySelector(window.location.hash); 340 var startTab; 341 342 // Check if the page has a hash set that is linked to a tab 343 if(tabRef >= 0 && !this._getTab(tabRef).disabled) { 344 // If so, set the current tab to the linked tab 345 startTab = this._getTab(tabRef); 346 } else if(this.options.active > 0 && !this._getTab(this.options.active).disabled) { 347 startTab = this._getTab(this.options.active); 348 } else { 349 // If not, just get the first one 350 startTab = this._getTab(0); 351 } 352 353 return startTab; 354 }; 355 356 /** 357 * This function sets the current state of the plugin 358 * @param {Event} e - The event that triggers the state change 359 */ 360 ResponsivePostTabs.prototype._setState = function(e) { 361 var $ul = $('ul:first', this.$element); 362 var oldState = this.state; 363 var startCollapsedIsState = (typeof this.options.startCollapsed === 'string'); 364 var startTab; 365 366 // The state is based on the visibility of the tabs list 367 if($ul.is(':visible')){ 368 // Tab list is visible, so the state is 'tabs' 369 this.state = 'tabs'; 370 } else { 371 // Tab list is invisible, so the state is 'accordion' 372 this.state = 'accordion'; 373 } 374 375 // If the new state is different from the old state 376 if(this.state !== oldState) { 377 // If so, the state activate trigger must be called 378 this.$element.trigger('tabs-activate-state', {oldState: oldState, newState: this.state}); 379 380 // Check if the state switch should open a tab 381 if(oldState && startCollapsedIsState && this.options.startCollapsed !== this.state && this._getCurrentTab() === undefined) { 382 // Get initial tab 383 startTab = this._getStartTab(e); 384 // Open the initial tab 385 this._openTab(e, startTab); // Open first tab 386 } 387 } 388 }; 389 390 /** 391 * This function opens a tab 392 * @param {Event} e - The event that triggers the tab opening 393 * @param {Object} oTab - The tab object that should be opened 394 * @param {Boolean} closeCurrent - Defines if the current tab should be closed 395 * @param {Boolean} stopRotation - Defines if the tab rotation loop should be stopped 396 */ 397 ResponsivePostTabs.prototype._openTab = function(e, oTab, closeCurrent, stopRotation) { 398 399 var _this = this; 400 var scrollOffset; 401 402 // Check if the current tab has to be closed 403 if(closeCurrent) { 404 this._closeTab(e, this._getCurrentTab()); 405 } 406 407 // Check if the rotation has to be stopped when activated 408 if(stopRotation && this.rotateInterval > 0) { 409 this.stopRotation(); 410 } 411 412 if(oTab == undefined) 413 return(false) 414 415 // Set this tab to active 416 oTab.active = true; 417 // Set active classes to the tab button and accordion tab button 418
419 if(_this.getState() === 'tabs'){ 420 oTab.tab.removeClass(_this.options.classes.stateDefault).addClass(_this.options.classes.stateActive); 421 } 422 423 if(_this.getState() === 'accordion'){ 424 oTab.accordionTab.removeClass(_this.options.classes.stateDefault).addClass(_this.options.classes.stateActive); 425 } 426 427 // Run panel transiton 428 _this._doTransition(oTab.panel, _this.options.animation, 'open', function() { 429 var scrollOnLoad = (e.type !== 'tabs-load' || _this.options.scrollToAccordionOnLoad); 430 431 // When finished, set active class to the panel 432 oTab.panel.removeClass(_this.options.classes.stateDefault).addClass(_this.options.classes.stateActive); 433 434 // And if enabled and state is accordion, scroll to the accordion tab 435 if(_this.getState() === 'accordion' && _this.options.scrollToAccordion && (!_this._isInView(oTab.accordionTab) || _this.options.animation !== 'default') && scrollOnLoad) { 436 437 // Add offset element's height to scroll position 438 scrollOffset = oTab.accordionTab.offset().top - _this.options.scrollToAccordionOffset; 439 440 // Check if the animation option is enabled, and if the duration isn't 0 441 if(_this.options.animation !== 'default' && _this.options.duration > 0) { 442 // If so, set scrollTop with animate and use the 'animation' duration 443 $('html, body').animate({ 444 scrollTop: scrollOffset 445 }, _this.options.duration); 446 } else { 447 // If not, just set scrollTop 448 $('html, body').scrollTop(scrollOffset); 449 } 450 } 451 }); 452 453 this.$element.trigger('tabs-activate', oTab); 454 }; 455 456 /** 457 * This function closes a tab 458 * @param {Event} e - The event that is triggered when a tab is closed 459 * @param {Object} oTab - The tab object that should be closed 460 */ 461 ResponsivePostTabs.prototype._closeTab = function(e, oTab) { 462 var _this = this; 463 var doQueueOnState = typeof _this.options.animationQueue === 'string'; 464 var doQueue; 465 466 if(oTab !== undefined) {
467 if(doQueueOnState && _this.getState() === _this.options.animationQueue) { 468 doQueue = true; 469 } else if(doQueueOnState) { 470 doQueue = false; 471 } else { 472 doQueue = _this.options.animationQueue; 473 } 474 475 // Deactivate tab 476 oTab.active = false; 477 // Set default class to the tab button 478 oTab.tab.removeClass(_this.options.classes.stateActive).addClass(_this.options.classes.stateDefault); 479 480 // Run panel transition 481 _this._doTransition(oTab.panel, _this.options.animation, 'close', function() { 482 // Set default class to the accordion tab button and tab panel 483 oTab.accordionTab.removeClass(_this.options.classes.stateActive).addClass(_this.options.classes.stateDefault); 484 oTab.panel.removeClass(_this.options.classes.stateActive).addClass(_this.options.classes.stateDefault); 485 }, !doQueue); 486 487 this.$element.trigger('tabs-deactivate', oTab); 488 } 489 }; 490 491 /** 492 * This function runs an effect on a panel 493 * @param {Element} panel - The HTML element of the tab panel 494 * @param {String} method - The transition method reference 495 * @param {String} state - The state (open/closed) that the panel should transition to 496 * @param {Function} callback - The callback function that is called after the transition 497 * @param {Boolean} dequeue - Defines if the event queue should be dequeued after the transition 498 */ 499 ResponsivePostTabs.prototype._doTransition = function(panel, method, state, callback, dequeue) { 500 var effect; 501 var _this = this; 502 503 // Get effect based on method 504 switch(method) { 505 case 'slide': 506 effect = (state === 'open') ? 'slideDown' : 'slideUp'; 507 break; 508 case 'fade': 509 effect = (state === 'open') ? 'fadeIn' : 'fadeOut'; 510 break; 511 default: 512 effect = (state === 'open') ? 'show' : 'hide'; 513 // When default is used, set the duration to 0 514 _this.options.duration = 0; 515 break; 516 } 517 518 // Add the transition to a custom queue 519 this.$queue.queue('responsive-tabs',function(next){ 520 // Run the transition on the panel 521 panel[effect]({ 522 duration: _this.options.duration, 523 complete: function() { 524 // Call the callback function 525 callback.call(panel, method, state); 526 // Run the next function in the queue 527 next(); 528 } 529 }); 530 }); 531 532 // When the panel is openend, dequeue everything so the animation starts 533 if(state === 'open' || dequeue) { 534 this.$queue.dequeue('responsive-tabs'); 535 } 536 537 }; 538 539 /** 540 * This function returns the collapsibility of the tab in this state 541 * @returns {Boolean} The collapsibility of the tab 542 */ 543 ResponsivePostTabs.prototype._isCollapisble = function() { 544 return (typeof this.options.collapsible === 'boolean' && this.options.collapsible) || (typeof this.options.collapsible === 'string' && this.options.collapsible === this.getState()); 545 }; 546 547 /** 548 * This function returns a tab by numeric reference 549 * @param {Integer} numRef - Numeric tab reference 550 * @returns {Object} Tab object 551 */ 552 ResponsivePostTabs.prototype._getTab = function(numRef) { 553 return this.tabs[numRef]; 554 }; 555 556 /** 557 * This function returns the numeric tab reference based on a hash selector 558 * @param {String} selector - Hash selector 559 * @returns {Integer} Numeric tab reference 560 */ 561 ResponsivePostTabs.prototype._getTabRefBySelector = function(selector) { 562 // Loop all tabs 563 for (var i=0; i<this.tabs.length; i++) { 564 // Check if the hash selector is equal to the tab selector 565 if(this.tabs[i].selector === selector) { 566 return i; 567 } 568 } 569 // If none is found return a negative index 570 return -1; 571 }; 572 573 /** 574 * This function returns the current tab element 575 * @returns {Object} Current tab element 576 */ 577 ResponsivePostTabs.prototype._getCurrentTab = function() { 578 return this._getTab(this._getCurrentTabRef()); 579 }; 580 581 /** 582 * This function returns the next tab's numeric reference 583 * @param {Integer} currentTabRef - Current numeric tab reference 584 * @returns {Integer} Numeric tab reference 585 */ 586 ResponsivePostTabs.prototype._getNextTabRef = function(currentTabRef) { 587 var tabRef = (currentTabRef || this._getCurrentTabRef()); 588 var nextTabRef = (tabRef === this.tabs.length - 1) ? 0 : tabRef + 1; 589 return (this._getTab(nextTabRef).disabled) ? this._getNextTabRef(nextTabRef) : nextTabRef; 590 }; 591 592 /** 593 * This function returns the previous tab's numeric reference 594 * @returns {Integer} Numeric tab reference 595 */ 596 ResponsivePostTabs.prototype._getPreviousTabRef = function() { 597 return (this._getCurrentTabRef() === 0) ? this.tabs.length - 1 : this._getCurrentTabRef() - 1; 598 }; 599 600 /** 601 * This function returns the current tab's numeric reference 602 * @returns {Integer} Numeric tab reference 603 */ 604 ResponsivePostTabs.prototype._getCurrentTabRef = function() { 605 // Loop all tabs 606 for (var i=0; i<this.tabs.length; i++) { 607 // If this tab is active, return it 608 if(this.tabs[i].active) { 609 return i; 610 } 611 } 612 // No tabs have been found, return negative index 613 return -1; 614 }; 615 616 /** 617 * This function gets the tallest tab and applied the height to all tabs 618 */ 619 ResponsivePostTabs.prototype._equaliseHeights = function() { 620 var maxHeight = 0; 621 622 $.each($.map(this.tabs, function(tab) { 623 maxHeight = Math.max(maxHeight, tab.panel.css('minHeight', '').height()); 624 return tab.panel; 625 }), function() { 626 this.css('minHeight', maxHeight); 627 }); 628 }; 629 630 // 631 // HELPER FUNCTIONS 632 // 633 634 ResponsivePostTabs.prototype._isInView = function($element) { 635 var docViewTop = $(window).scrollTop(), 636 docViewBottom = docViewTop + $(window).height(), 637 elemTop = $element.offset().top, 638 elemBottom = elemTop + $element.height(); 639 return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop)); 640 }; 641 642 // 643 // PUBLIC FUNCTIONS 644 // 645 646 /** 647 * This function activates a tab 648 * @param {Integer} tabRef - Numeric tab reference 649 * @param {Boolean} stopRotation - Defines if the tab rotation should stop after activation 650 */ 651 ResponsivePostTabs.prototype.activate = function(tabRef, stopRotation) { 652 var e = jQuery.Event('tabs-activate'); 653 var oTab = this._getTab(tabRef); 654 if(!oTab.disabled) { 655 this._openTab(e, oTab, true, stopRotation || true); 656 } 657 }; 658 659 /** 660 * This function deactivates a tab 661 * @param {Integer} tabRef - Numeric tab reference 662 */ 663 ResponsivePostTabs.prototype.deactivate = function(tabRef) { 664 var e = jQuery.Event('tabs-dectivate'); 665 var oTab = this._getTab(tabRef); 666 if(!oTab.disabled) { 667 this._closeTab(e, oTab); 668 } 669 }; 670 671 /** 672 * This function enables a tab 673 * @param {Integer} tabRef - Numeric tab reference 674 */ 675 ResponsivePostTabs.prototype.enable = function(tabRef) { 676 var oTab = this._getTab(tabRef); 677
678 if(oTab){ 679 oTab.disabled = false; 680 oTab.tab.addClass(this.options.classes.stateDefault).removeClass(this.options.classes.stateDisabled); 681 oTab.accordionTab.addClass(this.options.classes.stateDefault).removeClass(this.options.classes.stateDisabled); 682 } 683 }; 684 685 /** 686 * This function disable a tab 687 * @param {Integer} tabRef - Numeric tab reference 688 */ 689 ResponsivePostTabs.prototype.disable = function(tabRef) { 690 var oTab = this._getTab(tabRef); 691 if(oTab){ 692 oTab.disabled = true; 693 oTab.tab.removeClass(this.options.classes.stateDefault).addClass(this.options.classes.stateDisabled); 694 oTab.accordionTab.removeClass(this.options.classes.stateDefault).addClass(this.options.classes.stateDisabled); 695 } 696 }; 697 698 /** 699 * This function gets the current state of the plugin 700 * @returns {String} State of the plugin 701 */ 702 ResponsivePostTabs.prototype.getState = function() { 703 return this.state; 704 }; 705 706 /** 707 * This function starts the rotation of the tabs 708 * @param {Integer} speed - The speed of the rotation 709 */ 710 ResponsivePostTabs.prototype.startRotation = function(speed) { 711 var _this = this; 712 // Make sure not all tabs are disabled 713 if(this.tabs.length > this.options.disabled.length) { 714 this.rotateInterval = setInterval(function(){ 715 var e = jQuery.Event('rotate'); 716 _this._openTab(e, _this._getTab(_this._getNextTabRef()), true); 717 }, speed || (($.isNumeric(_this.options.rotate)) ? _this.options.rotate : 4000) ); 718 } else { 719 throw new Error("Rotation is not possible if all tabs are disabled"); 720 } 721 }; 722 723 /** 724 * This function stops the rotation of the tabs 725 */ 726 ResponsivePostTabs.prototype.stopRotation = function() { 727 window.clearInterval(this.rotateInterval); 728 this.rotateInterval = 0; 729 }; 730 731 /** 732 * This function can be used to get/set options 733 * @return {any} Option value 734 */ 735 ResponsivePostTabs.prototype.option = function(key, value) { 736 if(value) { 737 this.options[key] = value; 738 } 739 return this.options[key]; 740 }; 741 742 /** jQuery wrapper */ 743 $.fn.responsivePostTabs = function ( event, options, elem ) { 744 var args = arguments; 745 var instance; 746 747 if(event == 'init'){ 748 749 if (options === undefined || typeof options === 'object') { 750 751 return this.each(function () { 752 if (!$.data(this, 'responsiveposttabs')) { 753 $.data(this, 'responsiveposttabs', new ResponsivePostTabs( this, options )); 754 } 755 }); 756 757 } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') { 758 instance = $.data(this[0], 'responsiveposttabs'); 759 760 // Allow instances to be destroyed via the 'destroy' method 761 if (options === 'destroy') { 762 763 //customization: unbind event before binding (for filters begaviour) 764 $(this).unbind('tabs-load'); 765 $(this).unbind('tabs-click'); 766 $(this).unbind('tabs-activate'); 767 $(this).unbind('tabs-deactivate'); 768 $(this).unbind('tabs-activate-state'); 769 770 // TODO: destroy instance classes, etc 771 $.data(this, 'responsiveposttabs', null); 772 } 773 774 if (instance instanceof ResponsivePostTabs && typeof instance[options] === 'function') { 775 return instance[options].apply( instance, Array.prototype.slice.call( args, 1 ) ); 776 } else { 777 return this; 778 } 779 } 780 781 } 782 783 if(event == 'reinit'){ 784 785 if (options === undefined || typeof options === 'object') { 786 787 if (!$.data(this, 'responsiveposttabs')) { 788 $.data(this, 'responsiveposttabs', new ResponsivePostTabs( elem, options )); 789 790 } 791 792 } 793 794 } 795 796 797 }; 798 799}(jQuery, window));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.