jquery.tooltip.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /*
  2. * jQuery Tooltip plugin 1.3
  3. *
  4. * http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
  5. * http://docs.jquery.com/Plugins/Tooltip
  6. *
  7. * Copyright (c) 2006 - 2008 Jörn Zaefferer
  8. *
  9. * $Id: jquery.tooltip.js 5741 2008-06-21 15:22:16Z joern.zaefferer $
  10. *
  11. * Dual licensed under the MIT and GPL licenses:
  12. * http://www.opensource.org/licenses/mit-license.php
  13. * http://www.gnu.org/licenses/gpl.html
  14. */
  15. ;(function($) {
  16. // the tooltip element
  17. var helper = {},
  18. // the current tooltipped element
  19. current,
  20. // the title of the current element, used for restoring
  21. title,
  22. // timeout id for delayed tooltips
  23. tID,
  24. // IE 5.5 or 6
  25. IE = $.browser.msie && /MSIE\s(5\.5|6\.)/.test(navigator.userAgent),
  26. // flag for mouse tracking
  27. track = false;
  28. $.tooltip = {
  29. blocked: false,
  30. defaults: {
  31. delay: 200,
  32. fade: false,
  33. showURL: true,
  34. extraClass: "",
  35. top: 15,
  36. left: 15,
  37. id: "tooltip"
  38. },
  39. block: function() {
  40. $.tooltip.blocked = !$.tooltip.blocked;
  41. }
  42. };
  43. $.fn.extend({
  44. tooltip: function(settings) {
  45. settings = $.extend({}, $.tooltip.defaults, settings);
  46. createHelper(settings);
  47. return this.each(function() {
  48. $.data(this, "tooltip", settings);
  49. this.tOpacity = helper.parent.css("opacity");
  50. // copy tooltip into its own expando and remove the title
  51. this.tooltipText = this.title;
  52. $(this).removeAttr("title");
  53. // also remove alt attribute to prevent default tooltip in IE
  54. this.alt = "";
  55. })
  56. .mouseover(save)
  57. .mouseout(hide)
  58. .click(hide);
  59. },
  60. fixPNG: IE ? function() {
  61. return this.each(function () {
  62. var image = $(this).css('backgroundImage');
  63. if (image.match(/^url\(["']?(.*\.png)["']?\)$/i)) {
  64. image = RegExp.$1;
  65. $(this).css({
  66. 'backgroundImage': 'none',
  67. 'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
  68. }).each(function () {
  69. var position = $(this).css('position');
  70. if (position != 'absolute' && position != 'relative')
  71. $(this).css('position', 'relative');
  72. });
  73. }
  74. });
  75. } : function() { return this; },
  76. unfixPNG: IE ? function() {
  77. return this.each(function () {
  78. $(this).css({'filter': '', backgroundImage: ''});
  79. });
  80. } : function() { return this; },
  81. hideWhenEmpty: function() {
  82. return this.each(function() {
  83. $(this)[ $(this).html() ? "show" : "hide" ]();
  84. });
  85. },
  86. url: function() {
  87. return this.attr('href') || this.attr('src');
  88. }
  89. });
  90. function createHelper(settings) {
  91. // there can be only one tooltip helper
  92. if( helper.parent )
  93. return;
  94. // create the helper, h3 for title, div for url
  95. helper.parent = $('<div id="' + settings.id + '"><h3></h3><div class="body"></div><div class="url"></div></div>')
  96. // add to document
  97. .appendTo(document.body)
  98. // hide it at first
  99. .hide();
  100. // apply bgiframe if available
  101. if ( $.fn.bgiframe )
  102. helper.parent.bgiframe();
  103. // save references to title and url elements
  104. helper.title = $('h3', helper.parent);
  105. helper.body = $('div.body', helper.parent);
  106. helper.url = $('div.url', helper.parent);
  107. }
  108. function settings(element) {
  109. return $.data(element, "tooltip");
  110. }
  111. // main event handler to start showing tooltips
  112. function handle(event) {
  113. // show helper, either with timeout or on instant
  114. if( settings(this).delay )
  115. tID = setTimeout(show, settings(this).delay);
  116. else
  117. show();
  118. // if selected, update the helper position when the mouse moves
  119. track = !!settings(this).track;
  120. $(document.body).bind('mousemove', update);
  121. // update at least once
  122. update(event);
  123. }
  124. // save elements title before the tooltip is displayed
  125. function save() {
  126. // if this is the current source, or it has no title (occurs with click event), stop
  127. if ( $.tooltip.blocked || this == current || (!this.tooltipText && !settings(this).bodyHandler) )
  128. return;
  129. // save current
  130. current = this;
  131. title = this.tooltipText;
  132. if ( settings(this).bodyHandler ) {
  133. helper.title.hide();
  134. var bodyContent = settings(this).bodyHandler.call(this);
  135. if (bodyContent.nodeType || bodyContent.jquery) {
  136. helper.body.empty().append(bodyContent)
  137. } else {
  138. helper.body.html( bodyContent );
  139. }
  140. helper.body.show();
  141. } else if ( settings(this).showBody ) {
  142. var parts = title.split(settings(this).showBody);
  143. helper.title.html(parts.shift()).show();
  144. helper.body.empty();
  145. for(var i = 0, part; (part = parts[i]); i++) {
  146. if(i > 0)
  147. helper.body.append("<br/>");
  148. helper.body.append(part);
  149. }
  150. helper.body.hideWhenEmpty();
  151. } else {
  152. helper.title.html(title).show();
  153. helper.body.hide();
  154. }
  155. // if element has href or src, add and show it, otherwise hide it
  156. if( settings(this).showURL && $(this).url() )
  157. helper.url.html( $(this).url().replace('http://', '') ).show();
  158. else
  159. helper.url.hide();
  160. // add an optional class for this tip
  161. helper.parent.addClass(settings(this).extraClass);
  162. // fix PNG background for IE
  163. if (settings(this).fixPNG )
  164. helper.parent.fixPNG();
  165. handle.apply(this, arguments);
  166. }
  167. // delete timeout and show helper
  168. function show() {
  169. tID = null;
  170. if ((!IE || !$.fn.bgiframe) && settings(current).fade) {
  171. if (helper.parent.is(":animated"))
  172. helper.parent.stop().show().fadeTo(settings(current).fade, current.tOpacity);
  173. else
  174. helper.parent.is(':visible') ? helper.parent.fadeTo(settings(current).fade, current.tOpacity) : helper.parent.fadeIn(settings(current).fade);
  175. } else {
  176. helper.parent.show();
  177. }
  178. update();
  179. }
  180. /**
  181. * callback for mousemove
  182. * updates the helper position
  183. * removes itself when no current element
  184. */
  185. function update(event) {
  186. if($.tooltip.blocked)
  187. return;
  188. if (event && event.target.tagName == "OPTION") {
  189. return;
  190. }
  191. // stop updating when tracking is disabled and the tooltip is visible
  192. if ( !track && helper.parent.is(":visible")) {
  193. $(document.body).unbind('mousemove', update)
  194. }
  195. // if no current element is available, remove this listener
  196. if( current == null ) {
  197. $(document.body).unbind('mousemove', update);
  198. return;
  199. }
  200. // remove position helper classes
  201. helper.parent.removeClass("viewport-right").removeClass("viewport-bottom");
  202. var left = helper.parent[0].offsetLeft;
  203. var top = helper.parent[0].offsetTop;
  204. if (event) {
  205. // position the helper 15 pixel to bottom right, starting from mouse position
  206. left = event.pageX + settings(current).left;
  207. top = event.pageY + settings(current).top;
  208. var right='auto';
  209. if (settings(current).positionLeft) {
  210. right = $(window).width() - left;
  211. left = 'auto';
  212. }
  213. helper.parent.css({
  214. left: left,
  215. right: right,
  216. top: top
  217. });
  218. }
  219. var v = viewport(),
  220. h = helper.parent[0];
  221. // check horizontal position
  222. if (v.x + v.cx < h.offsetLeft + h.offsetWidth) {
  223. left -= h.offsetWidth + 20 + settings(current).left;
  224. helper.parent.css({left: left + 'px'}).addClass("viewport-right");
  225. }
  226. // check vertical position
  227. if (v.y + v.cy < h.offsetTop + h.offsetHeight) {
  228. top -= h.offsetHeight + 20 + settings(current).top;
  229. helper.parent.css({top: top + 'px'}).addClass("viewport-bottom");
  230. }
  231. }
  232. function viewport() {
  233. return {
  234. x: $(window).scrollLeft(),
  235. y: $(window).scrollTop(),
  236. cx: $(window).width(),
  237. cy: $(window).height()
  238. };
  239. }
  240. // hide helper and restore added classes and the title
  241. function hide(event) {
  242. if($.tooltip.blocked)
  243. return;
  244. // clear timeout if possible
  245. if(tID)
  246. clearTimeout(tID);
  247. // no more current element
  248. current = null;
  249. var tsettings = settings(this);
  250. function complete() {
  251. helper.parent.removeClass( tsettings.extraClass ).hide().css("opacity", "");
  252. }
  253. if ((!IE || !$.fn.bgiframe) && tsettings.fade) {
  254. if (helper.parent.is(':animated'))
  255. helper.parent.stop().fadeTo(tsettings.fade, 0, complete);
  256. else
  257. helper.parent.stop().fadeOut(tsettings.fade, complete);
  258. } else
  259. complete();
  260. if( settings(this).fixPNG )
  261. helper.parent.unfixPNG();
  262. }
  263. })(jQuery);