mirror of
https://github.com/jquery/jquery-ui.git
synced 2024-11-21 11:04:24 +00:00
Overhaul tooltip implementation. Avoid queuing and other problems by
creating the tooltip element on the fly, never reusing it. Use aria-describedby attribute to find the associated tooltip again. Allows customizing animations much easier (just replace fadeIn/fadeOut), still open. Updated demos and visual test to replace now-missing .widget() method. Added tooltipClass for that.
This commit is contained in:
parent
bc65675330
commit
67d49f593b
@ -11,12 +11,15 @@
|
|||||||
<link type="text/css" href="../demos.css" rel="stylesheet" />
|
<link type="text/css" href="../demos.css" rel="stylesheet" />
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(function() {
|
$(function() {
|
||||||
|
// TODO overhaul this with custom animation API
|
||||||
$(".demo").tooltip({
|
$(".demo").tooltip({
|
||||||
open: function() {
|
open: function() {
|
||||||
$(this).tooltip("widget").stop(false, true).hide().slideDown();
|
$(".ui-tooltip").stop(false, true).hide().slideDown();
|
||||||
},
|
},
|
||||||
close: function() {
|
close: function() {
|
||||||
$(this).tooltip("widget").stop(false, true).show().slideUp();
|
$(".ui-tooltip").stop(false, false).show().slideUp(function() {
|
||||||
|
$(this).remove();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
<li><a href="tracking.html">Track the mouse</a></li>
|
<li><a href="tracking.html">Track the mouse</a></li>
|
||||||
<li><a href="custom-animation.html">Custom animation</a></li>
|
<li><a href="custom-animation.html">Custom animation</a></li>
|
||||||
<li><a href="delegation-mixbag.html">Delegation Mixbag</a></li>
|
<li><a href="delegation-mixbag.html">Delegation Mixbag</a></li>
|
||||||
|
<li><a href="lots.html">Lots</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -13,12 +13,11 @@
|
|||||||
$(function() {
|
$(function() {
|
||||||
$(".demo").tooltip({
|
$(".demo").tooltip({
|
||||||
open: function() {
|
open: function() {
|
||||||
var tooltip = $(this).tooltip("widget");
|
var tooltip = $( ".ui-tooltip" );
|
||||||
$(document).mousemove(function( event ) {
|
$(document).mousemove(function( event ) {
|
||||||
tooltip.position( {
|
tooltip.position( {
|
||||||
my: "left center",
|
my: "left+25 center",
|
||||||
at: "right center",
|
at: "right+25 center",
|
||||||
offset: "25 25",
|
|
||||||
of: event
|
of: event
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
@ -10,7 +10,9 @@
|
|||||||
<script type="text/javascript" src="../../../ui/jquery.ui.position.js"></script>
|
<script type="text/javascript" src="../../../ui/jquery.ui.position.js"></script>
|
||||||
<script type="text/javascript" src="../../../ui/jquery.ui.button.js"></script>
|
<script type="text/javascript" src="../../../ui/jquery.ui.button.js"></script>
|
||||||
<script type="text/javascript" src="../../../ui/jquery.ui.tooltip.js"></script>
|
<script type="text/javascript" src="../../../ui/jquery.ui.tooltip.js"></script>
|
||||||
|
<!--
|
||||||
<script type="text/javascript" src="http://jqueryui.com/themeroller/themeswitchertool/"></script>
|
<script type="text/javascript" src="http://jqueryui.com/themeroller/themeswitchertool/"></script>
|
||||||
|
-->
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(function() {
|
$(function() {
|
||||||
$.fn.themeswitcher && $('<div/>').css({
|
$.fn.themeswitcher && $('<div/>').css({
|
||||||
@ -24,14 +26,16 @@
|
|||||||
$("#context1, form, #childish").tooltip();
|
$("#context1, form, #childish").tooltip();
|
||||||
|
|
||||||
// custom class, replaces ui-widget-content
|
// custom class, replaces ui-widget-content
|
||||||
$("#context2").tooltip().each(function() {
|
$("#context2").tooltip({
|
||||||
$(this).tooltip("widget").addClass("ui-widget-header");
|
tooltipClass: "ui-widget-header"
|
||||||
})
|
});
|
||||||
$("#right1").tooltip().tooltip("widget").addClass("ui-state-error");
|
$("#right1").tooltip({
|
||||||
|
tooltipClass: "ui-state-error"
|
||||||
|
});
|
||||||
|
|
||||||
// synchronous content
|
// synchronous content
|
||||||
$("#footnotes").tooltip({
|
$("#footnotes").tooltip({
|
||||||
items: "[href^=#]",
|
items: "[href^='#']",
|
||||||
content: function() {
|
content: function() {
|
||||||
return $($(this).attr("href")).html();
|
return $($(this).attr("href")).html();
|
||||||
}
|
}
|
||||||
@ -64,12 +68,13 @@
|
|||||||
|
|
||||||
// custom position
|
// custom position
|
||||||
$("#right2").tooltip({
|
$("#right2").tooltip({
|
||||||
|
tooltipClass: "ui-state-highlight",
|
||||||
position: {
|
position: {
|
||||||
my: "center top",
|
my: "center top",
|
||||||
at: "center bottom",
|
at: "center bottom",
|
||||||
offset: "0 10"
|
offset: "0 10"
|
||||||
}
|
}
|
||||||
}).tooltip("widget").addClass("ui-state-highlight");
|
});
|
||||||
|
|
||||||
$("#button1").button();
|
$("#button1").button();
|
||||||
$("#button2").button({
|
$("#button2").button({
|
||||||
@ -94,12 +99,12 @@
|
|||||||
enable();
|
enable();
|
||||||
|
|
||||||
$("#disable").toggle(function() {
|
$("#disable").toggle(function() {
|
||||||
$("*").tooltip("disable");
|
$(":ui-tooltip").tooltip("disable");
|
||||||
}, function() {
|
}, function() {
|
||||||
$("*").tooltip("enable");
|
$(":ui-tooltip").tooltip("enable");
|
||||||
});
|
});
|
||||||
$("#toggle").toggle(function() {
|
$("#toggle").toggle(function() {
|
||||||
$("*").tooltip("destroy");
|
$(":ui-tooltip").tooltip("destroy");
|
||||||
}, function() {
|
}, function() {
|
||||||
enable();
|
enable();
|
||||||
});
|
});
|
||||||
|
106
ui/jquery.ui.tooltip.js
vendored
106
ui/jquery.ui.tooltip.js
vendored
@ -18,6 +18,7 @@ var increments = 0;
|
|||||||
|
|
||||||
$.widget("ui.tooltip", {
|
$.widget("ui.tooltip", {
|
||||||
options: {
|
options: {
|
||||||
|
tooltipClass: null,
|
||||||
items: "[title]",
|
items: "[title]",
|
||||||
content: function() {
|
content: function() {
|
||||||
return $( this ).attr( "title" );
|
return $( this ).attr( "title" );
|
||||||
@ -29,24 +30,9 @@ $.widget("ui.tooltip", {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
_create: function() {
|
_create: function() {
|
||||||
var self = this;
|
this._bind( {
|
||||||
this.tooltip = $("<div></div>")
|
mouseover: "open",
|
||||||
.attr("id", "ui-tooltip-" + increments++)
|
focusin: "open"
|
||||||
.attr("role", "tooltip")
|
|
||||||
.attr("aria-hidden", "true")
|
|
||||||
.addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content")
|
|
||||||
.appendTo(document.body)
|
|
||||||
.hide();
|
|
||||||
this.tooltipContent = $("<div></div>")
|
|
||||||
.addClass("ui-tooltip-content")
|
|
||||||
.appendTo(this.tooltip);
|
|
||||||
this.opacity = this.tooltip.css("opacity");
|
|
||||||
this.element
|
|
||||||
.bind("focus.tooltip mouseover.tooltip", function(event) {
|
|
||||||
self.open( event );
|
|
||||||
})
|
|
||||||
.bind("blur.tooltip mouseout.tooltip", function(event) {
|
|
||||||
self.close( event );
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -55,34 +41,28 @@ $.widget("ui.tooltip", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
disable: function() {
|
disable: function() {
|
||||||
|
// only set option, disable element style changes
|
||||||
this.options.disabled = true;
|
this.options.disabled = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
_destroy: function() {
|
|
||||||
this.tooltip.remove();
|
|
||||||
},
|
|
||||||
|
|
||||||
widget: function() {
|
|
||||||
return this.element.pushStack(this.tooltip.get());
|
|
||||||
},
|
|
||||||
|
|
||||||
open: function(event) {
|
open: function(event) {
|
||||||
var target = $(event && event.target || this.element).closest(this.options.items);
|
var target = $(event && event.target || this.element).closest(this.options.items);
|
||||||
if ( !target.length ) {
|
if ( !target.length ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// already visible? possible when both focus and mouseover events occur
|
|
||||||
if (this.current && this.current[0] == target[0])
|
|
||||||
return;
|
|
||||||
var self = this;
|
var self = this;
|
||||||
this.current = target;
|
if ( !target.data("tooltip-title") ) {
|
||||||
this.currentTitle = target.attr("title");
|
target.data("tooltip-title", target.attr("title"));
|
||||||
|
}
|
||||||
var content = this.options.content.call(target[0], function(response) {
|
var content = this.options.content.call(target[0], function(response) {
|
||||||
// IE may instantly serve a cached response, need to give it a chance to finish with _open before that
|
// IE may instantly serve a cached response, need to give it a chance to finish with _open before that
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
// ignore async responses that come in after the tooltip is already hidden
|
// when undefined, it got removeAttr, then ignore (ajax response)
|
||||||
if (self.current == target)
|
// intially its an empty string, so not undefined
|
||||||
|
// TODO is there a better approach to enable ajax tooltips to have two updates?
|
||||||
|
if (target.attr( "aria-describedby" ) !== undefined) {
|
||||||
self._open(event, target, response);
|
self._open(event, target, response);
|
||||||
|
}
|
||||||
}, 13);
|
}, 13);
|
||||||
});
|
});
|
||||||
if (content) {
|
if (content) {
|
||||||
@ -99,39 +79,65 @@ $.widget("ui.tooltip", {
|
|||||||
if ( this.options.disabled )
|
if ( this.options.disabled )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.tooltipContent.html(content);
|
// ajaxy tooltip can update an existing one
|
||||||
this.tooltip.css({
|
var tooltip = this._find( target );
|
||||||
top: 0,
|
if (!tooltip.length) {
|
||||||
left: 0
|
tooltip = this._tooltip();
|
||||||
}).show().position( $.extend({
|
target.attr( "aria-describedby", tooltip.attr( "id" ) );
|
||||||
|
}
|
||||||
|
tooltip.find(".ui-tooltip-content").html( content );
|
||||||
|
tooltip.position( $.extend({
|
||||||
of: target
|
of: target
|
||||||
}, this.options.position ) ).hide();
|
}, this.options.position ) ).hide();
|
||||||
|
|
||||||
this.tooltip.attr("aria-hidden", "false");
|
|
||||||
target.attr("aria-describedby", this.tooltip.attr("id"));
|
|
||||||
|
|
||||||
this.tooltip.stop(false, true).fadeIn();
|
tooltip.fadeIn();
|
||||||
|
|
||||||
this._trigger( "open", event );
|
this._trigger( "open", event );
|
||||||
|
|
||||||
|
this._bind( target, {
|
||||||
|
mouseleave: "close",
|
||||||
|
blur: "close"
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
close: function( event ) {
|
close: function( event ) {
|
||||||
if (!this.current)
|
var target = $( event && event.currentTarget || this.element );
|
||||||
return;
|
target.attr( "title", target.data( "tooltip-title" ) );
|
||||||
|
|
||||||
var current = this.current;
|
|
||||||
this.current = null;
|
|
||||||
current.attr("title", this.currentTitle);
|
|
||||||
|
|
||||||
if ( this.options.disabled )
|
if ( this.options.disabled )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
current.removeAttr("aria-describedby");
|
var tooltip = this._find( target );
|
||||||
this.tooltip.attr("aria-hidden", "true");
|
target.removeAttr( "aria-describedby" );
|
||||||
|
|
||||||
this.tooltip.stop(false, true).fadeOut();
|
tooltip.fadeOut( function() {
|
||||||
|
$( this ).remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
target.unbind( "mouseleave.tooltip blur.tooltip" );
|
||||||
|
|
||||||
this._trigger( "close", event );
|
this._trigger( "close", event );
|
||||||
|
},
|
||||||
|
|
||||||
|
_tooltip: function() {
|
||||||
|
var tooltip = $( "<div></div>" )
|
||||||
|
.attr( "id", "ui-tooltip-" + increments++ )
|
||||||
|
.attr( "role", "tooltip" )
|
||||||
|
.addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content" );
|
||||||
|
if (this.options.tooltipClass) {
|
||||||
|
tooltip.addClass(this.options.tooltipClass);
|
||||||
|
}
|
||||||
|
$( "<div></div>" )
|
||||||
|
.addClass( "ui-tooltip-content" )
|
||||||
|
.appendTo( tooltip );
|
||||||
|
tooltip.appendTo( document.body );
|
||||||
|
return tooltip;
|
||||||
|
},
|
||||||
|
|
||||||
|
_find: function( target ) {
|
||||||
|
var id = target.attr( "aria-describedby" );
|
||||||
|
return id ? $( document.getElementById( id ) ) : $();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user