I'm using JS to make a simple function that displays 3 items one at a time. Works well when you're looking at the page, but when you minimize or change tabs then return, all three items are shown.
Anyone know why? It's as if fadeIn(x) keeps running but hide() stops working. I even checked with different classes.
Here is the code:
$(document).ready(function () {
function start() {
$(".featured-items").hide();
$( ".item-1" ).fadeIn('slow');
setTimeout(one, 5000);
}
function one() {
$(".featured-items").hide();
$( ".item-2" ).fadeIn('slow');
setTimeout(two, 5000);
}
function two() {
$(".featured-items").hide();
$( ".item-0" ).fadeIn('slow');
setTimeout(start, 5000);
}
setTimeout(start, 5000);
});
Problem solved, check the best answer below and make sure to read comments to get a good understanding. Thanks to all
(Updated to provide complete answer)
Your original code is too complex, and a more flexible and simpler implementation is to have just one function, and an array of items in the gallery. Secondly, you should modify your code so the fadeIn animation starts immediately instead of getting queued. Having only one function instead of several makes alterations such as this easier.
Note that in the code below, as in your original code, the various gallery items are classes rather than single element ids and could fade in multiple items.
var gallery = [ '.item-1', '.item-2', '.item-3' ];
var i = 0;
function galleryEvent() {
$(".featured-items").hide();
$( gallery[i] ).fadeIn({duration: 'slow', queue: false});
i = (i + 1) % gallery.length;
setTimeout(galleryEvent, 5000);
}
// start everything off....
galleryEvent();
Related
Been hitting my head a while with this one.
I'm a total novice in JavaScript and jQuery.
After a lot of trial and error I eventually managed to write a function to change the src attribute of an image to create a slideshow as such:
$(function () {
var slideshow = $("#img_slideshow");
var images = [
'img/slideshow1.jpg',
'img/slideshow2.jpg',
'img/slideshow3.jpg'];
var current = 0;
function nextSlide() {
slideshow.attr(
'src',
images[current = ++current % images.length]);
setTimeout(nextSlide, 5000);
}
setTimeout(nextSlide, 5000);
});
This works perfectly, changes the image every 5 seconds. What I wanted, was a fade transition between them. I tried calling .fadeIn and .fadeOut in several places I find logic, such as next to setTimeout (probably wrong) but nothing will work.
Can anyone help? And I'd be grateful to have a simple explanation of where it should be called, could help a lot of folks out there. Thanks.
It should be done like this (using the callbacks) -
function nextSlide() {
slideshow.fadeOut(function() {
$(this).attr('src',images[current = ++current % images.length]).fadeIn();
});
setTimeout(nextSlide, 5000);
}
This insures that the source is not changed until the fade out is complete. The source changes and the fade in then happens. This will not be a cross-fade though.
hoping someone can help.
I'm a javascript novice. I have a list of names that, when hovered over, display a box with that person's contact information.
The problem I'm having is that the box displays too fast; causing boxes to fire off rapidly when mousing over multiple names.
Link: http://law.nd.edu/faculty/
Here's what I believe is the relevant code:
<script>
jQuery(".directory-list li").hover(
function() {
jQuery(this).find(".directory-info").fadeIn(200); ;
},
function() {
jQuery(this).find(".directory-info").fadeOut(50);;
}
);
</script>
Thanks for any help.
Use hoverIntent instead.
There is a nice little plugin for it, that is the easiest way to do it.
http://cherne.net/brian/resources/jquery.hoverIntent.html
It will keep your elements from rapid-firing.
The easiest way would be to add a delay before your fadeIn:
jQuery(this).find(".directory-info").delay(300).fadeIn(200);
You can introduce a delay by using setTimeout as follows:
var hoverTimer;
jQuery(".directory-list li").hover(function() {
var elem = jQuery(this).find(".directory-info");
hoverTimer = setTimeout(function() {
elem.fadeIn(200);
}, 1000); // wait for one second and then fadeIn
},
function() {
clearTimeout(hoverTimer);
jQuery(this).find(".directory-info").fadeOut(50);
});
Check out this fiddle, think this is what you want. The other answer that uses timeoutes will loose the context of this inside the setTimeout() function and will not work.
http://jsfiddle.net/RZUVS/1/.
I have an animation using Animate.CSS that I would like to have replay if the user would like but what I have attempted does not work. Here is the code:
HTML:
<div class="img-center">
<img src="path.jpg" class="feature-image animated rotateInDownRight" />
</div>
<p class="textcenter"> </p>
<div class="img-center">
Replay
</div>
JS:
var $j = jQuery.noConflict();
$j("#replay").click(function() {
$j('.feature-image').removeClass('animated rotateInDownRight').addClass('animated rotateInDownRight');
});
I do know the script itself works as I can see it happen in Firebug however that animation doesn't animate again. How do I achieve this with Animate.CSS?
This is just a guess but it appears that jQuery isn't "finished" removing the class before it adds it back in. I know this makes NO sense, but it's how JavaScript works. It can call the next function in the chain before all the stuff from the first one is finished. I poked around the code on Animate.CSS's site and saw that they use a timeout in their animation function. You might try the same. Here's their code:
function testAnim(x) {
$('#animateTest').removeClass().addClass(x);
var wait = window.setTimeout( function(){
$('#animateTest').removeClass()},
1300
);
}
What this is doing is exactly like what you are doing except that it waits for the animation to finish, then removes the classes. That way when the other class is added back in, it is truely "new" to the tag. Here is a slightly modified function:
function testAnim(elementId, animClasses) {
$(elementId).addClass(animClasses);
var wait = window.setTimeout( function(){
$(elementId).removeClass(animClasses)},
1300
);
}
Notice two things: First this code would allow you to change what element gets the animation. Second, you remove the classes you added after 1300 milliseconds. Still not 100% there, but it might get you further down the road.
It should be noted that if there is already some animation classes on the object it might break this JS.
found the right answer at animate.css issue#3
var $at = $('#animateTest').removeClass();
//timeout is important !!
setTimeout(function(){
$at.addClass('flash')
}, 10);
Actually a simpler version can avoid using JQuery too.
el.classList.remove('animated','flash');
//timeout is important !!
setTimeout(function(){
el.classList.add('animated','flash');
}, 10);
I believe the issue here is that when I remove the class it was adding the class to quickly. Here is how I solved this issue:
(HTML is same as above question).
JS:
var $j = jQuery.noConflict();
window.setTimeout( function(){
$j('.feature-image').removeClass('animated rotateInDownRight')},
1300);
$j("#replay").click(function() {
$j('.feature-image').addClass('animated rotateInDownRight');
});
What I believe is happening is the jQuery code is removing and adding the class to quickly. Regardless of the reason this code works.
If you wish you can also give a try to this javaScript side development that support animate.css animations. Here is an example of usage.
//Select the elements to animate and enjoy!
var elt = document.querySelector("#notification") ;
iJS.animate(elt, "shake") ;
//it return an AnimationPlayer object
//animation iteration and duration can also be indicated.
var vivifyElt = iJS.animate(elt, "bounce", 3, 500) ;
vivifyElt.onfinish = function(e) {
//doSomething ...;
}
// less than 1500ms later...changed mind!
vivifyElt.cancel();
Take a look here
My answer is a trick to add/remove the css class with a tint delay:
$('#Box').removeClass('animated').hide().delay(1).queue(function() {
$(this).addClass('animated').show().dequeue();
});
Also you can test it without hide/show methods:
$('#Box').removeClass('animated').delay(1).queue(function() {
$(this).addClass('animated').dequeue();
});
I fill it works smooth in chrome but it works with more unexpected delay in FF, so you can test this js timeout:
$('#Box').removeClass('animated');
setTimeout(function(){
$('#Box').addClass('animated');
}, 1);
This solution relies on React useEffect, and it's rather clean, as it avoids manipulating the class names directly.
It doesn't really answers the OP question (which seems to be using jQuery), but it might still be useful to many people using React and Animate CSS library.
const [repeatAnimation, setRepeatAnimation] = useState<boolean>(true);
/**
* When the displayedFrom changes, replay the animations of the component.
* It toggles the CSS classes injected in the component to force replaying the animations.
* Uses a short timeout that isn't noticeable to the human eye, but is necessary for the toggle to work properly.
*/
useEffect(() => {
setRepeatAnimation(false);
setTimeout(() => setRepeatAnimation(true), 100);
}, [displayedFrom]);
return (
<div
className={classnames('block-picker-menu', {
'animate__animated': repeatAnimation,
'animate__pulse': repeatAnimation,
})}
...
)
In my application I have a script that tells when somebody comes online or goes offline. I put the text of if somebody goes online/offline via content = name+' went offline' or vice versa. I then put that text in a div at the end of my function call: $('#new').text(content);
The problem comes with the fade out, all in all it's not really working. I've been trying to play around with it. Here's what I have so far:
$('#new').text(content);
$('#new').fadeIn('slow', function() {
setTimeout($('#new').fadeOut('slow', function() {
$('#new').css('display', 'none');
}));
});
display:none inside the callback is unnecessary, fadeOut() automatically sets the display to none after concluding.
$('#new').text(content);
$('#new').fadeIn('slow', function() {
setTimeout("$('#new').fadeOut('slow');", 2000);
});
2000 is the number of miliseconds you'd like to delay it, change it to whatever value suits you better.
As #Pst commented, the function-object may be more consistent even though I personally have more issues with function-objects than code strings.
You may also use the function-object:
$('#new').text(content);
$('#new').fadeIn('slow', function() {
setTimeout(function(){ $('#new').fadeOut('slow'); }, 2000);
});
You need to remember to provide duration for which the setTimeout should wait before acting.
$("#hello")
.text(content)
.fadeIn("slow", function(){
setTimeout(function(){
$("#hello").fadeOut();
}, 2000);
});
2000 indicates 2 seconds. If you would like it to stay visible longer, increase this.
Functional Demo: http://jsbin.com/aciwon/edit#javascript,html
Are you using this inside a $(document).ready()? If not, place it like:
$(document).ready(function() {
$('#new')
.text(content)
.fadeIn('slow', function() {
setTimeout(function() { $('#new').fadeOut('slow'); }, 2000);
});
});
Also, be sure to initialize your element with a display: none and note I've removed part of the unecessary code.
Your setTimeout() code is wrong, you have to pass a function to it.
Why not just use delay?
$("#new").text(content).fadeIn("slow").delay(1000).fadeOut("slow");
I'm required to develop a slideshow (not an existing one) with jQuery. I was able to change picture with a function that I created named changePic (takes an image link). It incorporates the fading animation from the jQuery library.
For the slideshow I'm trying to use a while loop. It kind of works, except that it doesn't wait for the animation to finish.
How do I, a) wait for the animation to finish, b) delay the changing picture so it display the picture for a couple of seconds?
Also tried Settimeout, and it doesn't work.
Edit:
Basically changing image is like this:
function changePic(imglink){
var imgnode = document.getElementById("galleryimg");
$(imgnode).fadeTo(500, 0, function(){
$(imgnode).attr("src", imglink);
$(imgnode).fadeTo(1000, 1);
})
}
and the slideshow code is like this, but obviously it shouldn't.
function slideshow(gallerylinks){
var i=0;
while (i<gallerylinks.length){
changePic(gallerylinks[i]);
i++;
}
}
You could always try ditching the while loop, and going with a perpetually recursive function...
on the .animate, you could add a timeout function (at whatever interval) that calls the changePic function. As I have no idea what your code looks like, I will provide a fantastically generic outline.
/* array of imgUrls */
var imgUrls = new Array(); //populate it however
changePic(slideToShowIndex, fadeOutSpeed, fadeInSpeed, slideDelay)
{
$('#slideHolder').animate({ opacity: 0}, fadeOutSpeed , function(){
$('#slideHolder').attr('src', imgUrls[slideToShowIndex]);
$('#slideHolder').animate({ opacity: 1 }, fadeInSpeed, function() {
setTimeout(function() { changePic(slideToShowIndex+1, fadeOutSpeed, fadeInSpeed, slideDelay);}, slideDelay});
});
}});
}
$(document).ready(function() {
changePic(0, 5000, 5000, 10000);
});
This should (in theory) fade the image out, swap it with the new one, and fade it in (both taking 5 seconds) and then adding a delay to call itself with the next slide index in 10 seconds.
This is in no way perfect, but does outline the general idea. Since we have no idea what your code looks like, I can only assume your setTimeout was in the wrong spot. Doing it like this will make sure that the animation has finished before the timeout is set. This guarantees that the slide wont change until after the animation has changed.
of course you could always use a combination of the ':not(:animated)' selector and a setInterval to achieve much the same effect.
EDIT: made a slight change to stack the animations properly. The thoery behind this still works even with the OPs addition of code.
You could have provided more details or example code but have a look at stop() and delay() functions.