http://api.jquery.com/fadeOut/ <- fadeOut api
I'm trying to learn Javascript and I've been playing with a snippet I found on Codepen.
I'm having trouble trying to get the random text array snippet to have the text fadeOut when it transitions away to another text object. Right now, the array cycles through and randomly selects a string from the array using the Math.Random function (5*1) and it fades in each time a new text object loads in, however I want it to fade out and I don't think I'm utilizing the .fadeOut property properly. How can I get it so that the text fadesOut, so the text does fadeIn fadeOut, instead of fadeIn, insta kill?
var textTimer;
var inTransition = false;
startTimer();
function startTimer() {
clearTimeout(textTimer);
textTimer = setTimeout(changeTitle, 3500);
}
changeTitle();
var titleNumber = Math.floor(Math.random() * 5) + 1;
function changeTitle() {
var titleArray = [
"Test1",
"Test2",
"Test3",
"Test4",
"Test5"
];
var tempTitleLength = titleArray.length - 1;
if (inTransition == false) {
inTransition = true;
titleNumber++;
if (titleNumber > tempTitleLength){
titleNumber = 0
}
$('.text').html('');
$('.text').css({opacity: '0'});
$('.text').html(titleArray[titleNumber]);
$('.text').fadeOut();
$('.text').stop().delay(0).animate({
opacity: 1
}, 1500, function() {
inTransition = false;
startTimer.()
});
}
}
Thanks! :D
The HTML is pretty straight forward
<div class="text"></div>
Multiple problems:
$('.text').html('');
$('.text').css({opacity: '0'});
$('.text').html(titleArray[titleNumber]);
You are already removing the text in html('') without fading out,
setting css opacity to 0 without any delay, setting html new text without any animation.
There is a syntax error also startTimer.() I guess is typo.
Remove first 2 lines and set new text after fade out is done.
You also need to wait for fadeOut to finish before doing fadeIn.
So, sequence: fadeOut, set new text, fadeIn.
Like this:
$('.text').fadeOut(1500, function () {
$('.text').html(titleArray[titleNumber]);
$('.text').fadeIn(1500, function () {
inTransition = false;
startTimer()
});
});
JSFiddle: http://jsfiddle.net/Dzyzw/
You have syntax errors in your code: you have startTimer.() should be startTimer() and you did not close your startTimer function with a }. I corrected this for you and set up a sample JSFiddle for you review. Seems to be working otherwise.
Here is the sample JSFiddle: CLICK HERE
Here's what I think you're going for--
Set initial text.
Fade out your text.
Change the text.
Fade in the new text.
Wait a while, then return to step 2.
I would drop all the transition flags and use the optional callback functions that are fired when fadeOut and fadeIn complete to move from step to step, e.g.
$('.text').fadeOut(1000, function() {
$('.text').html(get_next_word());
$('.text').fadeIn(500);
});
Just fire that off on a timer that is 1500 milliseconds + the time you want the text to be fully visible.
Related
For my website, I am trying to fade out part of a word, replace it, and then fade it back in. I am using animate.css to do this along with jquery.
HTML
<h1>D<span id="span-header">iscover</span></h1>
JavaScript
$("#span-header").addClass("animated fadeOut");
setTimeout(function() {
var newText = $("#span-header").text().replace("iscover", "ispicio");
$("#span-header").text(newText);
}, 700);
$("#span-header").addClass("animated fadeIn");
What it is doing is fading out and replacing the text but it does not fade back in. What am I doing wrong?
1st: you need to Move the code for .addClass("fadeIn") inside setTimeout call back function
2nd: use .removeClass('fadeOut') to remove fadeOut class before adding fadeIn class
Demo
$("#span-header").addClass("animated fadeOut");
setTimeout(function() {
var newText = $("#span-header").text().replace("iscover", "ispicio");
$("#span-header").text(newText);
$("#span-header").removeClass('fadeOut').addClass("fadeIn");
}, 700);
so I'm trying to create a simple slide show from scratch, and so far I was able to get full screen images to fade out and fade in infinetly, but for some odd reason using setInterval(function(){fade(var)}, 3500);didn't work, maybe someone can explain why the first and last images took way longer than 3,5 seconds to fade. Meanwhile, I was trying to solve that problem by implementing a callback function in the fade(). My example has four images, and they start fading out until it reaches image one, then don't fade out image one and start fading back in image two until image 4, and do this forever, here is my recent attempt to implement a callback function:
var i = 4;
$(document).ready(function(){
fade(i, fade);
});
var fadeIN = false;
function fade(objectID, callbackfn){
var fadeTime = 3500;
if(!fadeIN){
$("#slide-"+objectID).fadeOut(fadeTime);
i--;
if(i === 1) {
fadeIN = true;
}
}
else{
i++;
$("#slide-"+objectID).fadeIn(fadeTime);
if(i === 4){
fadeIN = false;
}
}
if(arguments[1]){
callbackfn(i);
}
}
But that is not working, it fades out image 4, image 3 and stops on image 2. Maybe there is a way to evenly time the fading transitions using the setIntervel(), if so can someone tell me how? Appreciate any help.
Here is a JSFiddle to the code: http://jsfiddle.net/8kgc0chq/ it is not working tho.
Here is the doc for .fadeOut()
There is an optional argument complete:
A function to call once the animation is complete.
Put the next animation in there, they too take a complete (callback) function.
$("#id").fadeOut(fadeTime, function() {
// code to execute after animation complete
});
You need to do it properly with javascript. Easy way fails after last element.
So here is my solution. Can it be improved further, I think yes.. But it does work now. And is future proof to some extent.
I cleaned up css and changed html structure a little.
Demo: http://jsfiddle.net/8kgc0chq/3/
$(document).ready(function () {
$(window).resize(function () {
realTimeHeight();
});
realTimeHeight();
startSlides();
});
function startSlides() {
var fadeTime = 1000,
delay = 1300,
i = 0,
slides = $("#hero-slider > .slide"),
len = slides.length;
slides.hide();
var pF = $('<div class="slide">'), pB = pF.clone();
pF.attr('id', slides.eq(i).attr('id'));
$('#hero-slider').prepend(pF).prepend(pB);
setInterval(fadeThisIn, fadeTime + delay);
function fadeThisIn() {
pB.attr('id', pF.attr('id'));
i = ++i % len;
pF.hide().attr('id', slides.eq(i).attr('id')).fadeIn(fadeTime);
}
}
function realTimeHeight() {
var altura = $(window).height();
$("#hero-slider").css("height", altura);
}
I'm trying to build a simple image slider (but using a fade effect). Every two seconds, the image should change to another image. At the end, it should call repeat_sponsor() again, to start over, so it becomes a loop.
I've written this (highly ineffective) code for 5 images. Turns out I'm going to need it for around 50 images. My editor just freezes when I add too much code.
I've tried using while-loops, but I just can't figure it out how to do this the right way.
Anyone who can help me with this?
function repeat_sponsor()
{
$("#sponsor2").hide();
$("#sponsor3").hide();
$("#sponsor4").hide();
$("#sponsor5").fadeOut("slow");
$("#sponsor1").fadeIn("slow", function() {
setTimeout(function(){$("#sponsor2").fadeIn("slow", function() {
setTimeout(function(){$("#sponsor3").fadeIn("slow", function() {
setTimeout(function(){$("#sponsor4").fadeIn("slow", function() {
setTimeout(function(){$("#sponsor5").fadeIn("slow", ...
(function (){
var cnt = 50; //set to the last one...
var max=50;
function show() {
$("#sponsor" + cnt).fadeOut("slow"); //if you want the fadeout to be done before showing next, put the following code in the complete callback
cnt++;
if(cnt>max) {
cnt=1;
}
$("#sponsor" + cnt).fadeIn("slow");
window.setTimeout(show, 2000);
}
show();
})();
But the real issue is the fact you are loading tons of images from the start. You will be better off changing it so you only have a small subset of images and change the source.
You should use some sort of for loop and a class for hiding the images. and add a max value that if checks out resets c & i
var i=0;
var c=1;
function repeat_sponsor()
{
$("#sponsor"+i).fadeOut("slow");
$(".sponsers").hide()
$("#sponsor"+c).fadeIn("slow", function() {
window.setTimeout(repeat_sponsor(), 3000);
}
i++;
c++;
}
Just run a function every two seconds with setInterval and appropriately target your different sponsor divs:
var i = 1;
var max = 50;
setInterval(function() {
// Could target all other sponsor images with a class "sponsor"
$('.sponsor').fadeOut();
// Execute code on the target
$("#sponsor" + i).fadeIn();
if (i === max) {
i = 0;
}
i++;
}, 2000);
So I've created the following function to fade elements in and passed in a div that I want to fade in which in this case is an image gallery popup that I want to show when a user clicks an image thumbnail on my site. I'm also passing in a speed value (iSpeed) which the timeout uses for it's time value. In this case I'm using 25 (25ms).
I've stepped through this function whilst doing so it appears to be functioning as expected. If the current opacity is less than 1, then it is incremented and it will recall itself after the timeout until the opacity reaches 1. When it reaches one it stops fading and returns.
So after stepping through it, I take off my breakpoints and try to see it in action but for some reason my gallery instantly appears without any sense of fading.
var Effects = new function () {
this.Fading = false;
this.FadeIn = function (oElement, iSpeed) {
//set opacity to zero if we haven't started fading yet.
if (this.Fading == false) {
oElement.style.opacity = 0;
}
//if we've reached or passed max opacity, stop fading
if (oElement.style.opacity >= 1) {
oElement.style.opacity = 1;
this.Fading = false;
return;
}
//otherwise, fade
else {
this.Fading = true;
var iCurrentOpacity = parseFloat(oElement.style.opacity);
oElement.style.opacity = iCurrentOpacity + 0.1;
setTimeout(Effects.FadeIn(oElement, iSpeed), iSpeed);
}
}
}
Here's where I'm setting up the gallery.
this.Show = function (sPage, iImagesToDisplay, oSelectedImage) {
//create and show overlay
var oOverlay = document.createElement('div');
oOverlay.id = 'divOverlay';
document.body.appendChild(oOverlay);
//create and show gallery box
var oGallery = document.createElement('div');
oGallery.id = 'divGallery';
oGallery.style.opacity = 0;
document.body.appendChild(oGallery);
//set position of gallery box
oGallery.style.top = (window.innerHeight / 2) - (oGallery.clientHeight / 2) + 'px';
oGallery.style.left = (window.innerWidth / 2) - (oGallery.clientWidth / 2) + 'px';
//call content function
ImageGallery.CreateContent(oGallery, sPage, iImagesToDisplay, oSelectedImage);
//fade in gallery
Effects.FadeIn(oGallery, 25);
}
Could anyone help me out?
Also, I'm using IE10 and I've also tried Chrome, same result.
Thanks,
Andy
This line:
setTimeout(Effects.FadeIn(oElement, iSpeed), iSpeed);
calls Effects.FadeIn with the given arguments, and feeds its return value into setTimeout. This is exactly like foo(bar()), which calls bar immediately, and then feeds its return value into foo.
Since your FadeIn function doesn't return a function, that would be the problem.
Perhaps you meant:
setTimeout(function() {
Effects.FadeIn(oElement, iSpeed);
}, iSpeed);
...although you'd be better off creating that function once and reusing it.
For instance, I think this does what you're looking for, but without recreating functions on each loop:
var Effects = new function () {
this.FadeIn = function (oElement, iSpeed) {
var fading = false;
var timer = setInterval(function() {
//set opacity to zero if we haven't started fading yet.
if (fading == false) { // Consider `if (!this.Fading)`
oElement.style.opacity = 0;
}
//if we've reached or passed max opacity, stop fading
if (oElement.style.opacity >= 1) {
oElement.style.opacity = 1;
clearInterval(timer);
}
//otherwise, fade
else {
fading = true;
var iCurrentOpacity = parseFloat(oElement.style.opacity);
oElement.style.opacity = iCurrentOpacity + 0.1;
}
}, iSpeed);
};
};
Your code has a lot of problems. The one culpable for the element appearing immediately is that you call setTimeout not with a function but with the result of a function, because Effects.FadeIn will be executed immediately.
setTimeout(function(){Effects.FadeIn(oElement, iSpeed)}, iSpeed);
will probably act as you intend.
But seriously, you probably should not re-invent this wheel. jQuery will allow you to fade elements in and out easily and CSS transitions allow you to achieve element fading with as much as adding or removing a CSS class.
T.J. and MoMolog are both right about the bug: you're invoking the Effects.FadeIn function immediately before passing the result to setTimeout—which means that Effects.FadeIn calls itself synchronously again and again until the condition oElement.style.opacity >= 1 is reached.
As you may or may not know, many UI updates that all take place within one turn of the event loop will be batched together on the next repaint (or something like that) so you won't see any sort of transition.
This jsFiddle includes the suggested JS solution, as well as an alternate approach that I think you may find to be better: simply adding a CSS class with the transition property. This will result in a smoother animation. Note that if you go this route, though, you may need to also include some vendor prefixes.
I have a jsfiddle for this
Jsfiddle
The problem is, I am trying to create a script that ones a button is clicked flashes an image (car lights) on and off for a period of time. It works fine, but in IE8 since the lights are png the animation for it is causing a black background and border as it blinks on and off. So I trying to duplicate the same thing, but without using animation.
In my jsfiddle, the first function for the first click div represents what i am trying to do without animation, but it is not repeating. The code:
$('.oneD').click(function(){
for (var i = 0; i <= 9; i++) {
$('.oneP').show();
setTimeout(function(){
$('.oneP').hide();
}, 1000);
}
});
The 2nd function is the one I already created that does work, but it has the animation:
$('.twoD').click(function(){
for (var i = 0; i <= 9; i++) {
$(".twoP").fadeIn(1000, function () {
$(".twoP").hide();
});
}
});
Keep in mind that the jsfiddle is just a simple mock not using images. I am just looking for the functionality in which i can incorporate this. I appreciate your time in helping me with this.
instead of setTimeout() use setInterval() and clearInterval() like this:
$('.oneD').click(function(){
$('.oneP').show();
var interval = setInterval(function(){
$('.oneP').hide();
}, 1000);
//*after a number of time or loop
interval.clearInterval();
});
setInterval() "Loop" throught the function it is given every number of millisecond you pass it. and clearInterval() stop the "Loop".
I'd do it like this :
$('.oneD, .twoD').on('click', function(){
for (var i=0; i<9; i++)
$('.'+this.className.replace('D', 'P')).delay(1000).show(0)
.delay(1000).hide(0);
});
FIDDLE
This uses a selector for both elements and the same event handler, then swaps out the D for a P in the showing and hiding.
As for using delay() and making this work, hide() and show() will work just as the animated jQuery methods if a value for the duration is passed, even if that value is zero.
Fiddle here: http://jsfiddle.net/HxFpr/
var i;
$('.twoD').click(function(){
i = 0;
loopFlash();
});
function loopFlash(){
if(i < 10){ // flash 5 times (1 on 1 off = 2 cycles)
$('.twoP').toggle();
var flashing = setTimeout(loopFlash,500);
}
i++;
}
Yet another solution for you.
No Animation - with single interval
With animation - pure jQuery
http://jsfiddle.net/x6Kpv/6/
var noAnimationHandler = function() {
setInterval(function() {
var $el = $('.oneP');
$el[$el.is(":visible") ? "hide" : "show"]();
}, 800);
};
var animationHanddler = function() {
$('.twoP').fadeIn(300, function() {
$(this).delay(150).fadeOut(300, animationHanddler);
});
}
$('.oneD').click(noAnimationHandler);
$('.twoD').click(animationHanddler);
Thanks