foundation.tooltips.js 7.0 KB

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