Project

General

Profile

1
// Native Javascript for Bootstrap 3 | Dropdown
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.Dropdown = factory();
19
  }
20

    
21
})(function(root){
22

    
23
  // DROPDOWN DEFINITION
24
  // ===================
25
  var Dropdown = function( element) {
26
    this.menu = typeof element === 'object' ? element : document.querySelector(element);
27
    this.init();
28
  }
29

    
30
  // DROPDOWN METHODS
31
  // ================
32
  Dropdown.prototype = {
33

    
34
    init : function() {
35
      this.actions();
36
      this.menu.setAttribute('tabindex', '0'); // Fix onblur on Chrome | Safari
37
      document.addEventListener('click', this.handle, false);
38
    },
39

    
40
    actions : function() {
41
      var self = this;
42
      
43
      this.handle = function(e) { // fix some Safari bug with <button>
44
        var target = e.target || e.currentTarget, 
45
            children = [], c = self.menu.parentNode.getElementsByTagName('*');
46
        for ( var i=0, l = c.length||0; i<l; i++) { l && children.push(c[i]); }
47

    
48
        if ( target === self.menu || target.parentNode === self.menu ) { 
49
          self.toggle(e); 
50
        }  else if ( children && children.indexOf(target) > -1  ) {
51
          return;
52
        } else { self.close(); }
53
        /\#$/g.test(target.href) && e.preventDefault();
54
      }
55
      
56
      this.toggle = function(e) {
57
        if (/open/.test(this.menu.parentNode.className)) {
58
          this.close();
59
          document.removeEventListener('keydown', this.key, false);
60
        } else {
61
          this.menu.parentNode.className += ' open';
62
          this.menu.setAttribute('aria-expanded',true);
63
          document.addEventListener('keydown', this.key, false);
64
        }
65
      }
66
      
67
      this.key = function(e) {
68
        if (e.which == 27) {self.close();}
69
      }
70
      
71
      this.close = function() {
72
        self.menu.parentNode.className = self.menu.parentNode.className.replace(' open','');
73
        self.menu.setAttribute('aria-expanded',false);
74
      }
75
    }
76
  }
77

    
78
  // DROPDOWN DATA API
79
  // =================
80
  var Dropdowns = document.querySelectorAll('[data-toggle=dropdown]'), i = 0, ddl = Dropdowns.length;
81
  for (i;i<ddl;i++) {
82
    new Dropdown(Dropdowns[i]);
83
  }
84

    
85
  return Dropdown;
86
});
(7-7/17)