Jquery image cycling issues - javascript

I'm working on a website for a family friend. On it they wanted to have logos from all their associates on one row, that subtly fade to get replaced with additional logos that didn't fit the first time.
To achieve this i've assigned the <img>'s classes, that represent what cycle they should appear in, depending on how many of those images will fit on the row given its current width. This happens in my assignCycleNumbers function.
Then to actually fade them in and out i have another function called cycleAssociates which recursively fades the appropriate classes in and out. Well in theory, however it doesn't seem to be working properly, which is particularly odd because i tested the function here and it works fine. The only difference between them is that now i'm trying to assign the cycle numbers dynamically.
I'm really stumped and could do with some help!
You can see the website hosted here and if you scroll down to the bottom of the content you'll see the logos at the bottom, not behaving as expected. (First cycle appears okay but then subsequent cycles get muddled, more observable if you resize to a smaller screen width).
You can inspect the code thoroughly through your browser but here's everything you need to know, again i'd really appreciate any insight.
EDIT: The whole javascript file as requested. But all the relevant stuff is below:
JS:
//single global variable to represent how many logo cycles there is
var totalCycles = 0;
...
$(window).load(function() {
...
totalCycles = assignCycleNumbers();
cycleAssociates();
});
// window is resized
$(function(){
$(window).resize(function() {
...
totalCycles = assignCycleNumbers();
});
});
...
function cycleAssociates(){
var cycle = 0;
var recursiveCycling = function(cycle, totalCycles){
var currentAssociate = ".cycle" + cycle;
//fade in all img with the current cyle class over a second,
//wait 3 seconds before fading out over a second.
$(currentAssociate).delay(100).fadeIn(1000).delay(3000).fadeOut(1000,
function(){
cycle++;
if(cycle > totalCycles){
cycle = 0;
}
recursiveCycling(cycle, totalCycles);
});
};
recursiveCycling(cycle, totalCycles);
}
function assignCycleNumbers(){
//first remove any old cycle# classes (resized window case)
$('[class*="cycle"]').removeClass( function(unusedIdx,c){
return c.match(/cycle\d+/g).join(" ");
});
//measure div width
var divSpace = $("#bodies").innerWidth();
//assign a cycle number to a number of logos until no more will fit in that div
var cycleNum = 0;
$(".associate").each(function(){
if( divSpace - $(this).width() > 0){
$(this).addClass("cycle" + cycleNum);
divSpace = divSpace - $(this).width();
}
else{ //next logo won't fit current cycle, create next cycle
cycleNum++
$(this).addClass("cycle" + cycleNum);
divSpace = $("#bodies").innerWidth() - $(this).width();
}
});
return cycleNum;
}
html:
<img class="associate" src="IMG/spare.png" alt=""/>
<img class="associate" src="IMG/bcs_professional.jpg" alt="BCS Professional Member"/>
<img class="associate" src="IMG/climate_savers.jpg" alt="Climate Savers Smart Computing"/>
<img class="associate" src="IMG/code_of_conduct.jpg" alt="Data Centres Code Of Conduct Endorser"/>
<img class="associate" src="IMG/spare.gif" alt=""/>
<img class="associate" src="IMG/enistic.gif" alt="Enistic"/>
<img class="associate" src="IMG/greentrac_authorised.png" alt="Greentrac Authorised Reseller"/>
<img class="associate" src="IMG/very_pc.jpg" alt="Very PC Approved"/>
<img class="associate" src="IMG/spare.jpg" alt=""/>
css:
#bodies img.associate{
float: left;
max-width: 120px;
max-height: 80px;
display:none;
}

The issue is that your fadeOut function's callback is being executed even before all elements in the current cycle are faded out. Here's a modified version of your function that works as expected:
function cycleAssociates(){
var cycle = 0;
var recursiveCycling = function(cycle, totalCycles){
var currentAssociate = ".cycle" + cycle;
var n = $(currentAssociate).length; //How many images in current cycle?
$(currentAssociate).each(function() {
$(this).delay(100).fadeIn(1000).delay(3000).fadeOut(1000, function() {
n --;
if(n <= 0) { //current cycle done?
cycle++;
if(cycle > totalCycles){
cycle = 0;
}
recursiveCycling(cycle, totalCycles);
}
});
});
};
recursiveCycling(cycle, totalCycles);
}
To fix the issues that come up on window resize, try replacing your current $(window).resize handler with this:
$(function(){
$(window).resize(function() {
parallelNavbar();
$(".associate").stop(); //if there are any animations, stop 'em
$(".associate").hide(); //hide all associates
totalCycles = assignCycleNumbers(); //update the assignment
cycleAssociates(); //let's get cyclin' again!
});
});
Although I think you have some issues with scrolling. This should resolve the main cycling problem, though -- so I hope that helped!

Related

CSS attribute not always being grabbed by javascript correctly

I am trying to resize the side bars whenever the image changes.
I have my javascript trying grab the height of the image after it changes
var imgHeight = $('#mainImg').height();
var currImg = 0;
var imagesSet = ["1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg", "6.jpg"];
var imageLoc = "images/zalman/"
$('#bttnRight').click(function(){
nextImg();
imgHeight = $('#mainImg').height();
resizeBttn();
});
function nextImg(){
currImg++;
if(currImg>=imagesSet.length){
currImg=0;
}
$('#mainImg').attr("src",imageLoc + imagesSet[currImg]);
}
function resizeBttn() {
$(document).ready(function() {
$('#bttnLeft').css("height",imgHeight);
$('#bttnLeft').css("bottom",imgHeight/2-5);
});
$(document).ready(function() {
$('#bttnRight').css("height",imgHeight);
$('#bttnRight').css("bottom",imgHeight/2-5);
});
}
for some reason, it doesn't always grab the height at the correct time and the side bars will stay at the previous height.
Below I have a JSFiddle that should be working the way my setup is.
Please excuse any inconsistencies and inefficiencies, I am learning.
Just seems weird that it would sometimes grab the height and sometimes not.
I will also be attaching an image of what I see sometimes from the JSfiddle.
I will also attach an image of what I see on my site I am actually writing.
https://jsfiddle.net/6bewkuo5/6/
The issue is because your JavaScript accessing the height of the image before the image as actually been re-rendered in the DOM. Adding a slight delay after assigning the new image source may help things, but...
You actually don't need to use JavaScript to set the height of the buttons
You can achieve what you're after by placing the buttons and image inside of a container with css attribute display: flex.
Like this:
.container {
display: flex;
justify-content: center;
}
<div class="container">
<button class="prev"><</button>
<img src="https://www.avalonwinery.com/wp-content/uploads/2013/12/200x300.gif">
<button class="next">></button>
</div>
Elements within a flex container will automatically fill the height, this includes buttons. Because the images will automatically adjust the height of the container, the buttons will also automatically adjust their height to match.
Run the example below
const images = [
"https://www.avalonwinery.com/wp-content/uploads/2013/12/200x300.gif",
"https://images.sftcdn.net/images/t_app-logo-xl,f_auto/p/ce2ece60-9b32-11e6-95ab-00163ed833e7/1578981868/the-test-fun-for-friends-logo.png",
"https://hiveconnect.co.za/wp-content/uploads/2018/05/800x600.png",
"https://upload.wikimedia.org/wikipedia/commons/b/b5/800x600_Wallpaper_Blue_Sky.png"
]
const imageEl = document.querySelector('img')
let imageIndex = 0
document.querySelector('.prev').addEventListener('click', e => {
if (--imageIndex < 0) { imageIndex = images.length - 1 }
imageEl.src = images[imageIndex]
})
document.querySelector('.next').addEventListener('click', e => {
if (++imageIndex > images.length - 1) { imageIndex = 0 }
imageEl.src = images[imageIndex]
})
body {
background-color: #206a5d;
color: #ffffff;
text-align: center;
}
.container {
display: flex;
justify-content: center;
}
img {
max-width: 50%;
}
<h1>Zalman Build</h1>
<div class="container">
<button class="prev"><</button>
<img src="https://www.avalonwinery.com/wp-content/uploads/2013/12/200x300.gif">
<button class="next">></button>
</div>
The reason is because the resizeBttn code is firing before the image has actually finished downloading and loading into the DOM. I made these changes in your fiddle:
var imgHeight = $('#mainImg').height();
var currImg = 0;
var imagesSet = ["https://www.avalonwinery.com/wp-content/uploads/2013/12/200x300.gif","https://images.sftcdn.net/images/t_app-logo-xl,f_auto/p/ce2ece60-9b32-11e6-95ab-00163ed833e7/1578981868/the-test-fun-for-friends-logo.png", "https://hiveconnect.co.za/wp-content/uploads/2018/05/800x600.png", "https://upload.wikimedia.org/wikipedia/commons/b/b5/800x600_Wallpaper_Blue_Sky.png"];
var imageLoc = "images/zalman/"
$(document).ready(function() {
resizeBttn();
});
$( window ).resize(function() {
/* imgHeight = $('#mainImg').height() */; // commented out; we do this in resizeBttn now
resizeBttn();
});
$('#bttnLeft').click(function(){
prevImg();
/* imgHeight = $('#mainImg').height() */; // commented out; we do this in resizeBttn now
/* resizeBttn() */; // we do this as an `onload` to the image now
});
$('#bttnRight').click(function(){
nextImg();
/* imgHeight = $('#mainImg').height() */; // commented out; we do this in resizeBttn now
/* resizeBttn() */; // we do this as an `onload` to the image now
});
function nextImg(){
currImg++;
if(currImg>=imagesSet.length){
currImg=0;
}
$('#mainImg').attr("src",imagesSet[currImg]);
}
function prevImg(){
currImg--;
if(currImg<0){
currImg=imagesSet.length-1;
}
$('#mainImg').attr("src",imagesSet[currImg]);
}
function resizeBttn() {
imgHeight = $('#mainImg').height()
// removed superfluous doc.ready
$('#bttnLeft').css("height",imgHeight);
$('#bttnLeft').css("bottom",imgHeight/2-5);
$('#bttnRight').css("height",imgHeight);
$('#bttnRight').css("bottom",imgHeight/2-5);
}
And then rewrote your <img /> tag to call resizeBttn on onload:
<img id="mainImg" src="https://www.avalonwinery.com/wp-content/uploads/2013/12/200x300.gif" onload="resizeBttn()"/>
You can see this in action in this fiddle.
Also, a few additional notes on your code, at a glance:
You have some invalid HTML; you're going to want to run that through an HTML validator and fix it, because sometimes it is fine, but sometimes it can lead to all sorts of strange behavior.
You're playing fast and l0ose with global variables in your JS that get set in different functions; it might work OK while the script is small, but as things scale it can quickly become difficult to maintain
You should really avoid abusing the onclick to get link-like behavior from <li> elements; it can impact SEO as well as accessibility. I'd recommend simply using an anchor element inside or outside the <li>
I'd recommend taking a close look at this answer by user camaulay; he makes an excellent point that this may not require JS at all- if a more elegant solution exists w/ CSS it is probably going to be more performant and maintainable.

How can I animate a recently created DOM element in the same function?

I'm working to create an image gallery where the images will be composed by progressively fading in layers one on top of the other to form the final image.
I have many such layers so instead of loading them into many different <img> elements all at once (which would slow load time) I want to start off with a single <img id="base"> and then progressively add image elements with the jQuery .after() method, assign them the relevant sources and fade them in with a delay.
The problem is that I can't attach animations to the newly created elements because (I'm assuming) they don't exist yet within the same function. Here is my code:
HTML
<div id="gallery">
<img id="base" src="image-1.jpg">
</div>
CSS
#base {
opacity: 0;
}
.layers {
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
JavaScript
$(document).ready(function () {
$("#base").animate({opacity: 1}, 300); //fade in base
for (var i = 1; i <= numberOfLayers; i++, gap += 300) {
// create a new element
$("#base").after("<img class='layers' src='" + imgName + ".png'>");
// fade that new element in
$("#gallery").children().eq(i).delay(gap).animate({opacity: '1'}, 300);
}
}
Please note that I've altered my actual code to illustrate this better. I'm fairly new at JavaScript but I'm a quick learner so I'd appreciate if you could tell me what I'm doing wrong and what solution I should pursue.
EDIT: I've included my code inside your JSFiddle (all you need to do is add the library-X.jpg images) : http://jsfiddle.net/pgoevx03/
I've tried to replicate the intent of the code in a cleaner/more flexible way. Please let me know if I can do anything else to help.
I'm not saying this is the best way to do it, but it should be easy enough to understand and use.
The code is untested, but should work just fine. The comments should help you out if there's any compilation error.
Note that I removed the first image in the gallery (with ID "base") from the HTML file. It will be appended the same way as the rest.
// Array storing all the images to append to the gallery
var galleryImages = [
"image-1.jpg",
"image-2.jpg",
"image-3.jpg",
"image-4.jpg",
"image-5.jpg",
"image-6.jpg",
"image-7.jpg",
"image-8.jpg",
"image-9.jpg",
"image-10.jpg"
];
// Index of the image about to be appended
var imgIndex = -1;
var baseID = "base";
$(document).ready(function() {
// Start appending images
appendAllImages();
});
// Append the images, one at a time, at the end of the gallery
function appendAllImages() {
//Move to the next image
imgIndex++;
//We've reached the last image: stop appending
if (imgIndex >= galleryImages.length) return;
//Create image object
var img = $("<img>", {
src: galleryImages[imgIndex],
});
if (imgIndex === 0) { // It's the base!
//Give the base ID to the first image
img.attr("id", baseID);
//Append the image object
$("#gallery").append(img);
} else { // It's a layer!
//Give the base ID to the first image
img.attr("class", "layers");
//Append the image object
$("#" + baseID).after(img);
}
//Fade in the image appended; append the next image once it's done fading in
img.animate({
opacity: 1,
}, 300, appendAllImages);
}

Image slider hover stop and animated transition

I was testing out coding an image slider as a project to learn HTML, CSS and Javascript and it works great. I'd just like to implement a few tweaks on it and was wondering if anyone had any idea on how to do this. Bear in mind, I'm relatively new to this so a few explanatory comments would be greatly appreciated.
Here are the tweaks I'd like to implement: When the user hovers over the image, I'd like the slider to stop on that particular image so the user can look at it for as long as they wish. The slider resumes once the mouse is moved (a topic not explored on any questions here as far as I can find). Another thing I'd like to be able to do is create a more aesthetic fade transition between the images. There are tutorials out there for this but they don't give a lot of context for a beginner like me to implement it. Here's the jsfiddle, as requested, http://jsfiddle.net/7m9j0ttL/
<html>
<head>
<style type="text/css">
.container {
max-width: 400px;
background-color: black;
margin: 0 auto;
text-align: center;
position: relative;
}
.container div {
background-color: white;
width: 100%;
display: inline-block;
display: none;
}
.container img {
width: 100%;
height: auto;
}
</style>
</head>
<body>
<section class="demo">
<div class="container">
<div style="display: inline-block;">
<img src="Chrysanthemum.jpg" width="1024" height="768" />
</div>
<div>
<img src="Desert.jpg" width="1024" height="768" />
</div>
<div>
<img src="Hydrangeas.jpg" width="1024" height="768" />
</div>
</div>
</section>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
$(document).ready(function() {
var currentIndex = 0,
items = $('.container div'),
itemAmt = items.length;
function cycleItems() {
var item = $('.container div').eq(currentIndex);
items.hide();
item.css('display', 'inline-block');
}
var autoSlide = setInterval(function() {
currentIndex += 1;
if (currentIndex > itemAmt - 1) {
currentIndex = 0;
}
cycleItems();
}, 9000);
});
</script>
</body>
</html>
Updated your fiddle
$('.demo').hover(function(){
clearInterval(autoSlide);
},function(){
autoSlide = setInterval(function() {
currentIndex += 1;
if (currentIndex > itemAmt - 1) {
currentIndex = 0;
}
cycleItems();
}, 1000);
});
Added a hover handler to the .demo element. Cleared interval on hover, this would help stop the slide show. And re-set interval on mouseout to start the slideshow per the set interval.
I don't know whether such kind of answer is acceptable for you, but someday, a few years ago, I created my own slider when I was studying jquery.
Looking at your code, I have questions:
1. Why don't you use rather standard functions like fadeIn() and fadeOut() for transitions?
2. Why don't you make a function that will be able to run simultaneously with any number of tags on the page?
A few years ago I had these questions in my head and I came here, to stackoverflow to learn how to do that from other people. And I learnt (not only here, though).
And I created a function that could be loaded anywhere in the code - I studied how to do that. Then I added fade and slide effects there and also any other things...
This function is not really good, but PROBABLY it will sched some light for you in slider creation process. Sorry for many words, check what I have here:
https://jsfiddle.net/7m9j0ttL/3/
I hope my effort is useful for you. If you are going to go further with this and have questions - I would be glad to answer them.
Last comments:
So my main aim was to create function that could be ran like this:
$('.container').okwbSlider({ActAsDefined: 'fadeItOut', SlidingTag: 'div', timeOut: 3000});
so, here you can see that almost ANY tag, containing ANY other tags (with images, text etc in it) can be slided.
in order to make everything slided after some time, I thought that I have to break function in 2 parts: one accepts parameters and the second is called using javascript's setInterval.
So, here's the first one:
(function($){
$.fn.okwbSlider = function(params) {
//outer variables
var tgDfnr = this;
var somevar = this;
var MouseStatevar = 0;
var globalTimervar = (params.globalTimervar != undefined) ? params.globalTimervar : 4000;
var ActAsDefined = (params.ActAsDefined != undefined) ? params.ActAsDefined : "fadeItOut";
var SlidingTag = (params.SlidingTag != undefined) ? params.SlidingTag : 'img';
var numberOfChildren = tgDfnr.children(SlidingTag).length;
// alert('tgDfnr='+tgDfnr+' globalTimervar='+globalTimervar+' ActAsDefined='+ActAsDefined+' numberOfChildren='+numberOfChildren);
//alert("<"+tgDfnr.prop("tagName")+" id="+tgDfnr.attr('id')+">");
if (numberOfChildren > 1){
setInterval(function(){
okwbSlideIt(tgDfnr, ActAsDefined, numberOfChildren, MouseStatevar, SlidingTag);
}, globalTimervar);
}
if(numberOfChildren == 1){
tgDfnr.children(SlidingTag).fadeIn(500, function(){
$(this).addClass('active');
});
}
}
})(jQuery);
it contains everything that needed to run the function in jquery-like way (i.e. placing it after $('.yourANYClassNameOrId'))
and the second one (it's place higher in the text - re-accepts the entered parameters and works with them. It's written not in the really best way (I would write it much better now), but at least I think if you look at it, you can understand something useful.
So, let me know if you have questions and/or I can help you further.

Loop with trigger (which contains animation) not working

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.

Javascript - fading from one item to another pops up with both briefly

I have a testimonials area on my website that fades from one testimonial to another. I'm having an issue where it will fade out too slowly before the next item fades in causing both to come up making a large div making it look ugly.
I want it to fade from one testimonial to another without jumping and flashing with both.
You can see an example here: http://ledragonvert.com/index_test.php
Here is my Javascript code:
function rotate_p() {
if (p_current == p_count) {
p_current = 1;
} else {
p_current++;
}
var $container = $('#container');
$container.find('p').fadeOut();
$container.find('p:nth-child(' + p_current + ')').fadeIn();
}
var p_count;
var p_current = 0;
var p_interval;
$(document).ready(function () {
rotate_p();
p_count = $('#container').find('p').length;
p_interval = setInterval(function () {rotate_p();}, 7000);
});
Thanks you very much for taking your time out to help me.
the solution is CSS based. since the position of the "p" element is static and you call both fadeOut and fadeIn, there is an overlap, as two p elements are inevitably shown together. To get them one on top of the other you need to use absolute positioning on the p element, like so:
#container {
position:relative;
}
#container>p {
position:absolute;
//use any values you wish, to set the testimonial relative to #container:
top:10px;
left:50px;
}

Categories

Resources