Reverse jQuery effect after a given time - javascript

one quick question!
I am using the following code which does a "flip" card effect to flip a specific div element, when a certain link is mouse clicked. Is it possible to make the "flip" effect reverse after some time? Exactly as if I was clicking again with the mouse, but timed. I can do it now by cliking, but I would like to time it.
$(document).ready(function () {
$('.flip_card').click(function () {
var x = $(this).attr("id");
var i = x.substring(10);
$('.flip' + i + '').find('.card').toggleClass('flipped');
});
});
I have tried using the jquery functions delay() or settimeout, but I can only achieve that the first "flip" effect is delayed and happens after certain time. That is not what I want...
I hope my question is understanble enough.
Many thanks!

Try this.
$(document).ready(function () {
$('.flip_card').click(function () {
var x = $(this).attr("id");
var i = x.substring(10);
var ele = '.flip' + i + '';
$(ele).find('.card').toggleClass('flipped');
setTimeout(function(){
$(ele).find('.card').toggleClass('flipped');
}, 1000);
});
});

Try utilizing .queue()
$(document).ready(function () {
$(".flip_card").click(function () {
var x = this.id;
var i = x.substring(10);
$(".flip" + i).find(".card").toggleClass("flipped")
.queue("reset", function() {
setTimeout(function() {
$(".flip"+ i + " .card.flipped:eq(-1)").toggleClass("flipped");
// set duration here
}, 3000);
}).dequeue("reset");
});
});

You can use setTimeout(), but you should keep track of the timer ID so you can cancel it if the user clicks again before the timeout has executed. You can use the .data() function to store the timer ID so each card keeps track of its own timer ID.
$(document).ready(function () {
$('.flip_card').click(function () {
var i = $(this).attr('id').substring(10);
var $card = $('.flip' + i).find('.card');
// Clear the timeout if there is one.
var timerId = $card.data('timerId');
if (timerId) {
clearTimeout(timerId);
}
// Flip the card.
if (!$card.hasClass('flipped')) {
$card.addClass('flipped');
// Set the timeout so the card is flipped back after 3 seconds.
$card.data('timerId', setTimeout(function () {
$card.removeClass('flipped');
}, 3000));
} else {
$card.removeClass('flipped');
}
});
});
jsfiddle

How about something this simple. Just chaining should make it.
$(document).ready(function () {
$('.flip_card').bind('click', function() {
var x = $(this).attr("id");
var i = x.substring(10);
var ele = '.flip' + i + '';
$(ele).find('.card').toggleClass('flipped').delay(3000).toggleClass('flipped');
});
});

Related

Stop a jquery loop function on click while adding class

I have a function that continuously loops through a set of divs (see below) with the class active. I'm trying to modify the function so that when you click on the div it stops the loop and adds the class active to that div.
I've looked through countless examples on StackOverflow, but haven't been able to find something that works for my situation.
Function I'm trying to modify:
function doLoop() {
$('.cd-types, .img-frame, .img-content-container').each(function(){
(function($set){
setInterval(function(){
var $cur = $set.find('.active').removeClass('active');
var $next = $cur.next().length ? $cur.next() : $set.children().eq(0);
$next.addClass('active');
},7000);
})($(this));
});
}
Here is the jfiddle with my attempt on modifying the loop. I know its fairly simple and I've spent the last few hours trying to figure it out. Any advice/direction would be greatly appreciated.
Try
function doLoop() {
$('.cd-types, .img-frame, .img-content-container, .list-items').each(function () {
var $set = $(this);
var interval = setInterval(function () {
var $cur = $set.find('.active').removeClass('active');
var $next = $cur.next().length ? $cur.next() : $set.children().eq(0);
$next.addClass('active');
}, 1000);
$set.data('loop', interval);
$set.on('click', '> *', function () {
$(this).addClass('active').siblings('.active').removeClass('active');
clearInterval($set.data('loop'));
$set.removeData('loop')
});
});
}
Demo: Fiddle, Fiddle2
Simplified the loop function a bit to use the "self" variable trick.
timerID was used to track the setInterval() call so that it could be stopped using clearInterval() call when clicked:
$('.list-items').children().first().addClass('active');
var timerID;
$('.list-items').each(function () {
var self = this;
timerID = setInterval(function () {
var $cur = $(self).find('.active').removeClass('active');
var $next = $cur.next().length ? $cur.next() : $(self).children().eq(0);
$next.addClass('active');
}, 1000);
});
$('.list-items').on('click', function(){
clearInterval(timerID);
alert("Stopped");
});
See the working code at:
JSFiddle

Count how many seconds did the user hover an element using jquery or javascript?

just need a little help here. My problem is, how can I count the seconds when i hover a specific element. Like for example when I hover a button, how can i count the seconds did i stayed in that button after I mouseout?
An alternate solution using setInterval. DEMO HERE
var counter = 0;
var myInterval =null;
$(document).ready(function(){
$("div").hover(function(e){
counter = 0;
myInterval = setInterval(function () {
++counter;
}, 1000);
},function(e){
clearInterval(myInterval);
alert(counter);
});
});
A simple example
var timer;
// Bind the mouseover and mouseleave events
$('button').on({
mouseover: function() {
// set the variable to the current time
timer = Date.now();
},
mouseleave: function() {
// get the difference
timer = Date.now() - timer;
console.log( parseFloat(timer/1000) + " seconds");
timer = null;
}
});
Check Fiddle
How about this quick plugin I just knocked out, which will work on multiple elements, and without using any global variables:
(function($) {
$.fn.hoverTimer = function() {
return this.on({
'mouseenter.timer': function(ev) {
$(this).data('enter', ev.timeStamp);
},
'mouseleave.timer': function(ev) {
var enter = $(this).data('enter');
if (enter) {
console.log(this, ev.timeStamp - enter);
}
}
});
};
})(jQuery);
Actually disabling the functionality is left as an exercise for the reader ;-)
Demo at http://jsfiddle.net/alnitak/r9XkX/
IMHO, anything using a timer for this is a poor implementation. It's perfectly trivial to record the time without needing to use an (inaccurate) timer event to "count" seconds. Heck, the event object even has the current time in it, as used above.
This is exam:
var begin = 0;
var end = 0;
$('#btn').hover(function () {
begin = new Date().getTime();
});
$('#btn').leave(function () {
end = new Date().getTime();
sec = (end - begin) / 1000;
alert(sec);
});
One way to go about it would be the event.timeStamp method :
var initial_hover, exit_hover;
$('#ele').hover(
function(event){
initial_hover = event.timeStamp
console.log(initial_hover);
},
function(event){
exit_hover = event.timeStamp
$(this).html(exit_hover - initial_hover);
console.log(exit_hover);
}
);
jsfiddle
You've tagged the question with JQuery, so here's a jQuery solution.
$(element).on('mouseover', function(e){
$(e.target).data('hover-start', new Date().getTime());
});
$(element).on('mouseout', function(e){
// count the difference
var difference = new Date().getTime() - $(e.target).data('hover-start');
// clean up the data
$(e.target).data('hover-start', undefined);
console.log('Mouse was over for', difference/1000, 'seconds');
});
use setInterval and store value in variable. call the function on mouserover.
function mouseover(){
var start = 0;
setInterval(function(){
start++;
var count = start;
}, 1000);
}

animation starts with delay

i have writen script which loads content from external php file. i'm using jquery1-9-1. my script works normal, except that moment when i'm clicking on button second time. there is delay for 0.5s before the animation starts. i think i know what is the problem and where is it. $("#header").animate({marginTop: "10px"... must execute just on the first click. after this clicked once, it must be deactivated. who knows how to solve it? don judge me so harsh and sorry my english
$(document).ready(function () {
var content = $("#content");
$("#main_menu a").click(function () {
var id = this.id;
$("#header").animate({
marginTop: "10px"
}, 500, function () {
$("#content").fadeOut(500, function () {
$("#content").load(id + ".php")
$("#content").fadeIn(500)
})
})
})
})
I have to ask, what is the point of caching content = $("#content") if you then refuse to use it and just call $("#content") repeatedly later?
Anyway, you need a variable to tell if it's the first run or not:
$(function () {
var content = $("#content"), isfirst = true;
$("#main_menu a").click(function () {
var id = this.id,
reveal = function() {
content.fadeOut(500, function () {
content.load(id + ".php")
content.fadeIn(500)
});
};
if( isfirst) $("#header").animate({marginTop: "10px"}, 500, reveal);
else reveal();
isfirst = false;
});
});
You need to track whether or not it has loaded, in that case. A simple variable and some closure should do it:
var isLoaded = false;
$("#main_menu a").click(function () {
var id = this.id;
if (!isLoaded) {
$("#header").animate({
marginTop: "10px"
}, 500);
isLoaded = true;
}
$("#content").fadeOut(500, function () {
$("#content").load(id + ".php")
$("#content").fadeIn(500)
})
});

jquery/javascript set multiple timeouts one after the other via loop to run independently of the other

I am trying to animate a handful of DIV's to scroll upwards but I want one to scroll up after a pause after the other after the other. And the best I can come up with at the moment is
$('.curtain').each(function()
{
var $elem = $(this);
setTimeout(function()
{
$elem.animate({"height":0+'px'}, 2000);
}, 1000);
});
Problem is they still all animate together without pause. How can I go about doing something in this fashion. The divs are dynamically generated and there can be 5 - 20 of them so doing a hardcoded logic is out, any ideas?
function animateIt () {
var elems = $('.curtain').get();
(function next() {
if(elems.length){
var elem = $(elems.shift());
elem.animate({"height":0+'px'}, 2000, next);
}
})();
}
animateIt();
running example
Another way like queue
function animateIt () {
var divs = $('.curtain');
divs.each( function(){
var elem = $(this);
$.queue(divs[0],"fun", function(next) { elem.animate({"height":0+'px'}, 2000, next); });
});
divs.eq(0).dequeue("fun");
}
Looks like a simple recursive function might work for you here -
function doAnimation(elapsed){
var iterations = $('.curtain').length;
var current = elapsed+1;
if (current <= iterations){
setTimeout(function(){
$('.curtain:eq(' + elapsed + ')').animate(...);
doAnimation(current);
},50);
}
}
doAnimation(0);
Here's a simple demo

After setTimeout() check if still mouse out

I have a piece of code that hides an element on mouseout.
The code looks like this:
var myMouseOutFunction = function (event) {
setTimeout(function () {
$(".classToHide").hide();
$(".classToShow").show();
}, 200);
};
This produces a result very close to what I want to do. However, I want to wait the time on the timeout (in this case 200 ms) then check to see if my mouse is still "out" of the element. If it is, I want to do .hide() and .show() on the desired elements.
I want to do this because if a user slightly mouses out then quickly mouses back in, I don't want the elements to flicker (meaning: hide then show real quick) when the user just wants to see the element.
Assign the timeout's return value to a variable, then use clearTimeout in the onmouseover event.
Detailing Kolink answer
DEMO: http://jsfiddle.net/EpMQ2/1/
var timer = null;
element.onmouseout = function () {
timer = setTimeout(function () {
$(".classToHide").hide();
$(".classToShow").show();
}, 200);
}
element.onmouseover = function () {
clearTimeout(timer);
}
You should use mouseenter and mouseleave of jquery. mouseenter and mouseleave will get called only once.and use a flag if to check if mouseenter again called.
var isMouseEnter ;
var mouseLeaveFunction = function (event) {
isMouseEnter = false;
setTimeout(function () {
if(isMouseEnter ){ return;}
$(".classToHide").hide();
$(".classToShow").show();
}, 200);
};
var mouseEnterFunction = function(){
isMouseEnter = true;
}
Use a boolean flag:
var mustWait = true;
var myMouseOutFunction = function (event) {
setTimeout(function () {
if(mustWait){
mustWait = false;
}
else{
$(".classToHide").hide();
$(".classToShow").show();
mustWait = true;
}
}, 200);
};

Categories

Resources