Reputation: 1286
I have bootstrap tooltips set up on my webpage. When you roll over an image the tooltips show up, inside the tooltips I have a link, when I roll over the actually tooltip to click the link... it fades away.
My question (which I oddly could not seem to find an answer anywhere for) is how can I get tooltips to stay open when I hover over the actually tooltip itself.
I've seen and tried some solutions where you can set a delay, but I'd rather not go in that direction as I didn't like that effect.
Any help would be great, thanks!
Upvotes: 7
Views: 21625
Reputation: 1
This is what worked in my case - slightly modified version of the first answer
var originalLeave = $.fn.tooltip.Constructor.prototype._leave;
$.fn.tooltip.Constructor.prototype._leave = function (event, context) {
if (!event) {
originalLeave.call(this, event, context);
return;
}
var self = this;
var timeoutId;
var container;
if (self._timeout > 0) {
timeoutId = self._timeout;
originalLeave.call(this, event, context);
} else {
timeoutId = setTimeout(() => originalLeave.call(self, event), 200);
}
if (event.currentTarget) {
container = $("#" + $(event.currentTarget).attr("aria-describedby"));
container.one("mouseenter", function () {
//We entered the actual popover, so we don"t want to call original leave method anymore
clearTimeout(timeoutId);
//Let"s monitor popover content instead
container.one("mouseleave", function () {
originalLeave.call(self, event, context);
});
});
}
};
Upvotes: 0
Reputation: 1
let tooltipTimer = false;
let isTooltipOpen = false;
let tooltipDelay = 100;
$(document).on('mouseover', '[data-bs-toggle=tooltip]', function(e) {
$('.tooltip').tooltip('hide');
$(e.currentTarget).tooltip({
'trigger': 'manual',
'html': true
}).tooltip('show');
});
$(document).on('mouseleave', '[data-bs-toggle=tooltip]', function(e) {
if (!isTooltipOpen) {
tooltipTimer = setTimeout(function () {
$(e.currentTarget).tooltip('hide');
}, tooltipDelay);
}
});
$(document).on('mouseover', '.tooltip', function() {
clearTooltipTimeout();
isTooltipOpen = true;
});
$(document).on('mouseleave', '.tooltip', function(e) {
tooltipTimer = setTimeout(function () {
$(e.currentTarget).tooltip('hide');
}, tooltipDelay);
isTooltipOpen = false;
});
function clearTooltipTimeout()
{
if (tooltipTimer)
{
window.clearTimeout(tooltipTimer);
tooltipTimer = false;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
</head>
<body>
<a data-bs-toggle="tooltip" title="Tooltip open on hover!">Tooltip</a>
</body>
</html>
Upvotes: 0
Reputation: 270
This worked for me:
$('[data-toggle="tooltip"]').tooltip({
trigger: "manual"
});
$('[data-toggle="tooltip"]').on('mouseleave', function () {
$(this).tooltip('hide');
});
$('[data-toggle="tooltip"]').on('mouseenter', function () {
$(this).tooltip('show');
});
$('[data-toggle="tooltip"]').on('click', function () {
$(this).tooltip('hide');
});
Upvotes: 1
Reputation: 2574
$(document).ready(function(){
$(document).on("mouseover", "#myLink", (event) => {
$(event.target).tooltip(
{
trigger: 'manual',
delay: { "hide": 500 }
}).tooltip("show");
});
var isOver = false;
$(document).on("mouseleave", "#myLink", (event) => {
setTimeout(function () { }, 1000);
if (!isOver)
setTimeout(function () { $('#myLink').tooltip('hide'); }, 500);
});
$(document).on("mouseover", ".tooltip", (event) => {
isOver = true;
});
$(document).on("mouseleave", ".tooltip", (event) => {
setTimeout(function () { $('#myLink').tooltip('hide'); }, 500);
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
</head>
<body>
<a href="#" id="myLink" data-toggle="tooltip" title="Stay over me!">Hover over me</a>
</body>
</html>
Upvotes: 1
Reputation: 21
Thу way i did
$(document).ready(function () {
$('[data-toggle="tooltip"]').tooltip({
trigger: "manual"
});
$('body').on('mouseleave', '.tooltip', function () {
$('[data-toggle="tooltip"]').tooltip('hide');
});
$('[data-toggle="tooltip"] > i').on('mouseenter', function () {
$('[data-toggle="tooltip"]').tooltip('show');
});
$('[data-toggle="tooltip"]').on('click', function () {
$(this).tooltip('show');
}); });
Upvotes: 2
Reputation: 21
I did it this way.
I'm triggering the tooltip on a link - so the a would have to be replaced to the relevant element:
Initialize the tooltip:
$(document).ready(function() {
$('a').tooltip();
})
Keep Tooltip open on mouseover + add a helper class on first mouseover (the tooltip alway triggered two mouseover events in my case - so I had to be sure only to add .active in the first go)
$(document).on('mouseover','.tooltip', function() {
var tooltipTrigger = $('a[aria-describedby="' + $(this).attr('id') + '"');
if(! $(tooltipTrigger).hasClass('active')) {
$(tooltipTrigger).tooltip('show').addClass('active');
}
});
Hide the corresponding tooltip when mouseout happens... this uses tooltip-inner to trigger, because the little arrow of the tooltip, which still belongs to .tooltip, can lead to a case, where you might go out of the tooltip with the cursor, but not far enough, and then the tooltips remains open...
$(document).on('mouseout','.tooltip-inner', function() {
$('a.active').tooltip('hide').removeClass('active');
});
Upvotes: 2
Reputation: 101
var originalLeave = $.fn.tooltip.Constructor.prototype.leave;
$.fn.tooltip.Constructor.prototype.leave = function(obj){
var self = obj instanceof this.constructor ?
obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
var container, timeout;
originalLeave.call(this, obj);
if(obj.currentTarget) {
container = $(obj.currentTarget).siblings('.tooltip')
timeout = self.timeout;
container.one('mouseenter', function(){
//We entered the actual popover – call off the dogs
clearTimeout(timeout);
//Let's monitor popover content instead
container.one('mouseleave', function(){
$.fn.tooltip.Constructor.prototype.leave.call(self, self);
});
})
}
};
$('body').tooltip({ selector: '[data-toggle]', trigger: 'click hover', placement: 'bottom auto', delay: {show: 50, hide: 400}});
Upvotes: 10