Project

General

Profile

1
// Native Javascript for Bootstrap 3 | Tab
2
// by dnp_theme
3

    
4
(function(factory){
5

    
6
  // CommonJS/RequireJS and "native" compatibility
7
  if(typeof module !== "undefined" && typeof exports == "object") {
8
    // A commonJS/RequireJS environment
9
    if(typeof window != "undefined") {
10
      // Window and document exist, so return the factory's return value.
11
      module.exports = factory();
12
    } else {
13
      // Let the user give the factory a Window and Document.
14
      module.exports = factory;
15
    }
16
  } else {
17
    // Assume a traditional browser.
18
    window.Tab = factory();
19
  }
20

    
21
})(function(){
22

    
23
  // TAB DEFINITION
24
  // ===================
25
  var Tab = function( element,options ) {
26
    options = options || {};
27
    this.isIE = (new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent) != null) ? parseFloat( RegExp.$1 ) : false; 
28
    this.tab = typeof element === 'object' ? element : document.querySelector(element);
29
    this.tabs = this.tab.parentNode.parentNode;
30
    this.dropdown = this.tabs.querySelector('.dropdown');
31
    if ( /dropdown-menu/.test(this.tabs.className) ) {
32
      this.dropdown = this.tabs.parentNode;
33
      this.tabs = this.tabs.parentNode.parentNode;
34
    }
35
    this.options = options;
36

    
37
    // default tab transition duration
38
    this.duration = 150;
39
    this.options.duration = (this.isIE && this.isIE < 10)  ? 0 : (options.duration || this.duration);
40
    this.init();
41
  }
42

    
43
  // TAB METHODS
44
  // ================
45
  Tab.prototype = {
46

    
47
    init : function() {
48
      this.actions();
49
      this.tab.addEventListener('click', this.action, false);
50
    },
51

    
52
    actions : function() {
53
      var self = this;
54

    
55
      this.action = function(e) {
56
        e = e || window.e; e.preventDefault();
57
        var next = e.target; //the tab we clicked is now the next tab
58
        var nextContent = document.getElementById(next.getAttribute('href').replace('#','')); //this is the actual object, the next tab content to activate
59
        var isDropDown = new RegExp('(?:^|\\s)'+ 'dropdown-menu' +'(?!\\S)');
60
        
61
        // get current active tab and content
62
        var activeTab = self.getActiveTab();
63
        var activeContent = self.getActiveContent();
64

    
65
        if ( !/active/.test(next.parentNode.className) ) {
66
          // toggle "active" class name
67
          self.removeClass(activeTab,'active');
68
          self.addClass(next.parentNode,'active');    
69
  
70
          // handle dropdown menu "active" class name    
71
          if ( self.dropdown ) {
72
            if ( !(isDropDown.test(self.tab.parentNode.parentNode.className)) ) {
73
              if (/active/.test(self.dropdown.className)) self.removeClass(self.dropdown,'active');
74
            } else {
75
              if (!/active/.test(self.dropdown.className)) self.addClass(self.dropdown,'active');
76
            }
77
          }
78
  
79
          //1. hide current active content first
80
          self.removeClass(activeContent,'in');
81
          
82
          setTimeout(function() { // console.log(self)
83
            //2. toggle current active content from view
84
            self.removeClass(activeContent,'active');
85
            self.addClass(nextContent,'active');
86
          }, self.options.duration);
87
          setTimeout(function() {
88
            //3. show next active content
89
            self.addClass(nextContent,'in');
90
          }, self.options.duration*2);
91
        }
92
      },
93
      this.addClass = function(el,c) {
94
        if (el.classList) { el.classList.add(c); } else { el.className += ' '+c; }
95
      },
96
      this.removeClass = function(el,c) {
97
        if (el.classList) { el.classList.remove(c); } else { el.className = el.className.replace(c,'').replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,''); }
98
      },
99
      this.getActiveTab = function() {
100
        var activeTabs = this.tabs.querySelectorAll('.active');
101
        if ( activeTabs.length === 1 && !/dropdown/.test(activeTabs[0].className) ) {
102
          return activeTabs[0]
103
        } else if ( activeTabs.length > 1 ) {
104
          return activeTabs[activeTabs.length-1]
105
        }
106
      },
107
      this.getActiveContent = function() {
108
        var a = this.getActiveTab().getElementsByTagName('A')[0].getAttribute('href').replace('#','');
109
        return a && document.getElementById(a)
110
      }
111
    }
112
  }
113

    
114

    
115
  // TAB DATA API
116
  // =================
117
  var Tabs = document.querySelectorAll("[data-toggle='tab'], [data-toggle='pill']"), tbl = Tabs.length, i=0;
118
  for ( i;i<tbl;i++ ) {
119
    var tab = Tabs[i], options = {};
120
    options.duration = tab.getAttribute('data-duration') && tab.getAttribute('data-duration') || false;
121
    new Tab(tab,options);
122
  }
123

    
124
  return Tab;
125

    
126
});
(16-16/17)