I have some code that I would like to integrate into the a website and have it be in the middle of the screen. This code does some fading with Javascript. But I can't move it around the screen like I would like to. When I move it around it messes up the animation.
Here is the HTML
<!DOCTYPE html>
jQuery fade-ins with a JavaScript for() loop
<div id="elem0" class="toBeFaded">Here's the first message...</div>
<div id="elem1" class="toBeFaded">We have second one here...</div>
<div id="elem2" class="toBeFaded">And here's the third message...</div>
<div id="elem3" class="toBeFaded">OMG!!! Here's the fourth message!</div>
<script src="js/jquery-1.7.1.min.js"></script>
<script src="js/fadeCode.js" defer="defer"></script>
Javascript
$(function (){
var yourFade = 1, // the amount of time in seconds that the elements will fade in AND fade out
yourDelay = 2, // the amount of time in seconds that there will be a delay between the fade ins and fade outs
fadeTime = yourFade * 1000, //convert fade seconds to milliseconds (1000)
delayTime = yourDelay * 1000, // convert delay seconds to milliseconds (2000)
totalTime = fadeTime + delayTime, //3000 milliseconds...needed for all those delays we talked about
allElems, // find out exactly how many page elements have the 'toBeFaded' class (4)
elemNoFade, // Will help us find the last element represent the last element (3)
i,
fadingElem;
for (i = 0, allElems = $('.toBeFaded').length, elemNoFade = allElems - 1; i < allElems; i+=1) {
fadingElem = "#elem" + i;
if (i === 0) {
$(fadingElem).fadeIn(fadeTime).delay(delayTime).fadeOut(fadeTime);
} else if (i === elemNoFade) {
$(fadingElem).delay(totalTime * i).fadeIn(fadeTime);
} else {
$(fadingElem).delay(totalTime * i).fadeIn(fadeTime).delay(delayTime).fadeOut(fadeTime);
}
} });
and CSS
.toBeFaded {
display: none;
position:absolute;
font-size:70pt;
}
and a link to jsfiddle
I'm not sure I see the problem. Take a look at this fiddle: http://jsfiddle.net/joplomacedo/6xfKN/375/
Related
I have a div that shows gif image and I have 4 gif image to cycle through with different duration in an endless loop(gif should cycle through 1 2 3 4 then 1 2 3 4 endlessly)
My gifplayer div: Other than the first div the other 4 divs initial display property is set to none
<div id="gifplayer"><img id="gif1" class="gifimg" src="gif1.gif">
<div id="gifplayer"><img id="gif2" class="gifimg" src="gif2.gif" style="display:none;>
<div id="gifplayer"><img id="gif3" class="gifimg" src="gif3.gif" style="display:none;>
<div id="gifplayer"><img id="gif4" class="gifimg" src="gif4.gif" style="display:none;>
Each gif has a different duration and I would like to play one another in an endless loop. Below is my jQuery and it works but only for the first time and also only the first gif is playing as expected 2nd, 3rd and 4th gifs are abruptly ending:
jQuery:
$(document).ready(function() {
setTimeout(function(){
$("#gif1").css("display","none")
$("#gif2").css("display","block")
$("#gif3").css("display","none")
$("#gif4").css("display","none")
}, 16000);
setTimeout(function(){
$("#gif1").css("display","none")
$("#gif2").css("display","none")
$("#gif3").css("display","block")
$("#gif4").css("display","none")
}, 18000);
setTimeout(function(){
$("#gif1").css("display","none")
$("#gif2").css("display","none")
$("#gif3").css("display","none")
$("#gif4").css("display","block")
}, 67800);
setTimeout(function(){
$("#gif1").css("display","block")
$("#gif2").css("display","none")
$("#gif3").css("display","none")
$("#gif4").css("display","none")
}, 16000);
})
Use the Modulo operator % to reset a i counter back to 0
Use classList 's .remove() and .add() methods
Use data-* attribute to store a desired ms duration time and later read it in JS using Element.dataset
const gifify = (EL) => {
const IMGS = EL.querySelectorAll("img");
const tot = IMGS.length;
let i = 0;
(cycle = () => {
const IMG = IMGS[i];
const dur = IMG.dataset.duration || 100; // ms (Fallback to 100ms)
IMGS.forEach(EL => EL.classList.remove("show")); // Hide all
IMG.classList.add("show"); // Show one
i += 1; // Increment index
i %= tot; // Loop index
setTimeout(cycle, dur );
})();
};
document.querySelectorAll(".gifify").forEach(gifify);
.gifify img { display: none; }
.gifify img.show { display: block; }
Infinite cycle trough images with different duration:
<div class="gifify">
<img data-duration="300" src="//www.placehold.it/100x100/0bf?text=1">
<img data-duration="500" src="//www.placehold.it/100x100/fb0?text=2">
<img data-duration="400" src="//www.placehold.it/100x100/f0b?text=3">
<img data-duration="100" src="//www.placehold.it/100x100/b0f?text=4">
</div>
I'm trying to find a good way to append a div to a container one at a time. I don't want to append all the divs and have them fade in one at a time. The code below is not working. Without the for loop it appends one at a time. I tried the for loop to limit the amount of times div gets appended sequentially but it output 4 divs every second. I want it to output one div once a second, four times.
for(var i = 0;i < 4; i++){
setInterval(function(){
$(".output").append("<div class='odiv'>TEST</div>")
},1000)
}
css:
.odiv{
display: inline-block;
}
html:
<div class="output"></div>
Just use timeout instead of interval with time as function of current iteration index 1000 * i:
for (var i = 0; i < 4; i++) {
setTimeout(function () {
$(".output").append("<div class='odiv'>TEST</div>")
}, 1000 * i);
}
.odiv {
display: inline-block;
padding: 5px;
background: #EEE;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="output"></div>
Use a counter in order to clear the interval:
var i = 0;
var myInterval = setInterval(function() {
if (i === 4) return clearInterval(myInterval);
$(".output").append("<div class='odiv'>TEST</div>");
i++;
},1000);
Your current code is running $('.output').append() four times each second. Here's a breakdown of what your current code is doing:
- Start a loop for 0,1,2,3
--- Loop 0
Append a div to `.output` every 1000 milliseconds.
--- Loop 1
Append a div to `.output` every 1000 milliseconds.
--- Loop 2
Append a div to `.output` every 1000 milliseconds.
--- Loop 3
Append a div to `.output` every 1000 milliseconds.
The result is 4 intervals appending the .odiv element every 1000 milliseconds.
You want to append a single .odiv element every 1000 milliseconds, for 4 seconds. To do this, create a function that appends a div each 1000 milliseconds and stop it after the 4th iteration.
var i = 0;
var appendDiv = setInterval(function() {
if (i === 4) {
// Stop the setInterval function from running
clearInterval(appendDiv);
} else (
$(".output").append("<div class='odiv'>TEST</div>")
)
// Increase the counter
i++
}, 1000)
Here's a working jsFiddle.
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 have a div called noti_box which fades in on page load. Sometimes there may be only one noti_box div or there might be 2 3 or 4.
a user can close this div should they want to by clicking on it.
If no noti_boxes are displayed on the page I am trying to fade in another div, lets call this div (advert).
however with my current script I have, because my first div noti_box takes a couple of seconds to fade in it will automatically show my advert div. what should happen is my advert div should only show once the user has closed the div noti_box, not before it fades in on the page.
Is there a way I can delay my jquery function to wait until the noti_box has finished fading in?
noti_box jquery:
<script>
$('.noti_box').each(function(i) {
// 'i' stands for index of each element
$(this).hide().delay(i * 1000).fadeIn(1500);
});
</script>
my advert div jquery:
<script type="text/javascript">
$(document).ready(function(){
if ($('.noti_box').is(':hidden')) {
$(".advert").fadeIn("slow");
}
}); </script>
I have gotten close to what I need:
<script>
$(document).ready(function(){
var animations = [];
$('.noti_box').each(function(i) {
animations.push(
$(this).hide().delay(i * 1000).fadeIn(1500).promise()
);
});
$.when.apply($, animations).done(function () {
if ($('.noti_box').is(':visible')===false) {
$(".advert").fadeIn("slow");
}});
});
</script>
by using this script my noti_boxes fade in and if I close them within like 1 second of them fading in then my advert box fades in. however if I wait after 1 second then I close the noti_boxes my advert doesn't fade in at all. Any ideas?
Since you know the amount of elements and the amount of time each takes to fade, you can calculate the total needed delay for the advert to show, something like this:
// number of elements * their delay + fade time
var totalDelay = ($('.noti_box').length - 1) * 1000 + 1500;
$(document).ready(function(){
setTimeout(function(){
$(".advert").fadeIn("slow");
}, totalDelay);
});
Here's an example with 5 noti boxes (can be any number):
$('.noti_box').each(function(i) {
// 'i' stands for index of each element
$(this).hide().delay(i * 1000).fadeIn(1500);
});
// number of elements * their delay + fade time
var totalDelay = ($('.noti_box').length - 1) * 1000 + 1500;
$(document).ready(function() {
setTimeout(function() {
$(".advert").fadeIn("slow");
}, totalDelay);
});
.advert {
display: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="noti_box">1</div>
<div class="noti_box">2</div>
<div class="noti_box">3</div>
<div class="noti_box">4</div>
<div class="noti_box">5</div>
<div class="advert">ADVERT</div>
Try putting document.ready in Javascript SetTimeout function.
I found the answer to my question, I set a time interval for my last function to repeat every second.
<script>
$(document).ready(function(){
var animations = [];
$('.noti_box').each(function(i) {
animations.push(
$(this).hide().delay(i * 1000).fadeIn(1500).promise()
);
});
$.when.apply($, animations).done(function () {
time=setInterval(function(){
if ( $('.noti_box:visible').length === 0 ) {
$(".advert").fadeIn("slow");
} },1000);
});
});
</script>
So I seem to have run into a bit of a dead end. I'm making a page which has an image slider. The slider has three images, one centered on the screen, the other two overflow on the left and right. When you click on the button to advance the slides it runs this code....
$('#slideRight').click(function() {
if ($('.container').is(':animated')) {return false;}
var next=parseInt($('.container img:last-of-type').attr('id')) + 1;
if (next == 12) {
next = 0;
}
var diff = galsize() - 700;
if ($('.thumbs').css("left") == "0px") {
var plus = 78;
} else {
var plus = 0;
}
var app='<img id="' + next + '" src="' + imgs[next].src + '">';
$('.container').width('2800px').append(app);
$('.container').animate({marginLeft: (diff + plus) + "px"}, 300, function() {
$('.container img:first-of-type').remove();
$('.container').width('2100px').css("margin-left", (galsize() + plus) + "px");
});
}); // end right click
This works just fine, not a problem..... I also have an interval set up to run this automatically every 5 seconds to form a slideshow...
var slideShow = setInterval(function() {
$('#slideRight').trigger("click");
}, 5000);
This also works perfectly, not a problem.... However my problem is this.... I have thumbnails, when you click on a thumbnail, it should run this code until the current picture is the same as the thumbnail.... here is the code....
$('img.thumbnail').click(function() {
clearInterval(slideShow);
var src = $(this).attr("src");
while ($('.container img:eq(1)').attr('src') != src) {
$('#slideRight').trigger("click");
}
});
When I click on the thumbnail nothing happens... I've used alert statements to try and debug, what ends up happening is this....
The while loop executes, however nothing happens the first time. The slide is not advanced at all. Starting with the second execution, the is('::animated') is triggered EVERY TIME and the remainder of the slideRight event is not executed...
So my first problem, can anyone shed some light on why it doesn't run the first time?
And my second question, is there any way to wait until the animation is complete before continuing with the loop?
Any help would be appreciated. Thank you!
I'm going to start with the second part of your question, regarding completing the animation before continuing with the loop.
I have done something similar in the past, and what I did was set two global variables to control the animation. One variable is for how long you want the period to be, the other is a counter for how much time since the last loop.
So, for example:
$timeToChange = 5; // in Seconds
$timeSinceReset = 0; // also in Seconds
Set your interval for one second and call a new function (autoAdvance()):
var slideShow = setInterval(function() {
autoAdvance();
}, 1000); // only one second
and then use the counter variable to count each time the interval is called (each second). Something like:
function autoAdvance(){
if($timeSinceReset == $timeToChange){
$timeSinceReset = 0;
$('#slideRight').trigger("click"); // execute click if satisfied
}
else{$timeSinceReset++;}
}
To stop from looping until the animation is done, reset $timeSinceReset back to 0 (zero) when you click on the thumbnail. Something like:
$('#thumbnail').click(function(){
$timeSinceReset = 0;
});
That'll give you a nice 5 second buffer (or whatever you set $timeToChange) before the loop continues.
As for the first part of your question, grab the number of the particular thumbnail, and use that to scroll to the appropriate image. Something like:
$('.thumb').click(function (each) {
$childNumber = $(this).index();
});
which you cansee in this fiddle. Click in one of the grey boxes and it'll tell you which one you clicked in. Use that info to scroll to the appropriate image (1, 2 or 3 if you only have three images).
Hope this helps.
Here is a full solution for one possible way of doing it at this fiddle.
HTML:
The top container holds the images. In this particular example I've included three, using divs instead of images. Whether you use images or divs doesn't change anything.
<div class="holder_container">
<div class="img_container">
<div class="photo type1">ONE</div>
<div class="photo type2">TWO</div>
<div class="photo type3">THREE</div>
</div>
</div>
.img_container holds all the images, and is the same width as the sum of the widths of the images. In this case, each image (.photo) is 150px wide and 50px tall, so .img_container is 450px wide and 50px tall. .holder_container is the same dimensions as a single image. When this runs, the .holder_container is set to hide any overflow while .img_container moves its position left or right.
Included also are two nav buttons (forward and back)
<div class="nav_buttons">
<div class="nav back"><<<</div>
<div class="nav forward">>>></div>
</div>
As well as three thumbnail images - one for each image in the top container
<div class="top">
<div class="thumb"></div>
<div class="thumb"></div>
<div class="thumb"></div>
</div>
CSS:
Refer to the JS Fiddle for all CSS rules.
The most important are:
.holder_container {
margin: 0px;
padding: 0px;
height: 50px;
width: 150px;
position: relative;
overflow: hidden;
}
.img_container {
margin: 0px;
padding: 0px;
height: 50px;
width: 450px;
position: relative;
left: 0px;
top: 0px;
}
In the example, .type1, .type2 and .type3 are only used to color the image divs so you can see the animation. They can be left out of your code.
JavaScript:
The javascript contains the following elements…
Variables:
var timeToChange = 3; // period of the image change, in seconds
var timeSinceReset = 0; // how many seconds have passed since last image change
var currentImage = 1; // Which image you are currently viewing
var totalImages = 3; // How many images there are in total
Functions:
autoAdvance - called once every second via setInterval. Counts the number of seconds since the last image change. If the number of seconds that has passed is equal to the period, a function is called that switches the images.
function autoAdvance() {
if (timeSinceReset == timeToChange) {
timeSinceReset = 0;
moveNext();
} else {
timeSinceReset++;
}
}
moveNext() - moves to the next image. If the current image is the last (currentImage == totalImages) then currentImages is set back to 1 and the first image is displayed.
function moveNext(){
if(currentImage == totalImages){
currentImage = 1;
var newPos = 0 + 'px';
$('.img_container').animate({left: newPos}, 300);
}else{
currentImage++;
var newPos = -((currentImage-1) * 150) + 'px'; // child numbers are zero-based
$('.img_container').animate({left: newPos}, 300);
}
}
Rest of code:
If one of the thumbs is clicked, move to the corresponding image.
$('.thumb').click(function (each) {
timeSinceReset = 0;
var childNumber = $(this).index();
currentImage = childNumber + 1; // child numbers are zero-based
var newPos = -(childNumber * 150) + 'px'; // child numbers are zero-based
$('.img_container').animate({left: newPos}, 300);
});
If one of the navigation buttons is clicked, move accordingly. If "back" is clicked, move one image backwards (or to last image if currently on first). If "first" is clicked, move one image forwards (or to first image if currently on last).
$('.nav').click(function(){
timeSinceReset = 0;
if($(this).hasClass('back')){ // Back button
if(currentImage == 1){
currentImage = totalImages;
}else{
currentImage--;
}
}else{ // Forward button
if(currentImage == totalImages){
currentImage = 1;
}else{
currentImage++;
}
}
var newPos = -((currentImage-1) * 150) + 'px';
$('.img_container').animate({left: newPos}, 300);
});
Here is the link to the fiddle example.