I'm showing a jQuery UI Tooltip right in the middle of my element, when hovering. But the tooltip itself disappears when hovering over it. (propagation
problem)
Element:
With tooltip:
So, when I then hover the tooltip itself, it disappears, due to a propagation problem, I suppose.
HTML:
<div class="bar-wrapper">
<label class="bar-lbl active one" title="2013"><span>2013</span></label>
<div class="bar" data-percent="90"></div>
<div class="bar-rest-overlay" data-percent="10"></div>
</div>
<div class="bar-wrapper">
<label class="bar-lbl active one" title="2014"><span>2014</span></label>
<div class="bar" data-percent="80"></div>
<div class="bar-rest-overlay" data-percent="20"></div>
</div>
Current code:
$('.bar-lbl').tooltip(
{
tooltipClass: 'bar-tooltip',
position:
{
my: 'center',
at: 'center'
}
});
Partial fix (but leaves tooltips permanently visible):
$('.bar-lbl').on('mouseleave',
function(e)
{
e.stopImmediatePropagation();
}).tooltip(
{
tooltipClass: 'bar-tooltip',
position:
{
my: 'center',
at: 'center'
}
});
Not working:
$('body').on('hover', '.ui-tooltip',
function(e)
{
e.stopImmediatePropagation();
});
UPDATE: Thanks to Trevor, I came to a close-solution. (it still leaves the last hovered tooltip visible when hovering out):
It seems, when hovering out the tooltip itself, it hides. But hovering out of the .bar-lbl
element, the tooltip stays visible, unless I hover another .bar-lbl
element.
The problem is in the on('mouseleave')
event on my .bar-lbl
. I need both lines, but they interfere with each other. (see comments)
$('.bar-lbl').on('mouseenter',
function(e)
{
$('.bar-lbl').not($(this)).tooltip('close'); // Close all other tooltips
}).on('mouseleave',
function(e)
{
e.stopImmediatePropagation(); // keeps tooltip visible when hovering tooltip itself
$('.bar-lbl').tooltip('close'); // I need this, but it breaks the line above, causing the tooltip to flicker
}).tooltip(
{
tooltipClass: 'bar-tooltip',
position:
{
my: 'center',
at: 'center'
}
});
$('body').on('mouseleave', '.ui-tooltip',
function(e)
{
$('.bar-lbl').tooltip('close');
});
Just putting the first part of your code for reference.
$('.bar-lbl').tooltip(
{
tooltipClass: 'bar-tooltip',
position:
{
my: 'center',
at: 'center'
}
});
$('.bar-lbl').on('mouseleave', function(e)
{
e.stopImmediatePropagation();
}).tooltip(
{
tooltipClass: 'bar-tooltip',
position:
{
my: 'center',
at: 'center'
}
});
For the last part, change the not working part to the following which closes the tooltip on mouseleave
.
$('body').on('mouseleave', '.ui-tooltip',
function(e)
{
$('.bar-lbl').tooltip('close');
});
This is how I handled it. You add a marker class .tooltip-anchor
to every element that should have a tooltip. You also add data-tooltip-content
attribute which contains the selector of that anchor's tooltip content. Finally, to opt-in to hover keeping the tooltip open, you add .tooltip-is-hoverable
to the anchor. The code prevents jQuery UI from closing the tooltip and instead manages its own closing timers.
HTML:
<span class="tooltip-anchor tooltip-is-hoverable"
data-tooltip-content="#my-tooltip-content"
>
this has a tooltip <span>(this inner span won't have a second tooltip)</span>
</span>
<div id="my-tooltip-content">
When your tooltips don't vanish:
<a href="https://www.google.com/search?q=be+happy">you might feel</a>.
</div>
JS:
$(() => {
$(".tooltip-anchor").each((index, element) => {
let $anchor = $(element),
contentSelector = $anchor.data("tooltip-content"),
$content = $(contentSelector).detach();
let timeoutId = null;
function cancelClose() {
if (timeoutId) {
clearTimeout(timeoutId);
timeoutId = null;
}
}
function scheduleClose() {
cancelClose();
timeoutId = setTimeout(() => {
$anchor.tooltip("close");
timeoutId = null;
}, 250)
}
let tooltipOptions = {
content: () => $content,
// Only the tooltip anchor should get a tooltip. If we used "*", every child tag would
// also get a tooltip.
items: ".tooltip-anchor",
position: {
my: "center top+10",
at: "center bottom",
collision: "flipfit",
},
};
if ($anchor.is(".tooltip-is-hoverable")) {
$.extend(tooltipOptions, {
open: (e) => {
let $anchor = $(e.target),
contentSelector = $anchor.data("tooltip-content"),
$content = $(contentSelector),
$tooltip = $content.closest("[role='tooltip'],.ui-tooltip");
$tooltip.on('mouseenter', cancelClose),
$tooltip.on('mouseleave', scheduleClose);
},
tooltipClass: "hoverable-tooltip",
});
// Prevent jquery UI from closing the tooltip of an anchor with a hoverable tooltip.
$anchor.on('mouseleave', (e) => {
// Instead, schedule a close.
scheduleClose();
e.stopImmediatePropagation();
});
}
$anchor.tooltip(tooltipOptions);
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With