jQuery fade in and fade out loop issue - javascript

I am making a results screen which toggles between showing the user their best time/score and their latest time/score. I found a solution using this site but after leaving the website open for a few hours I saw that the timings had gone out of sync. I know that this is hard to test so I thought I would see if any experts on here could help me to optimize or fix my code.
CODEPEN
JSFIDDLE
JS
$(document).ready(function() {
setInterval( function() { resultsTransition(); }, 4000);
function resultsTransition() {
$('.latest-transition').fadeOut(500).delay(3500).fadeIn(500).delay(3500);
$('.best-transition').fadeIn(500).delay(3500).fadeOut(500).delay(3500);
}
});

I think your design could be improved (and the out-of-sync problem solved) by simply toggling the opacity of the elements in your resultsTransition method instead of starting a new sequence, which could interfere unpredictably with the interval.
Something like:
var latestTransitionElementVisible = true; //the initial state of your elements
setInterval(resultsTransition, 4000); //note you can just pass the function name
function resultsTransition() {
$('.latest-transition').fadeTo(500, latestTransitionElementVisible ? 0 : 1);
$('.best-transition').fadeTo(500, latestTransitionElementVisible ? 1 : 0);
latestTransitionElementVisible = !latestTransitionElementVisible ;
}

I guess whatever problem/issue you are facing is because of varying animation times .Try the following:
$(document).ready(function() {
setTimeout( function() { resultsTransition(); }, 4000);
function resultsTransition() {
if(!$('.latest-transition').is(':animated') && !$('.best-transition').is(':animated'))
{
$('.latest-transition').fadeOut(500).delay(3500).fadeIn(500).delay(3500);
$('.best-transition').fadeIn(500).delay(3500).fadeOut(500).delay(3500);
setTimeout( function() { resultsTransition(); }, 4000);
}
}
});

Related

Adding comma to jQuery animated numbers

I'm using a jQuery script from here.
So far it works great, but the only thing that I'm wondering about is how to go about getting a comma into one of the values.
Since the number animate up when you scroll, it's tricky to get the browser to check what the integer is after the fact. I've read a bunch of posts that will add a comma (in this case I'm trying to get 100,000) but it won't work since the browser can't see that integer initially (starts at 0).
Here's the script that I'm using to invoke the animaition when you scroll down the page:
$(function () {
var fx = function fx() {
$(".stat-number").each(function (i, el) {
var data = parseInt(this.dataset.n, 10);
var props = {
"from": {
"count": 0
},
"to": {
"count": data
}
};
$(props.from).animate(props.to, {
duration: 500 * 1,
step: function (now, fx) {
$(el).text(Math.ceil(now));
},
complete:function() {
if (el.dataset.sym !== undefined) {
el.textContent = el.textContent.concat(el.dataset.sym)
}
}
});
});
};
var reset = function reset() {
console.log($(this).scrollTop())
if ($(this).scrollTop() > 950) {
$(this).off("scroll");
fx()
}
};
$(window).on("scroll", reset);
});
It takes the value from the data attribute data-n in the HTML and then works it's magic from there. If I have 100,000 in the data-n attribute then it cuts it short at 100 when the numbers animate.
So yeah, I'm not sure if I need to amend this script so it can accommodate for the comma in the data attribute or if there is something else I might need to do after the fact?
Ok, so after digging through it a bit more, I was able to come up with a solution.
I found this:
$.fn.digits = function(){
return this.each(function(){
$(this).text( $(this).text().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,") );
})
}
and then added an addtional class in my HTML.
I then hooked into the complete:function and added:
$(".class-i-added").digits();
to the end of the animation.
Overall, that appears to provide the result that I am looking for.
Since I only need to attribute it to one number (so far) it works as it should.

use javascript to make element take turns to appear

So I have two element first and second; I'm trying to let them take turns to appear; I have following code;
setTimeout(setInterval(function(){
$(".first").hide();
$(".second").show();
},20000),10000)
setTimeout(setInterval(function(){
$(".first").show();
$(".second").hide();
},20000),0)
it seems these codes doesn't work, can someone tell me what's wrong?
i found an alternative:
var d=0;
setInterval(function(){
if(d==0){
d=1
$(".first").hide();
$(".second").show();
}else if(d==1){
d=0
$(".first").show();
$(".second").hide();
}
},10000)
Your setTimeout() callbacks need to be actual function references like function() {setInterval(...)}. The way you had it, you were executing the setInterval() immediately and then passing the results to setTimeout() which was doing nothing:
setTimeout(function() {
setInterval(function(){
$(".first").hide();
$(".second").show();
},20000),10000);
But, there is a much better way to implement this with only a single timer:
(function() {
var flag = true;
setInterval(function() {
flag = !flag;
$(".first")[flag ? "hide" : "show"]();
$(".second")[flag ? "show" : "hide"]();
}, 10000);
})();
Or, if you set the hide/show state opposite initially, then you can just use jQuery's .toggle() to reverse the visibility:
$(".first").show();
$(".second").hide();
setInterval(function() {
$(".first").toggle();
$(".second").toggle();
}, 10000);

Timer Reset Function Not Working!

Hello Guys!
I have been trying to create a simple sample code for my newest jQuery Plugin, but it doesn't seems to be working at all! Can anyone tell where I'm going wrong?, or can anyone provide me a new function to do it. So my problem is that when I mouse over an element classed trigger an another element classed eg should fadeIn(); but if the user takes out the mouse before the element classed eg fades in it should not be fading in anymore, but this is not working at all. I don't not what is getting wrong? Please help me out. (Below is my Problem HTML nad Jquery Code!)
HTML CODE
<div class="trigger">MouseOverMe</div>
<div class="eg">See Me!</div>
JQUERY CODE
function timereset(a)
{
var elem = $('.'+a);
if(elem.data('delay')) { clearTimeout(elem.data('delay')); }
}
$(document).ready(function () {
$('div.eg').hide();
$('div.trigger').mouseover(function () {
$('div.eg').delay(1000).fadeIn();
});
$('div.trigger').mouseout(function () {
timereset('eg');
$('div.eg').fadeOut();
});
});
THANKS IN ADVANCE
You don't need that timereset stuff, simply call stop() on the object and the previous effect will stop:
http://api.jquery.com/stop/
Update based on the new comment:
$('div.trigger').mouseout(function () {
$('div.eg').stop().hide();
});
jQuery
$('.trigger').hover(function() {
$('.eg').delay(1000).fadeIn();
}, function() {
$('.eg').stop(true, true).hide();
});
Fiddle: http://jsfiddle.net/UJBjg/1
Another option would be to clear the queued functions like:
$('div.trigger').mouseout(function () {
$('div.eg').queue('fx', []);
$('div.eg').fadeOut();
});
Bear in mind if the fadeOut/In has already started by using stop you could end up with a semi-transparent element.
EDIT
Here's an example: http://jsfiddle.net/Qchqc/
var timer = -1;
$(document).ready(function () {
$('div.eg').hide();
$('div.trigger').mouseover(function () {
timer = window.setTimeout("$('div.eg').fadeIn(function() { timer = -1; });",1000);
});
$('div.trigger').mouseout(function () {
if(timer != -1)
window.clearTimeout(timer);
$('div.eg').fadeOut();
});
});

How to block JQuery actions while a previous action is still taking place

I have a a div in a page that slides up on hover, and then back down on hover out. If you were then to hover in and out on the item, then all the actions will be queued and thus triggered, causing the object to keep sliding up and down even though you are no longer interacting with it.
You can see this in action on the site I am developing here. Simply hover over the large image in the center to see the information div to appear.
Ideally what should happen is that while an animation is taking place no further actions should be queued.
Here is my current code:
$(document).ready(function(){
$(".view-front-page-hero").hover(
function() {
$hero_hover = true;
$('.view-front-page-hero .views-field-title').slideDown('slow', function() {
// Animation complete.
});
},
function() {
$hero_hover = false;
$('.view-front-page-hero .views-field-title').slideUp('slow', function() {
// Animation complete.
});
}
);
});
Create a global variable. When the animation starts. Clear it when it completes. Set a condition to exit the function if this variable is set before calling the animation.
This is probably not the best solution, but if you run stop(true, true) before the animation, it should work.
Live demo: http://jsfiddle.net/TetVm/
$(document).ready(function(){
var continue=true;
$(".view-front-page-hero").hover(
function() {
if(continue){
$('.view-front-page-hero .views-field-title').slideDown('slow', function() {
continue=false;
});
}
},
function() {
if(continue!){
$('.view-front-page-hero .views-field-title').slideUp('slow', function() {
continue=true;
});
}
}
);
});
//this will make your code work correctly...

jQuery - link working *only* after some time

I have a link:
Here's my link
This is not a normal clickable link, it's coded in jQuery like this:
$("#link").hover(function(e) {
e.preventDefault();
$("#tv").stop().animate({marginLeft: "50px"});
$("#tv img)").animate({opacity: 1});
})
So after hovering unclickable link there's change of #tv's margin and opacity.
Is there any way of making this work only after the user hovers the link area with pointer for more than two seconds?
Because now everything happens in real time.
I know there's delay(), but it doesn't work because it just delays the animation and in this case I don't want any action if the pointer is over for less than two seconds.
Possible without a loop?
What you're after is called hoverIntent.
var animateTimeout;
$("#link").hover(function() {
if (animateTimeout != null) {
clearTimeout(animateTimeout);
}
animateTimeout = setTimeout(animate, 2000);
}, function() {
clearTimeout(animateTimeout);
});
function animate() {
//do animation
}
You just need a setTimeout() to delay the code, along with a clearTimeout() to clear it if the user leaves the link within 2 seconds.
Example: http://jsfiddle.net/mNWEq/2/
$("#link").hover(function(e) {
e.preventDefault();
$.data(this).timeout = setTimeout(function() {
$("#tv").stop().animate({marginLeft: "50px"});
$("#tv img)").animate({opacity: 1});
}, 2000);
}, function(e) {
clearTimeout($.data(this,'timeout'));
});

Categories