Set timeout within hover function - javascript

I have content that is dynamically loaded. This content needs to be invoked in the following way due to it's dynamic nature.
This works perfectly if no setTimeout is used. Is there a way of setting a timeout of 0.25 seconds in this instance?
Fiddle https://jsfiddle.net/vuezt9dh/
Works
$(".wrapper").on({
mouseenter: function() {
$(this).find('.show-me').slideDown(150);
},
mouseleave: function() {
$(this).find('.show-me').slideUp(0);
}
}, '.main-page');
Doesn't work
$(".wrapper").on({
mouseenter: function() {
var $this = $(this);
setTimeout(function() {
$this.find('.show-me').slideDown(150);
}, 250);
},
mouseleave: function() {
$(this).find('.show-me').slideUp(0);
}
}, '.main-page');

Your targeting is incorrect, i'm suprised this works at all (didn't in my tests)
Demo https://jsfiddle.net/vuezt9dh/2/
Should be:
$(".main-page").on({
mouseenter: function() {
var $this = $(this);
setTimeout(function() {
$this.find('.show-me').slideDown(150);
}, 550);
},
mouseleave: function() {
$(this).find('.show-me').slideUp(0);
}
}, '.wrapper');
Your wrapper and main-page were the wrong way around.

Related

Mouse leave not firing (nested)

Why is the mouse leave not firing.
$('.tlcr').hide();
$('.tli')
.on({
mouseenter: function() {
$('.tlcr').hide();
const index = $(this).index('.tli');
$('.tlcr').eq(index).show();
},
mouseleave: function() {
$('.tlcr').eq(index)
.on({
mouseenter: function() {
$('.tlcr').eq(index).show();
}, mouseleave: function() {
$('.tlcr').hide();
}
});
$('.tlcr').hide();
}
});
Above code into a fiddle: https://jsfiddle.net/czqab09j/3/
I want to achieve this: https://jsfiddle.net/aLquks1c/1/
But I would like to achieve it with the code from the first fiddle. But I am doing something wrong.
I got it working and here is the updated code:
$('.tli')
.on({
mouseenter: function() {
$('.tlcr').hide();
const index = $(this).index('.tli');
$('.tlcr').eq(index).show();
},
mouseleave: function() {
$('.tlcr').eq(index)
.on({
mouseenter: function() {
$('.tlcr').eq(index).show();
}
});
}
});
$('.tlcr')
.on({
mouseleave: function() {
$('.tlcr').hide();
}
});
I basically removed the nested mouse leave function and made it standalone.
See here the result in a fiddle: https://jsfiddle.net/czqab09j/4/

JQuery setInterval is not working after multiple hover sequence

I'm trying to emulate the footer of a powerpoint presentation. So this is the code
$(function() {
$('.presentation').on({
mouseleave: function() {
setInterval(function () {
if(!$("input").is(":focus") && !$(".presentation:hover").length > 0 && !$('.bp-controls').hasClass('show')){
$('.bp-controls').fadeOut();
$('.bp-controls').removeClass('show');
}
}, 4000);
},
mouseenter: function() {
$('.bp-controls').fadeTo(500, 1, function() {
// Animation complete.
$('.bp-controls').addClass('show');
});
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="presentation">
<img src="Main.png" width="50%">
<div class="bp-controls"><input type="number" pattern="[0-9]*"></div>
</div>
I don't understand why setInterval works the first and maybe the second time when the document is ready but then it doesn't work anymore.
You are adding multiple intervals. You need to clear then when you leave. Should be a timeout also, I doubt you want to keep firing it.
$('.presentation').on({
mouseleave: function() {
this.timer = setTimeout(function () {}, 4000);
},
mouseenter: function() {
if (this.timer) window.clearTimeout(this.timer)
}
});

JQuery .slideUp() after time OR mouseleave

I got an element that is slided down by JQuery using .slideDown() method
$('#dropdown_shopping_cart').slideDown(800);
Now i want it to slide up after 6 seconds, but only if there is no hover on the element, if there is an hover, it should not .slideUp().
So far i worked with a timeout that added display:none to the element while i was giving the element´s hover display:block!important; in CSS so it would not get display: none until the hover is over.
JS
setTimeout(function () {
$('#dropdown_shopping_cart').css('display', 'none');
}, 6000);
_______________________________________________________
CSS
#dropdown_shopping_cart:hover {
display: block!important;
}
Now i want to add the .slideUp() to this.
Check this:
var myVar;
myVar = setTimeout(function() {
$('#dropdown_shopping_cart').slideUp(800)
}, 6000);
$("#dropdown_shopping_cart").hover(
function() {
clearTimeout(myVar);
},
function() {
myVar = setTimeout(function() {
$('#dropdown_shopping_cart').slideUp(800)
}, 6000);
}
);
By default shopping cart will slideUp() after 6 seconds, if mouse hover action occured, setTimeOut will be cleared, after mouse leave the shopping cart, setTimeOut will setted automatically
You can clear the timeout on mouseenter and reset it on mouseleave like this:
var hide_div_to;
function hideDiv(){
hide_div_to = setTimeout(function () {
$('#dropdown_shopping_cart').slideUp(800);
}, 6000);
}
$('#dropdown_shopping_cart').slideDown(800,hideDiv());
$('#dropdown_shopping_cart').mouseenter(function(){
clearTimeout(hide_div_to);
});
$('#dropdown_shopping_cart').mouseleave(function(){
hideDiv();
});
Here is a working JSFiddle
UPDATE
If you don't wan't to wait the timeout again when you leave, after the timeout is reached, you can do this:
$('#dropdown_shopping_cart').slideDown(800);
setTimeout(function () {
if(!$('#dropdown_shopping_cart').is(':hover')){
$('#dropdown_shopping_cart').slideUp(800);
}
else{
$('#dropdown_shopping_cart').mouseleave(function(){
$('#dropdown_shopping_cart').slideUp(800);
});
}
}, 3000);
And here is a JSFiddle and here is another one that shows how this can be triggered multiple times.
Id suggest you work with mouseover and a class:
$('#dropdown_shopping_cart').hover(function(){
if(!$('#dropdown_shopping_cart').hasClass('active'))
{
$(this).addClass('active');
}
else
{
$(this).removeClass('active');
}
},
function() {
var myVar = setTimeout(function() {
if(!$('#dropdown_shopping_cart').hasClass('active'))
{
$('#dropdown_shopping_cart').slideUp()
}
}, 6000);
})
And than in your setTimeout Function you add:
demo: http://jsfiddle.net/yo5gnvy3/7/
$('#dropdown_shopping_cart').hide().slideDown(800, function () {
var events = $._data($(this)[0], "events") || {};
if (events.mouseover === undefined) {
$(this).delay(1000).slideUp()
}
});

Trigger function only if mouseenter event lasted 1 second

I need to show a tooltip when a user hovers over a specific tag on my page. However, I want to do it only if the tag was hovered for at least a second. I tried the code below, but - obviously - setTimeout() will trigger after a second every time, even if the cursor is "long gone".
Is there an easy way in jQuery to achieve this? Not really interested in any plugin-solution.
Fiddle
HTML
<div class="tag-tooltip" id="tooltip-1">Followers: 34</div>
<div class="tag js-tag" data-id="1">Star Wars (hover over me!)</div>
jQuery
$(document).on('mouseenter', '.js-tag', function() {
var $this = $(this);
setTimeout(function() {
$('#tooltip-' + $this.data('id')).show();
}, 2000);
});
$(document).on('mouseleave', '.js-tag', function() {
$('#tooltip-' + $this.data('id')).hide();
});
UPDATE ON SOLUTION
Many good suggestions below, many ways to achieve same thing. I find clearTimeout() solution the cleanest, though. Thanks to everyone who contributed:)
You were almost there, here you go:
http://jsfiddle.net/j21wjtwh/4/
var hoverTimer;
$(document).on('mouseenter', '.js-tag', function() {
var $this = $(this);
hoverTimer = setTimeout(function() {
$('#tooltip-' + $this.data('id')).show();
}, 1000);
});
$(document).on('mouseleave', '.js-tag', function() {
clearTimeout(hoverTimer);
$('#tooltip-' + $(this).data('id')).hide();
});
Use a flag. Set it to false on mouseleave. In mouseenter check if variable is set.
var show = false; // Define var
// ^^^^^^^^^^^^^
$(document).on('mouseenter', '.js-tag', function () {
show = true; // Set to `true`
var $this = $(this);
setTimeout(function () {
if (show) { // Check if true
$('#tooltip-' + $this.data('id')).show();
}
}, 1000);
});
$(document).on('mouseleave', '.js-tag', function () {
$('#tooltip-' + $(this).data('id')).hide();
show = false; // Unset
});
Demo: http://jsfiddle.net/tusharj/j21wjtwh/2/
Here is a Fiddle
Here is a Code
$(document).on('mouseenter', '.js-tag', function() {
var $this = $(this);
setTimeout(function() {
if($('.js-tag').is(":hover"))
{
$('#tooltip-' + $this.data('id')).show();
}
}, 1000);
});
$(document).on('mouseleave', '.js-tag', function() {
$('#tooltip-' + $(this).data('id')).hide();
});
But there is one small bug here, try to hover/unhover fast, and you will see it
EDIT
As for me THIS answer much better. It doesn't contains my bug
Just keep track of whether or not you are currently hovering with a variable.
Set the hovering variable to true on mouse enter, and false on mouseleave.
Then in your setTimeout event, check if you are currently hovering.
Updated Fiddle
var hovering = false;
$('.js-tag').mouseenter(function () {
var $this = $(this);
hovering = true;
setTimeout(function () {
if (hovering) {
$('#tooltip-' + $this.data('id')).show();
}
}, 1000);
});
$('.js-tag').mouseleave(function () {
hovering = false;
$('#tooltip-' + $(this).data('id')).hide();
});
You can store timer handle in variable and clear it using clearTimeout on mouseleave.
Here is jsfiddle for it.
http://jsfiddle.net/Lz9snp9t/3/
Try this:
$('.js-tag').on('mouseover', function() {
var $this = $(this);
if(!$this.data('timeout')) {
$this.data('timeout', setTimeout(function() {
$('#tooltip-' + $this.data('id')).show();
}, 2000);
}
});
$('.js-tag').on('mouseout', function() {
var $this = $(this);
if($this.data('timeout')) {
clearTimeout($this.data('timeout'));
}
$('#tooltip-' + $this.data('id')).hide();
});

Hover from one object to another without the second DOM object disappearing right away

Target: Object user will hover over to bring up secondary DOM
Tooltip: Fixed DOM object positioned about 10-15px below target
I have made a jquery "tooltip" plugin. This plugin allows users to hover over a DOM object, and will show the "tooltip". I want users to be able to move their mouse from the target to the tooltip without it disappearing the second their mouse leaves the target.
I have tried this:
var hoverTimeout;
data.target.hover(function(){
$this.tooltip('show');
}, function(){
hoverTimeout = setTimeout(function(){
$this.tooltip('hide');
console.log('hey');
}, 1000);
});
data.tooltip.hover(function(){
data.tooltip('show');
clearTimeout(hoverTimeout);
}, function(){
data.tooltip('hide');
});
However, this seems to stop the Tooltip from hiding. The reason I'd like to do this, is so forms can be used, text can be copied, etc., in the tooltip.
I'm hoping something like a setTimeout and clearTimeout will work as I don't want to use hoverintent plugin.
Thank you so much in advance!
You should use the timer both ways:
var hoverTimeout;
data.target.hover(function()
{
hoverTimeout && clearTimeout(hoverTimeout);
$(this).tooltip('show');
},
function()
{
var $this = $(this);
hoverTimeout = setTimeout(function(){
$this.tooltip('hide');
}, 1000);
});
data.tooltip.hover(function()
{
hoverTimeout && clearTimeout(hoverTimeout);
},
function()
{
var $this = $(this);
hoverTimeout = setTimeout(function(){
$this.tooltip('hide');
}, 1000);
});
You should probably combine the two, since you're anyhow doing the exact same thing on both of them:
var hoverTimeout;
data.target.add( data.tooltip ).hover(function()
{
hoverTimeout && clearTimeout(hoverTimeout);
$(this).tooltip('show');
},
function()
{
var $this = $(this);
hoverTimeout = setTimeout(function(){
$this.tooltip('hide');
}, 1000);
});
var hoverTimeout;
data.target.hover(function()
{
$this.tooltip('show');
clearTimeout(hoverTimeout);
}, function()
{
hoverTimeout = setTimeout(function(){
$this.tooltip('hide');
}, settings.delay);
});
data.tooltip.hover(function()
{
clearTimeout(hoverTimeout);
}, function()
{
hoverTimeout = setTimeout(function(){
$this.tooltip('hide');
}, settings.delay);
});

Categories