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