I have a code that is intended to make a navbar disappear when the mouse is still, and when the mouse moves, it is supposed to fade in. The code works, except that when the mouse is still, the navbar will fade out, but then will fade in a couple seconds later, and continue fading out and in at regular intervals. The website with the problem is here.
My code is below
$("#header").hide();
$("html").mousemove(function( event ) {
$("#header").fadeIn(1500);
myStopFunction();
myFunction();
});
function myFunction() {
myVar = setTimeout(function(){
$("#header").fadeOut(1500);
}, 2000);
}
function myStopFunction() {
if(typeof myVar != 'undefined'){
clearTimeout(myVar);
}
}
Try this (pattern)
$(function () {
var _toggle = function () {
$(document).one("mousemove.t", function (e) {
e.target = $("#header");
$(e.target).toggle(1500).delay(2000).toggle(1500, function () {
_toggle()
})
})
};
$.when(_toggle())
})
jsfiddle http://jsfiddle.net/guest271314/8VeDN/
Related
There is simple code
window.onload = function () {
window.addEventListener('scroll', function () {
alert('asd');
});
};
when you refresh scrolled page, in firefox - you wont see alert, but in chrome SOMETIMES, it fires alert, sometimes its not. Same page, same scroll, just multiple refreshes.
Question is how to avoid triggering scroll event on load in chrome after refresh?
Problem is, DOMContentLoaded can solve this, but i have block animation with coordinates on scroll (scroll-then-fixed), and with DOMContentLoaded coordinates are wrong.
p.s. No $##$ jQuery allowed.
p.s.2.
if ('scrollRestoration' in history) {
history.scrollRestoration = 'manual';
}
is not fix, but workaround too.
use this:
var tFn = function (){
alert();
}
document.onreadystatechange = function (){
if ( document.readyState == ("complete") ) {
setTimeout(function(){
window.onscroll = tFn;
},100);
}
}
You could track the initial scroll with a flag and detect whether the page did not actually scroll:
window.onload = function () {
var isFirstTime = true;
window.addEventListener('scroll', function () {
if (isFirstTime) {
isFirstTime = false;
if (window.scrollY === 0) return;
}
alert('asd');
});
};
Try below code
<script>
window.onscroll = function() {
console.log('Scrolling');
};
</script>
I'm using a hover function with a fade in and fade out to show and hide images. The problem is I want each image to finish fading before the other begins to fade in.
This is what I'm trying. The setTimeout function has broke the hover function and all images are displaying when the page loads.
$(document).ready(function() {
var delay = 0;
//Everything below repeats for each image
$("#image_e_natural_minor").hide();
$("#hover_e_natural_minor").hover(
if (delay == 1) {
setTimeout(function() {
function () {
$("#image_e_natural_minor").fadeIn(1000);
}, //mouse over
function () {
$("#image_e_natural_minor").fadeOut(1000);
delay = 0;
} //mouse out
); //hover close
},1000); // delay time
}
else {
$("#hover_e_natural_minor").hover(
function () {
delay = 1;
$("#image_e_natural_minor").fadeIn(1000);
}, //mouse over
function () {
$("#image_e_natural_minor").fadeOut(1000);
delay = 0;
} //mouse out
); //hover close
}
This is what I had before that works but it will display two images at once.
$("#image_e_natural_minor").hide();
$("#hover_e_natural_minor").hover(
function () {
$("#image_e_natural_minor").fadeIn(1000);
}, //mouse over
function () {
$("#image_e_natural_minor").fadeOut(1000);
} //mouse out
); //hover close
$("#image_e_harmonic_minor").hide();
$("#hover_e_harmonic_minor").hover(
function () {
$("#image_e_harmonic_minor").fadeIn(1000);
}, //mouse over
function () {
$("#image_e_harmonic_minor").fadeOut(1000);
} //mouse out
); //hover close
Sorry for the poor syntax. I'm very new to programming.
jQuery functions fadeIn and fadeOut both have a callback param which is triggered when the animation finishes, so you can hook the fadeIn for current image call right when fadeOut finishes.
But: try this on a single image first; once you have it working try to rewrite it in a function you can call on every image. Remember DRY principle: Don't Repeat Yourself.
EDIT:
What I mean is: When hover over image A 'hover detector', the function should first fadeOut the currently visible image B (which you can get using :visible's jQuery selector) and when the fadeOut animation finishes it will call the fadeIn of image A (which you provided throw the callback param):
$("#image_e_natural_minor").hide();
$("#hover_e_natural_minor").hover(
function () {
$(".myImageClass:visible").fadeOut(1000, function(){$("#image_e_natural_minor").fadeIn(1000)});
}, //mouse over
function () {
$("#image_e_natural_minor").fadeOut(1000);
} //mouse out
); //hover close
Again: try this with a single image, and then rewrite it so it looks like:
$("#image_e_natural_minor").hide();
$("#hover_e_natural_minor").hover(
function(){showThis('#image_e_natural_minor')}, //mouse over
function(){hideThis('#image_e_natural_minor')} //mouse out
); //hover close
I think what you need is something like this. (In this example you also need to set the hover images to have class='hoverI'.)
var delayF = false,
mouseOn = null;
function setHandlers() {
$(".hoverI").hover(function() {
mouseOn = $('#' + event.target.id.replace('hover_e', 'image_e'));
if (!delayF) {
mouseOn.fadeIn(1000);
mouseOn = null;
}
}, function() {
var image = $('#' + event.target.id.replace('hover_e', 'image_e'));
if (mouseOn == image) mouseOn = null;
delayF = true;
image.fadeOut(1000, function() {
delayF = false;
if (mouseOn) {
mouseOn.fadeIn(1000);
mouseOn = null;
}
});
});
}
$("#image_e_natural_minor").hide();
$("#image_e_harmonic_minor").hide();
setHandlers();
HTML Code:
<div id="slick-slidetoggle">wxyz</div>
<div id="slickbox" >abcd</div>
JavaScript:
var hoverVariable=false;
var hoverVariable2=false;
$('#slickbox').hide();
$('#slick-slidetoggle').mouseover(function() {
hoverVariable2=true;
$('#slickbox').slideToggle(600);
return false;
})
$('#slick-slidetoggle').mouseleave(function() {
hoverVariable2=false;
setTimeout(function (){
if(!hoverVariable && !hoverVariable2){
$('#slickbox').slideToggle(600);
return false;}
}, 1000);
})
$('#slickbox').mouseleave(function() {
hoverVariable=false;
setTimeout(function (){
if(!hoverVariable && !hoverVariable2){
$('#slickbox').slideToggle(600);
return false;}
return false;
}, 1000);
})
$('#slickbox').mouseover(function() {
hoverVariable2=false;
hoverVariable=true;
})
CSS Code:
#slickbox {
background: black;
width:100px;
height: 135px;
display: none;
cursor:pointer;
color:white;
}
#slick-slidetoggle{
background: yellow;
width:100px;
height: 135px;
cursor:pointer;
color:black;
}
Now the desired behaviour is that when mouse is slide over yellow div("wxyz") black div("abcd") should slide down and if mouse is moved out of yellow without moving on to black div, the black div should hide after two seconds.
This is happening. If mouse is moved over black div immediately after moving out of yellow div the black div should not hide as long as the mouse is on the black div. This is also happening.
Next steps are bit difficult to explain but I'll try, when mouse is moved over yellow div and black div comes out then mouse is moved over black div and within two seconds if it moved out of it(black div) then the whole animation goes haywire. Its behaviour is reversed. But if the mouse is kept on black div for more than two seconds and then it is moved out then the whole script runs fine.
This is the link to explain better. http://jsfiddle.net/HAQyK/381/
Try replacing slideToggle() with the appropriate slideUp() and slideDown() calls. http://jsfiddle.net/tppiotrowski/HAQyK/386/
var hoverVariable = false;
var hoverVariable2 = false;
$('#slickbox').hide();
$('#slick-slidetoggle').mouseover(function() {
hoverVariable2 = true;
$('#slickbox').slideDown(600);
return false;
})
$('#slick-slidetoggle').mouseleave(function() {
hoverVariable2 = false;
setTimeout(function() {
if (!hoverVariable && !hoverVariable2) {
$('#slickbox').slideUp(600);
return false;
}
}, 1000);
})
$('#slickbox').mouseleave(function() {
hoverVariable = false;
setTimeout(function() {
if (!hoverVariable && !hoverVariable2) {
$('#slickbox').slideUp(600);
return false;
}
return false;
}, 1000);
})
$('#slickbox').mouseover(function() {
hoverVariable2 = false;
hoverVariable = true;
})
I re-coded a solution. Checkout the fiddle here
var hideB;
var $black = $('#slickbox');
var $yellow = $('#slick-slidetoggle');
function showBlack() {
if( hideB ) window.clearTimeout( hideB );
$black.stop( true, true );
$black.slideDown(600);
}
function hideBlack() {
hideB = setTimeout( function( ) {
$black.stop( true, true );
$black.slideUp( 600 ); }
, 1000 );
}
$black.hide();
$yellow.mouseenter(function() {
showBlack();
})
$yellow.mouseleave(function() {
hideBlack();
});
$black.mouseleave( function( ) {
hideBlack();
});
$black.mouseenter( function( ) {
showBlack();
});
Your problem seems to be that the slideToggle in firing twice in quick succession because of your duplicate timeout functions. The cleanest way to deal with timeouts or intervals is to store them in a variable to give you the control of removing them when not needed:
// Defined in global scope
var timer;
$('#slick-slidetoggle').mouseleave(function() {
hoverVariable2=false;
// Timer set as function
timer = setTimeout(function (){
if(!hoverVariable && !hoverVariable2){
$('#slickbox').slideToggle(600);
// Timer no longer need and so cleared
clearTimeout(timer);
return false;}
}, 1000);
});
EDIT: Neglected to add the slideUp/slideDown instead of Toggle as per the correct answer above. See the updated jsFiddle which is now correct: http://jsfiddle.net/HAQyK/390/
Another way you could approach your script is to use jQuerys delay funciton and the stop(); method for animation. Wrap the divs in a container and you've got a much simpler block of code:
$('#slick-container').mouseenter(function() {
$('#slickbox').stop().slideDown(600);
}).mouseleave(function(){
$('#slickbox').stop().delay(1000).slideUp(600);
});
Check it out here: http://jsfiddle.net/HAQyK/387/
There are three images that I have made a tooltip for each.
I wanted to show tooltips within timed intervals say for 2 seconds first tooltip shows and for the second interval the 2nd tooltips fades in and so on.
for example it can be done with this function
function cycle(id) {
var nextId = (id == "block1") ? "block2": "block1";
$("#" + id)
.delay(shortIntervalTime)
.fadeIn(500)
.delay(longIntervalTime)
.fadeOut(500, function() {cycle(nextId)});
}
now what i want is to stop the cycle function when moseover action occurs on each of the images and show the corresponding tooltip. And again when the mouse went away again the cycle function fires.
If I understand everthing correctly, than try this code. Tt stops the proccess if you hover the image and continues if you leave the image. The stop() function will work on custom functions if you implement them like the fadeOut(), slideIn(), ... functions of jquery.
$('#' + id)
.fadeIn(500, function () {
var img = $(this).find('img'),
self = $(this),
fadeOut = true;
img.hover(function () {
fadeOut = false;
},
function () {
window.setTimeout(function () {
self.fadeOut(500);
}, 2000);
}
);
window.setTimeout(function () {
if (fadeOut === false) {
return;
}
self.fadeOut(500);
}, 2000);
});
Can anybody help me on this one...I have a button which when is hovered, triggers an action. But I'd like it to repeat it for as long as the button is hovered.
I'd appreciate any solution, be it in jquery or pure javascript - here is how my code looks at this moment (in jquery):
var scrollingposition = 0;
$('#button').hover(function(){
++scrollingposition;
$('#object').css("right", scrollingposition);
});
Now how can i put this into some kind of while loop, so that #object is moving px by px for as #button is hovered, not just when the mouse enters it?
OK... another stab at the answer:
$('myselector').each(function () {
var hovered = false;
var loop = window.setInterval(function () {
if (hovered) {
// ...
}
}, 250);
$(this).hover(
function () {
hovered = true;
},
function () {
hovered = false;
}
);
});
The 250 means the task repeats every quarter of a second. You can decrease this number to make it faster or increase it to make it slower.
Nathan's answer is a good start, but you should also use window.clearInterval when the mouse leaves the element (mouseleave event) to cancel the repeated action which was set up using setInterval(), because this way the "loop" is running only when the mouse pointer enters the element (mouseover event).
Here is a sample code:
function doSomethingRepeatedly(){
// do this repeatedly when hovering the element
}
var intervalId;
$(document).ready(function () {
$('#myelement').hover(function () {
var intervalDelay = 10;
// call doSomethingRepeatedly() function repeatedly with 10ms delay between the function calls
intervalId = setInterval(doSomethingRepeatedly, intervalDelay);
}, function () {
// cancel calling doSomethingRepeatedly() function repeatedly
clearInterval(intervalId);
});
});
I created a sample code on jsFiddle which demonstrates how to scroll the background-image of an element left-to-right and then backwards on hover with the code shown above:
http://jsfiddle.net/Sk8erPeter/HLT3J/15/
If its an animation you can "stop" an animation half way through. So it looks like you're moving something to the left so you could do:
var maxScroll = 9999;
$('#button').hover(
function(){ $('#object').animate({ "right":maxScroll+"px" }, 10000); },
function(){ $('#object').stop(); } );
var buttonHovered = false;
$('#button').hover(function () {
buttonHovered = true;
while (buttonHovered) {
...
}
},
function () {
buttonHovered = false;
});
If you want to do this for multiple objects, it might be better to make it a bit more object oriented than a global variable though.
Edit:
Think the best way of dealing with multiple objects is to put it in an .each() block:
$('myselector').each(function () {
var hovered = false;
$(this).hover(function () {
hovered = true;
while (hovered) {
...
}
},
function () {
hovered = false;
});
});
Edit2:
Or you could do it by adding a class:
$('selector').hover(function () {
$(this).addClass('hovered');
while ($(this).hasClass('hovered')) {
...
}
}, function () {
$(this).removeClass('hovered');
});
var scrollingposition = 0;
$('#button').hover(function(){
var $this = $(this);
var $obj = $("#object");
while ( $this.is(":hover") ) {
scrollingposition += 1;
$obj.css("right", scrollingposition);
}
});