$('#test').hover(
function () {
$(this).append('Blah');
}
);
How can I make the jQuery repeatedly append Blah in #test based on how long you are hovering over #test?
For instance, how can I append Blah once every second you are hovering over #test?
You could use setInterval like this :
var myInterval = false;
$('#test').hover(
function(){
$that = $(this);
// need to save $(this) as 'this' will be different within setInterval
myInterval = setInterval(function(){
$that.append('Blah');
}, 100); // repeat every 100 ms
},function() {
clearInterval(myInterval); // clear the interval on hoverOut
}
);
Working example here
(function() {
var intv;
$('#test').hover(
function () {
var $this = $(this);
intv = setInterval(function() {
$this.append('Blah');
}, 1000);
},
function() {
clearInterval(intv);
}
);
}());
I've enclosed all the code inside a anonymous scoped function so to not pollute global scope, and I cached a reference to $(this) to avoid a new evaluation every second, inside the timeout
You can use setInterval to do so:
var appending; //var to store the interval
$('#test').hover(function(){ //on mouseenter
var $this = $(this); //store the context, i.e. the element triggering the hover
appending = setInterval(function(){ //the following function gets executed every second until the interval is cleared
$this.append('<p>Blah</p>'); //append content to context
},1000); //1000 meaning the repetition time in ms
},function(){ //on mouseleave
clearInterval(appending); //clear the interval on mouseleave
});
use setInterval()
$('#test').hover(
function () {
setInterval(function() {
$(this).append('Blah');
},1000)
}
);
Related
What I am trying to do is only run my code when someone has hovered on an element for 1 second.
Here is the code that I am using:
var timer;
$(".homeLinkWrap").mouseenter(function() {
timer = setTimeout(function(){
$(this).find('.homeLinkNfo').removeClass('flipOutY').addClass('flipInY').css({opacity: '1'});
console.log('in');
}, 1000);
}).mouseleave(function() {
$(this).find('.homeLinkNfo').removeClass('flipInY').addClass('flipOutY');
console.log('out');
clearTimeout(timer);
});
The first part (mouseenter) IS NOT functioning and DOESN'T remove the class and then add the new one. The second one (mouseleave) IS functioning properly and DOES remove the class and add the new one.
I am guessing it is because I am targeting $(this) which is the current element being hovered over and since it is in a timer function jQuery doesn't know which element $(this) is referring to.
What can I do to remedy this?
I think it is because you are calling $(this) inside the setTimeout function. You need to do something like this:
$(".homeLinkWrap").mouseenter(function() {
var $self = $(this);
timer = setTimeout(function(){
$self.find('.homeLinkNfo').removeClass('flipOutY').addClass('flipInY').css({opacity: '1'});
console.log('in');
}, 1000);
});
Inside the setTimeout callback, this no longer refers to the jQuery selection. You should either keep a reference to the selection:
$(".homeLinkWrap").mouseenter(function() {
var $this = $(this);
timer = setTimeout(function(){
$this.find('.homeLinkNfo').removeClass('flipOutY').addClass('flipInY').css({opacity: '1'});
console.log('in');
}, 1000);
})
Or use an arrow function (ES2015)
$(".homeLinkWrap").mouseenter(function() {
timer = setTimeout(() => {
$(this).find('.homeLinkNfo').removeClass('flipOutY').addClass('flipInY').css({opacity: '1'});
console.log('in');
}, 1000);
})
The problem here is that the this inside the callback function that you're passing to setTimeout doesn't reference to the same point that the this outside the callback does.
There are some ways of solving your problem, I'll suggest you to use Function.prototype.bind to bind your callback function to the same this you have outside:
var timer;
$(".homeLinkWrap").mouseenter(function() {
timer = setTimeout((function() {
$(this).find('.homeLinkNfo').removeClass('flipOutY').addClass('flipInY').css({ opacity: '1' });
}).bind(this), 1000);
}).mouseleave(function() {
$(this).find('.homeLinkNfo').removeClass('flipInY').addClass('flipOutY');
clearTimeout(timer);
});
This is my current code to run the series of setTimeout functions. How do I stop these when either the mouse moves, or is over a certain element?
$( document ).ready(function() {
clicky()
function clicky() {
setTimeout(function () {jQuery('#1500').trigger('click');}, 3000);
setTimeout(function () {jQuery('#1990').trigger('click');}, 6000);
setTimeout(function () {jQuery('#2010').trigger('click');}, 9000);
setTimeout(function () {jQuery('#battle').trigger('click');}, 12000);
setTimeout(function () {
jQuery('#water').trigger('click');clicky()
}, 15000);
}
});
You essentially need to save a reference to your timeouts so that they can be cleared when you need them to be. In the following example, I just used an object so that you could specify which timeout you wanted to affect, if desired.
Here's a working fiddle that will clear the timeouts on hover, then reset them when the mouse leaves: http://jsfiddle.net/6tQ4M/2/
And the code:
$(function(){
var timeouts = {};
function setTimeouts () {
timeouts['#1500'] = specifyTimeout('#1500', 3000);
timeouts['#1990'] = specifyTimeout('#1990', 6000);
timeouts['#2010'] = specifyTimeout('#2010', 9000);
timeouts['#battle'] = specifyTimeout('#battle', 12000);
timeouts['#water'] = specifyTimeout('#water', 15000, function(){
console.log('reset the timeouts');
clearTimeouts();
setTimeouts();
});
}
function clearTimeouts () {
for(var key in timeouts){
if(timeouts.hasOwnProperty(key)){
clearTimeout(timeouts[key]);
delete timeouts[key];
}
}
}
function specifyTimeout (id, time, callback) {
return setTimeout(function(){
$(id).trigger('click');
if(callback){
callback();
}
}, time);
}
$('a').on('click', function(){
$('#projects').append('clicky clicky!');
});
$('#map').on('mouseover', clearTimeouts);
$('#map').on('mouseleave', setTimeouts);
setTimeouts();
});
Let me know if you have any questions about the code at all!
Your setTimeout needs to be defined to a variable, so that it can be cleared by passing to clearTimeout(). Something like:
var interval = setTimeout(function() {
//msc
}, 8000);
window.clearTimeout(interval);
Well, according to what you ordered, when you hover an area, the setTimeOut should be fired, and when you are out of this region, the setTimeOut should be reset.
This is the code:
HTML
<div id="map"></div>
CSS
#map{
width:100px;
height:100px;
background-color: black;
}
Javascript
var timeoutHandle;
$('#map').mouseover(function(event){
window.clearTimeout(timeoutHandle);
});
$('#map').mouseout(function(event){
timeoutHandle = window.setTimeout(function(){ alert("Hello alert!"); }, 2000);
});
Basically you should keep a reference to the setTimeOut, in this case the variable is timeoutHandle, call clearTimeOut on mouse over and call setTimeOut again to reset the timer.
Here is the jsFiddle:
http://jsfiddle.net/bernardo_pacheco/RBnpp/4/
The same principle can be used for more than one setTimeOut timer.
You can see more technical details here:
Resetting a setTimeout
Hope it helps.
I'm very new to JavaScript and jQuery and I'm having trouble with a bit of code.
HTML:
<div class="toggle" style="display: block; width: 200px; height: 200px; background-color: red;">test</div>
JavaScript:
jQuery(document).ready(
function()
{
jQuery(".toggle").on("click", function() {
console.log("let the toggling begin!");
jQuery(this).slideToggle(600, function(){ // slide up
setTimeout(function(){ // wait 4 sec, then slide back down
jQuery(this).slideToggle(600)
}, 4000);
});
});
}
);
So the idea is that you click on the div, it slides up, then 4 seconds later slides back down. It doesn't work.
JSFIDDLE: http://jsfiddle.net/zEqN9/2/
However, if I change the this inside each of the closures to ".toggle", then it does work.
JSFIDDLE: http://jsfiddle.net/YZxMb/
So clearly the issue is my use of this.
I tried passing this as a parameter into each of the two closure functions, but that gave the error Unexpected token this.
How can I access the this variable from the inner functions?
Create a reference to this in slideToggle function.
jQuery(document).ready(
function()
{
jQuery(".toggle").on("click", function() {
console.log("let the toggling begin!");
jQuery(this).slideToggle(600, function(){ // slide up
var self = this; // <-- notice this
setTimeout(function(){ // wait 4 sec, then slide back down
jQuery(self).slideToggle(600)
}, 4000);
});
});
}
);
Use bind to specify a this for a function you expect to call out of context.
var foo = {
bar: function () {
setTimeout(function () { // though in a setTimeout
console.log(this);
}.bind(this), 0); // binding to `this` here means
}
};
foo.bar(); // invoking it still has `this` of `foo`
var yourThing = jQuery(this);
yourThing.slideToggle(600, function(){ // slide up
setTimeout(function(){ // wait 4 sec, then slide back down
yourThing.slideToggle(600)
}, 4000);
});
Just add this line in your code to understand why:
setTimeout(function(){ // wait 4 sec, then slide back down
console.log(jQuery(this)); //this one
jQuery(this).slideToggle(600)
}, 4000);
Open your console. You will see that, in the setTimeout function, $(this) refers to the window object.
You need a create a referente to this,so when runs the function associate to setTimeout you can pass this reference.
jQuery(document).ready(
function()
{
jQuery(".toggle").on("click", function() {
console.log("let the toggling begin!");
var that = this; // <--- reference to this
jQuery(this).slideToggle(600, function(){ // slide up
setTimeout(function(){ // wait 4 sec, then slide back down
jQuery(that).slideToggle(600)
}, 4000);
});
});
}
);
The reason is that for a jQuery event, the context of the function is explicitly set so that this refers to the target element - this is done for you by jQuery. However, the anonymous function for setTimeout doesn't have that context set for you - it gets the default global context, so this refers to the window.
What you need to do is grab a reference to the click event's context, and then use the reference in the timeout:
jQuery(function () {
jQuery(".toggle").on("click", function () {
var $this = $(this);
$this.slideToggle(600, function () { // slide up
setTimeout(function () { // wait 4 sec, then slide back down
$this.slideToggle(600);
}, 4000);
});
});
});
However, as pointed out in a comment, this could be written as:
jQuery(function () {
jQuery(".toggle").click(function () {
jQuery(this).slideToggle(600).delay(4000).slideToggle(600);
});
});
I have a fancybox for displaying photos and descriptions of them.
Now it opens fancybox on mouseenter event. It works perfectly with this code:
$('.fancy_link').live('mouseenter', mouseEnter);
function mouseEnter()
{
jQuery(this).fancybox().trigger('click');
return false;
}
But i need to set delay for opening fancybox. How it should work: User moves cursor over a link, after 1 second fancybox should open and display content. If user moves mouse away before waiting 1 second, fancybox should not open.
I have tried JQuery delay() and setTimeout() but both of them are not working properly.
One sec. delay just ignored by both methods.
use setTimeout/clearTimeout...
//binding code...
$('.fancy_link').on('mouseenter',mouseEnter);
$('.fancy_link').on('mouseleave', mouseLeave);
//run when the mouse hovers over the item
function mouseEnter() {
//clear any previous timer
clearTimeout($(this).data('h_hover'));
//get a reference to the current item, for the setTimeout callback
var that = this;
//set a timer, and save the reference to g_hover
var h_hover = setTimeout(function(){
//timer timed out - click the item being hovered
$(that).click();
}, 1000);
//save the reference - attached to the item - for clearing
// data is a generic "store", it isn't saved to the tag in the dom.
// note: if you have a data-* attribute it is readable via data()
$(this).data('h_hover',h_hover)
}
//handler for when the mouse leaves the item
function mouseLeave() {
//clear the previously set timeout
clearTimeout($(this).data('h_hover'));
}
this could help you
function openFancybox() {
setTimeout( function() {$('#fancy_link').trigger('click'); },1000);
}
I imagine you will need to use setTimeout and clearTimeout
Something along these lines:
var timer;
$('.fancy_link').mouseenter(function(){
var $this = $(this);
timer = setTimeout(function(){
$this.fancybox().trigger('click');
}, 1000);
}).mouseleave(function(){
clearTimeout(timer);
});
Try this solution:
var timer = null;
$('.fancy_link').on('mouseenter', function() {
timer = setTimeout(mouseEnter, 1000);
});
// clear timer when mouse leaves
$('.fancy_link').on('mouseleave', function() {
clearTimeout(timer);
});
I am working on a nested menu, and when my mouse move over a option, a sublist will show up.
Here is my hover function:
$( ".sublist" ).parent().hover( function () {
$(this).toggleClass("li_hover",300); //use to change the background color
$(this).find(".sublist").toggle("slide", {}, 500); //sub list show / hide
});
Now, I want add a short period before the sublist shows up to prevent the crazy mouse moving from user. Does somebody have a good suggestion on this?
Update:
Thanks for you guys, I did a little bit change on my program, recently it looks like this:
function doSomething_hover (ele) {
ele.toggleClass("li_hover",300);
ele.find(".sublist").toggle("slide", {}, 500);
}
$(function () {
$( ".sublist" ).parent().hover( function () {
setTimeout(doSomething_hover($(this)), 3000);
});
}):
This is weird that setTimeout will not delay anything. but if I change the function call to doSomething_hover (without "()"), the function will delay good. but i can not pass any jquery element to the function, so it still not works, could somebody tell me that how to make doSomething_hover($(this)) work in setTimeout ?
Update 2:
Got the setTimeout work, but it seems not what I want:
What I exactly want is nothing will happen, if the mouse hover on a option less than 0.5sec.
Anyway, here is the code I make setTimeout work:
function doSomething_hover (ele) {
ele.toggleClass("li_hover",300);
ele.find(".sublist").toggle("slide", {}, 500);
}
$(function () {
$( ".sublist" ).parent().hover( function () {
var e = $(this);
setTimeout(function () { doSomething_hover(e); }, 1000);
});
}):
Final Update:
I got this work by using clearTimeout when I move the mouse out.
so the code should be:
$( ".sublist" ).parent().mouseover( function () {
var e = $(this);
this.timer = setTimeout(function () { doSomething_hover(e); }, 500);
});
$( ".sublist" ).parent().mouseout ( function () {
if(this.timer){
clearTimeout(this.timer);
}
if($(this).hasClass("li_hover")){
$(this).toggleClass("li_hover");
}
$(this).find(".sublist").hide("slide", {}, 500);
});
This is the part in the $(document).ready(). Other code will be same as above.
真. Final Update:
So, mouseover and mouseout will lead to a bug sometime, since when I move the mouse to the sublist, the parents' mouseover event will be fire, and hide the sublist.
Problem could be solved by using hover function:
$( ".sublist" ).parent().hover(
function () {
var e = $(this);
this.timer = setTimeout(function () { doSomething_hover(e); }, 500);
},
function () {
if(this.timer){
clearTimeout(this.timer);
}
$(this).find(".sublist").hide("slide", {}, 500);
if($(this).hasClass("li_hover")){
$(this).toggleClass("li_hover",300);
}
}
);
Thanks all
Try this please:
Code
setInterval(doSomthing_hover, 1000);
function doSomthing_hover() {
$(".sublist").parent().hover(function() {
$(this).toggleClass("li_hover", 300); //use to change the background color
$(this).find(".sublist").toggle("slide", {}, 500); //sub list show / hide
});
}
SetTime vs setInterval
At a fundamental level it's important to understand how JavaScript timers work. Often times they behave unintuitively because of the single thread which they are in. Let's start by examining the three functions to which we have access that can construct and manipulate timers.
var id = setTimeout(fn, delay); - Initiates a single timer which will call the specified function after the delay. The function returns a unique ID with which the timer can be canceled at a later time.
var id = setInterval(fn, delay); - Similar to setTimeout but continually calls the function (with a delay every time) until it is canceled.
clearInterval(id);, clearTimeout(id); - Accepts a timer ID (returned by either of the aforementioned functions) and stops the timer callback from occurring.
In order to understand how the timers work internally there's one important concept that needs to be explored: timer delay is not guaranteed. Since all JavaScript in a browser executes on a single thread asynchronous events (such as mouse clicks and timers) are only run when there's been an opening in the execution.
Further read this: http://ejohn.org/blog/how-javascript-timers-work/
timeout = setTimeout('timeout_trigger()', 3000);
clearTimeout(timeout);
jQuery(document).ready(function () {
//hide a div after 3 seconds
setTimeout( "jQuery('#div').hide();",3000 );
});
refer link
function hover () {
$( ".sublist" ).parent().hover( function () {
$(this).toggleClass("li_hover",300); //use to change the background color
$(this).find(".sublist").toggle("slide", {}, 500); //sub list show / hide
});
}
setTimeout( hover,3000 );
....
You could use .setTimeout
$(".sublist").parent().hover(function() {
setTimeout(function() {
$(this).toggleClass("li_hover", 300); //use to change the background color
$(this).find(".sublist").toggle("slide", {}, 500); //sub list show / hide
}, 1000);
});