foundation.dropdown.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. ;(function ($, window, document, undefined) {
  2. 'use strict';
  3. Foundation.libs.dropdown = {
  4. name : 'dropdown',
  5. version : '5.1.1',
  6. settings : {
  7. active_class: 'open',
  8. is_hover: false,
  9. opened: function(){},
  10. closed: function(){}
  11. },
  12. init : function (scope, method, options) {
  13. Foundation.inherit(this, 'throttle');
  14. this.bindings(method, options);
  15. },
  16. events : function (scope) {
  17. var self = this,
  18. S = self.S;
  19. S(this.scope)
  20. .off('.dropdown')
  21. .on('click.fndtn.dropdown', '[' + this.attr_name() + ']', function (e) {
  22. var settings = S(this).data(self.attr_name(true) + '-init') || self.settings;
  23. e.preventDefault();
  24. if (!settings.is_hover || Modernizr.touch) self.toggle(S(this));
  25. })
  26. .on('mouseenter.fndtn.dropdown', '[' + this.attr_name() + '], [' + this.attr_name() + '-content]', function (e) {
  27. var $this = S(this);
  28. clearTimeout(self.timeout);
  29. if ($this.data(self.data_attr())) {
  30. var dropdown = S('#' + $this.data(self.data_attr())),
  31. target = $this;
  32. } else {
  33. var dropdown = $this;
  34. target = S("[" + self.attr_name() + "='" + dropdown.attr('id') + "']");
  35. }
  36. var settings = target.data(self.attr_name(true) + '-init') || self.settings;
  37. if(S(e.target).data(self.data_attr()) && settings.is_hover) {
  38. self.closeall.call(self);
  39. }
  40. if (settings.is_hover) self.open.apply(self, [dropdown, target]);
  41. })
  42. .on('mouseleave.fndtn.dropdown', '[' + this.attr_name() + '], [' + this.attr_name() + '-content]', function (e) {
  43. var $this = S(this);
  44. self.timeout = setTimeout(function () {
  45. if ($this.data(self.data_attr())) {
  46. var settings = $this.data(self.data_attr(true) + '-init') || self.settings;
  47. if (settings.is_hover) self.close.call(self, S('#' + $this.data(self.data_attr())));
  48. } else {
  49. var target = S('[' + self.attr_name() + '="' + S(this).attr('id') + '"]'),
  50. settings = target.data(self.attr_name(true) + '-init') || self.settings;
  51. if (settings.is_hover) self.close.call(self, $this);
  52. }
  53. }.bind(this), 150);
  54. })
  55. .on('click.fndtn.dropdown', function (e) {
  56. var parent = S(e.target).closest('[' + self.attr_name() + '-content]');
  57. if (S(e.target).data(self.data_attr()) || S(e.target).parent().data(self.data_attr())) {
  58. return;
  59. }
  60. if (!(S(e.target).data('revealId')) &&
  61. (parent.length > 0 && (S(e.target).is('[' + self.attr_name() + '-content]') ||
  62. $.contains(parent.first()[0], e.target)))) {
  63. e.stopPropagation();
  64. return;
  65. }
  66. self.close.call(self, S('[' + self.attr_name() + '-content]'));
  67. })
  68. .on('opened.fndtn.dropdown', '[' + self.attr_name() + '-content]', function () {
  69. self.settings.opened.call(this);
  70. })
  71. .on('closed.fndtn.dropdown', '[' + self.attr_name() + '-content]', function () {
  72. self.settings.closed.call(this);
  73. });
  74. S(window)
  75. .off('.dropdown')
  76. .on('resize.fndtn.dropdown', self.throttle(function () {
  77. self.resize.call(self);
  78. }, 50)).trigger('resize');
  79. },
  80. close: function (dropdown) {
  81. var self = this;
  82. dropdown.each(function () {
  83. if (self.S(this).hasClass(self.settings.active_class)) {
  84. self.S(this)
  85. .css(Foundation.rtl ? 'right':'left', '-99999px')
  86. .removeClass(self.settings.active_class);
  87. self.S(this).trigger('closed');
  88. }
  89. });
  90. },
  91. closeall: function() {
  92. var self = this;
  93. $.each(self.S('[' + this.attr_name() + '-content]'), function() {
  94. self.close.call(self, self.S(this))
  95. });
  96. },
  97. open: function (dropdown, target) {
  98. this
  99. .css(dropdown
  100. .addClass(this.settings.active_class), target);
  101. dropdown.trigger('opened');
  102. },
  103. data_attr: function () {
  104. if (this.namespace.length > 0) {
  105. return this.namespace + '-' + this.name;
  106. }
  107. return this.name;
  108. },
  109. toggle : function (target) {
  110. var dropdown = this.S('#' + target.data(this.data_attr()));
  111. if (dropdown.length === 0) {
  112. // No dropdown found, not continuing
  113. return;
  114. }
  115. this.close.call(this, this.S('[' + this.attr_name() + '-content]').not(dropdown));
  116. if (dropdown.hasClass(this.settings.active_class)) {
  117. this.close.call(this, dropdown);
  118. } else {
  119. this.close.call(this, this.S('[' + this.attr_name() + '-content]'))
  120. this.open.call(this, dropdown, target);
  121. }
  122. },
  123. resize : function () {
  124. var dropdown = this.S('[' + this.attr_name() + '-content].open'),
  125. target = this.S("[" + this.attr_name() + "='" + dropdown.attr('id') + "']");
  126. if (dropdown.length && target.length) {
  127. this.css(dropdown, target);
  128. }
  129. },
  130. css : function (dropdown, target) {
  131. var offset_parent = dropdown.offsetParent(),
  132. position = target.offset();
  133. position.top -= offset_parent.offset().top;
  134. position.left -= offset_parent.offset().left;
  135. if (this.small()) {
  136. dropdown.css({
  137. position : 'absolute',
  138. width: '95%',
  139. 'max-width': 'none',
  140. top: position.top + target.outerHeight()
  141. });
  142. dropdown.css(Foundation.rtl ? 'right':'left', '2.5%');
  143. } else {
  144. if (!Foundation.rtl && this.S(window).width() > dropdown.outerWidth() + target.offset().left) {
  145. var left = position.left;
  146. if (dropdown.hasClass('right')) {
  147. dropdown.removeClass('right');
  148. }
  149. } else {
  150. if (!dropdown.hasClass('right')) {
  151. dropdown.addClass('right');
  152. }
  153. var left = position.left - (dropdown.outerWidth() - target.outerWidth());
  154. }
  155. dropdown.attr('style', '').css({
  156. position : 'absolute',
  157. top: position.top + target.outerHeight(),
  158. left: left
  159. });
  160. }
  161. return dropdown;
  162. },
  163. small : function () {
  164. return matchMedia(Foundation.media_queries.small).matches &&
  165. !matchMedia(Foundation.media_queries.medium).matches;
  166. },
  167. off: function () {
  168. this.S(this.scope).off('.fndtn.dropdown');
  169. this.S('html, body').off('.fndtn.dropdown');
  170. this.S(window).off('.fndtn.dropdown');
  171. this.S('[data-dropdown-content]').off('.fndtn.dropdown');
  172. this.settings.init = false;
  173. },
  174. reflow : function () {}
  175. };
  176. }(jQuery, this, this.document));