foundation.tooltip.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. ;(function ($, window, document, undefined) {
  2. 'use strict';
  3. Foundation.libs.tooltip = {
  4. name : 'tooltip',
  5. version : '5.0.0',
  6. settings : {
  7. additional_inheritable_classes : [],
  8. tooltip_class : '.tooltip',
  9. append_to: 'body',
  10. touch_close_text: 'Tap To Close',
  11. disable_for_touch: false,
  12. tip_template : function (selector, content) {
  13. return '<span data-selector="' + selector + '" class="'
  14. + Foundation.libs.tooltip.settings.tooltip_class.substring(1)
  15. + '">' + content + '<span class="nub"></span></span>';
  16. }
  17. },
  18. cache : {},
  19. init : function (scope, method, options) {
  20. this.bindings(method, options);
  21. },
  22. events : function () {
  23. var self = this;
  24. if (Modernizr.touch) {
  25. $(this.scope)
  26. .off('.tooltip')
  27. .on('click.fndtn.tooltip touchstart.fndtn.tooltip touchend.fndtn.tooltip',
  28. '[data-tooltip]', function (e) {
  29. var settings = $.extend({}, self.settings, self.data_options($(this)));
  30. if (!settings.disable_for_touch) {
  31. e.preventDefault();
  32. $(settings.tooltip_class).hide();
  33. self.showOrCreateTip($(this));
  34. }
  35. })
  36. .on('click.fndtn.tooltip touchstart.fndtn.tooltip touchend.fndtn.tooltip',
  37. this.settings.tooltip_class, function (e) {
  38. e.preventDefault();
  39. $(this).fadeOut(150);
  40. });
  41. } else {
  42. $(this.scope)
  43. .off('.tooltip')
  44. .on('mouseenter.fndtn.tooltip mouseleave.fndtn.tooltip',
  45. '[data-tooltip]', function (e) {
  46. var $this = $(this);
  47. if (/enter|over/i.test(e.type)) {
  48. self.showOrCreateTip($this);
  49. } else if (e.type === 'mouseout' || e.type === 'mouseleave') {
  50. self.hide($this);
  51. }
  52. });
  53. }
  54. },
  55. showOrCreateTip : function ($target) {
  56. var $tip = this.getTip($target);
  57. if ($tip && $tip.length > 0) {
  58. return this.show($target);
  59. }
  60. return this.create($target);
  61. },
  62. getTip : function ($target) {
  63. var selector = this.selector($target),
  64. tip = null;
  65. if (selector) {
  66. tip = $('span[data-selector="' + selector + '"]' + this.settings.tooltip_class);
  67. }
  68. return (typeof tip === 'object') ? tip : false;
  69. },
  70. selector : function ($target) {
  71. var id = $target.attr('id'),
  72. dataSelector = $target.attr('data-tooltip') || $target.attr('data-selector');
  73. if ((id && id.length < 1 || !id) && typeof dataSelector != 'string') {
  74. dataSelector = 'tooltip' + Math.random().toString(36).substring(7);
  75. $target.attr('data-selector', dataSelector);
  76. }
  77. return (id && id.length > 0) ? id : dataSelector;
  78. },
  79. create : function ($target) {
  80. var $tip = $(this.settings.tip_template(this.selector($target), $('<div></div>').html($target.attr('title')).html())),
  81. classes = this.inheritable_classes($target);
  82. $tip.addClass(classes).appendTo(this.settings.append_to);
  83. if (Modernizr.touch) {
  84. $tip.append('<span class="tap-to-close">'+this.settings.touch_close_text+'</span>');
  85. }
  86. $target.removeAttr('title').attr('title','');
  87. this.show($target);
  88. },
  89. reposition : function (target, tip, classes) {
  90. var width, nub, nubHeight, nubWidth, column, objPos;
  91. tip.css('visibility', 'hidden').show();
  92. width = target.data('width');
  93. nub = tip.children('.nub');
  94. nubHeight = nub.outerHeight();
  95. nubWidth = nub.outerHeight();
  96. objPos = function (obj, top, right, bottom, left, width) {
  97. return obj.css({
  98. 'top' : (top) ? top : 'auto',
  99. 'bottom' : (bottom) ? bottom : 'auto',
  100. 'left' : (left) ? left : 'auto',
  101. 'right' : (right) ? right : 'auto',
  102. 'width' : (width) ? width : 'auto'
  103. }).end();
  104. };
  105. objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', target.offset().left, width);
  106. if (this.small()) {
  107. objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', 12.5, $(this.scope).width());
  108. tip.addClass('tip-override');
  109. objPos(nub, -nubHeight, 'auto', 'auto', target.offset().left);
  110. } else {
  111. var left = target.offset().left;
  112. if (Foundation.rtl) {
  113. left = target.offset().left + target.offset().width - tip.outerWidth();
  114. }
  115. objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', left, width);
  116. tip.removeClass('tip-override');
  117. if (classes && classes.indexOf('tip-top') > -1) {
  118. objPos(tip, (target.offset().top - tip.outerHeight()), 'auto', 'auto', left, width)
  119. .removeClass('tip-override');
  120. } else if (classes && classes.indexOf('tip-left') > -1) {
  121. objPos(tip, (target.offset().top + (target.outerHeight() / 2) - nubHeight*2.5), 'auto', 'auto', (target.offset().left - tip.outerWidth() - nubHeight), width)
  122. .removeClass('tip-override');
  123. } else if (classes && classes.indexOf('tip-right') > -1) {
  124. objPos(tip, (target.offset().top + (target.outerHeight() / 2) - nubHeight*2.5), 'auto', 'auto', (target.offset().left + target.outerWidth() + nubHeight), width)
  125. .removeClass('tip-override');
  126. }
  127. }
  128. tip.css('visibility', 'visible').hide();
  129. },
  130. small : function () {
  131. return matchMedia(Foundation.media_queries.small).matches;
  132. },
  133. inheritable_classes : function (target) {
  134. var inheritables = ['tip-top', 'tip-left', 'tip-bottom', 'tip-right', 'noradius'].concat(this.settings.additional_inheritable_classes),
  135. classes = target.attr('class'),
  136. filtered = classes ? $.map(classes.split(' '), function (el, i) {
  137. if ($.inArray(el, inheritables) !== -1) {
  138. return el;
  139. }
  140. }).join(' ') : '';
  141. return $.trim(filtered);
  142. },
  143. show : function ($target) {
  144. var $tip = this.getTip($target);
  145. this.reposition($target, $tip, $target.attr('class'));
  146. $tip.fadeIn(150);
  147. },
  148. hide : function ($target) {
  149. var $tip = this.getTip($target);
  150. $tip.fadeOut(150);
  151. },
  152. // deprecate reload
  153. reload : function () {
  154. var $self = $(this);
  155. return ($self.data('fndtn-tooltips')) ? $self.foundationTooltips('destroy').foundationTooltips('init') : $self.foundationTooltips('init');
  156. },
  157. off : function () {
  158. $(this.scope).off('.fndtn.tooltip');
  159. $(this.settings.tooltip_class).each(function (i) {
  160. $('[data-tooltip]').get(i).attr('title', $(this).text());
  161. }).remove();
  162. },
  163. reflow : function () {}
  164. };
  165. }(jQuery, this, this.document));