Animating an image carousel - javascript

I am using and have modified an image slider/carousel and need some guidance one two things. I need to enable it to auto scroll through the images firstly. and secondly I need to have three words underneath that act as controls too. So if I click on one it will take me to that image in the slider with some text underneath?
Example Fiddle
(function() {
var first = $('.item').first(),
last = $('.item').last(),
itemWidth = first.width(),
carousel = $('.carousel');
carousel.prepend(last.clone()).append(first.clone());
carousel.width(itemWidth * $('.item').length);
carousel.css({left: -itemWidth});
$('.prev').on('click', function(e){
e.preventDefault();
carousel.animate({left: '+=' + itemWidth}, 300, function(){
if(Math.abs(carousel.position().left) < 2) {
carousel.css({left: -itemWidth * (carousel.children().length - 2)});
}
});
return false;
});
$('.next').on('click', function(e){
e.preventDefault();
carousel.animate({left: '-=' + itemWidth}, 300, function(){
if(Math.abs(carousel.position().left + itemWidth * (carousel.children().length - 1)) < 2) {
carousel.css({left: -itemWidth});
}
});
return false;
});
})();
so the image illustrates my aim.

Easiest way:
Create variable var autoplay=true;,
Wrap Your function binded to next button click in setInterval, so setInterval Function would be like this one:
setInterval(function(){
if(!autoplay)return;
carousel.animate({left: '-=' + itemWidth}, 300, function(){
if(Math.abs(carousel.position().left + itemWidth * (carousel.children().length - 1)) < 2) {
carousel.css({left: -itemWidth});
}
})
},1000)
and then just add autoPlay toggle handler
$('.autoplayControl').on('click',function(){
autoplay=!autoplay;
})
FIDDLE: http://jsfiddle.net/UWbrQ/197/

Since I hadn't seen the button for autoplay I thought of automatic solution.
In This fiddle the Gallery moves with automatic movement(ten second for image) when the user clicks on pre next buttons auto move stops to restart after 10 seconds of inactivity
For me this is a more elegant solution
<script type="text/javascript">
$(document).ready(function(){
var first = $('.item').first(),
last = $('.item').last(),
itemWidth = first.width(),
carousel = $('.carousel');
console.log(itemWidth)
carousel.prepend(last.clone()).append(first.clone());
carousel.width(itemWidth * $('.item').length);
carousel.css({left: -itemWidth});
//auto start
var giranews = setInterval(function(){move()},5000);
function move(){
carousel.animate({left: '-=' + itemWidth}, 300, function(){
if(Math.abs(carousel.position().left + itemWidth * (carousel.children().length - 1)) < 2) {
carousel.css({left: -itemWidth});
}
});
};
function stopx(){
clearInterval(giranews);
};
function countdown(a) {
var count = a;
timerId = setInterval(function() {
count--;
console.log(count);
if(count == 0) {
clearInterval(timerId);
giranews = setInterval(function(){move()},5000);
};
}, 1000);
};
$('.prev').on('click', function(e){
e.preventDefault();
stopx();
if(typeof timerId!=='undefined'){clearInterval(timerId);countdown(10)}else{countdown(10)}
carousel.animate({left: '+=' + itemWidth}, 300, function(){
if(Math.abs(carousel.position().left) < 2) {
carousel.css({left: -itemWidth * (carousel.children().length - 2)});
}
});
return false;
});
$('.next').on('click', function(e){
e.preventDefault();
stopx();
if(typeof timerId!=='undefined'){clearInterval(timerId);countdown(10)}else{countdown(10)}
carousel.animate({left: '-=' + itemWidth}, 300, function(){
if(Math.abs(carousel.position().left + itemWidth * (carousel.children().length - 1)) < 2) {
carousel.css({left: -itemWidth});
}
});
return false;
});
})
</script>

The Easiest Way Demo Based On your Code with Just Addition of few Lines
Periodically Call the auto function
This function is basically the content inside your click for next slide
Wrap this inside the function and call it with your required interval
setInterval(Auto,5000);
function Auto(){
carousel.animate({left: '-=' + itemWidth}, 300, function(){
if(Math.abs(carousel.position().left + itemWidth * (carousel.children().length - 1)) < 2) {
carousel.css({left: -itemWidth});
}
});
}

Although the aim of this community is not provide complete script to other people, but provide solutions to specific problems, given my love for web galleries in this fiddle there is a gallery with caption below the image with buttons that move images
To accomplish this i had to change the script logic and code is increased slightly
If you like this solution don't forget to flag in green my answer ;) thanks
<script type="text/javascript">
$(document).ready(function(){
var first = $('.item').first(),
last = $('.item').last(),
itemWidth = first.width(),
countx=1,
carousel = $('.carousel');
console.log(carousel.position().left)
carousel.width(itemWidth * $('.item').length);
//auto start
var giranews = setInterval(function(){move()},5000);
function move(){
var left=carousel.position().left
if(left<(itemWidth*($('li.item').length-2)*-1)){carousel.animate({'left':'0px'},300)}else{ carousel.animate({left: '-=' + itemWidth}, 300);}
if(countx===4){countx=1}else{countx++}
showCaption(countx)
};
function stopx(){
clearInterval(giranews);
};
function countdown(a) {
var count = a;
timerId = setInterval(function() {
count--;
console.log(count);
if(count == 0) {
clearInterval(timerId);
giranews = setInterval(function(){move()},5000);
};
}, 1000);
};
//show captions in caption div
function showCaption(countx){
var caption=$('li:eq('+(countx-1)+')').attr('data-caption')
$('#caption').text(caption)
}
showCaption(countx)
$('.prev').on('click', function(e){
e.preventDefault();
stopx();
if(typeof timerId!=='undefined'){clearInterval(timerId);countdown(10)}else{countdown(10)}
if(countx===1){countx=4}else{countx--}
showCaption(countx)
var left=carousel.position().left
if(left===0){carousel.animate({'left':(itemWidth*($('li.item').length-1)*-1)+'px'},300)}else{carousel.animate({left: '+=' + itemWidth}, 300);}
});
$('.next').on('click', function(e){
e.preventDefault();
stopx();
if(typeof timerId!=='undefined'){clearInterval(timerId);countdown(10)}else{countdown(10)}
if(countx===4){countx=1}else{countx++}
showCaption(countx)
var left=carousel.position().left
if(left<(itemWidth*($('li.item').length-2)*-1)){carousel.animate({'left':'0px'},300)}else{carousel.animate({left: '-=' + itemWidth}, 300);}
});
//insert buttons links to image
for(a=0;a<$('li.item').length;a++){
$('<a class="butt">'+(a+1)+'</a>').appendTo('div.buttons')
}
$('a.butt').click(function(e){
e.preventDefault();
stopx();
if(typeof timerId!=='undefined'){clearInterval(timerId);countdown(10)}else{countdown(10)}
var pos=carousel.position().left
carousel.animate({'left': (($(this).index()*itemWidth)*-1)+'px'})
showCaption($(this).index()+1)
countx=$(this).index()+1
})
})
</script>

Related

Hiding Arrows Based on Horizontal Scroll

I'm struggling to make a tiny change in this horizontal scroll code: http://jsfiddle.net/Lpjj3n1e/
I want to make the right button disappear when you scroll all the way to the right (just like it happens with the left button in the original code).
There should be a quick and easy solution but I haven't been able to find one. Please help me and thank you in advance!
$(function() {
var print = function(msg) {
alert(msg);
};
var setInvisible = function(elem) {
elem.css('visibility', 'hidden');
};
var setVisible = function(elem) {
elem.css('visibility', 'visible');
};
var elem = $("#elem");
var items = elem.children();
// Inserting Buttons
elem.prepend('<div id="right-button" style="visibility: hidden;"><</div>');
elem.append(' <div id="left-button">></div>');
// Inserting Inner
items.wrapAll('<div id="inner" />');
// Inserting Outer
debugger;
elem.find('#inner').wrap('<div id="outer"/>');
var outer = $('#outer');
var updateUI = function() {
var maxWidth = outer.outerWidth(true);
var actualWidth = 0;
$.each($('#inner >'), function(i, item) {
actualWidth += $(item).outerWidth(true);
});
if (actualWidth <= maxWidth) {
setVisible($('#left-button'));
}
};
updateUI();
$('#right-button').click(function() {
var leftPos = outer.scrollLeft();
outer.animate({
scrollLeft: leftPos - 200
}, 800, function() {
debugger;
if ($('#outer').scrollLeft() <= 0) {
setInvisible($('#right-button'));
}
});
});
$('#left-button').click(function() {
setVisible($('#right-button'));
var leftPos = outer.scrollLeft();
outer.animate({
scrollLeft: leftPos + 200
}, 800);
});
$(window).resize(function() {
updateUI();
});
});
The main problem seems to be that on clicking the left button there is no function to check whether the arrow should be removed or not.
To test for this we can use the actualWidth which has already been calculated (but it needs to be made more global so its declaration has moved).
There is another small thing which needs rectification - if the maxWidth is greater than the actualWidth there is no need for the arrows. In the code below therefore setVisible has become setVisibleIfNeeded
Here is the revised JS - the original was taken from the jsfiddle. There is a NOTE beside each alteration.
$(function() {
var print = function(msg) {
alert(msg);
};
var setInvisible = function(elem) {
elem.css('visibility', 'hidden');
};
var setVisibleIfNeeded = function(elem) {
if (actualWidth>maxWidth) {//NOTE we don't want to show the arrows if there is space in the div for everything without the need to scroll
elem.css('visibility', 'visible');
}
};
var elem = $("#elem");
var items = elem.children();
// Inserting Buttons
elem.prepend('<div id="right-button" style="visibility: hidden;"><</div>');
elem.append(' <div id="left-button" style="visibility: hidden;">></div>');//NOTE: visibility set to hidden
// Inserting Inner
items.wrapAll('<div id="inner" />');
// Inserting Outer
debugger;
elem.find('#inner').wrap('<div id="outer"/>');
var outer = $('#outer');
var actualWidth=0;//NOTE the declaration is moved up here from the function it was in
var maxwidth=0;//ditto
var updateUI = function() {
maxWidth = outer.outerWidth(true);
actualWidth = 0;
$.each($('#inner >'), function(i, item) {
actualWidth += $(item).outerWidth(true);
});
setVisibleIfNeeded($('#left-button'));
};
updateUI();
$('#right-button').click(function() {
setVisibleIfNeeded($('#left-button'));//NOTE added
var leftPos = outer.scrollLeft();
outer.animate({
scrollLeft: leftPos - 200
}, 800, function() {
debugger;
if ($('#outer').scrollLeft() <= 0) {
setInvisible($('#right-button'));
}
});
});
$('#left-button').click(function() {
setVisibleIfNeeded($('#right-button'));
var leftPos = outer.scrollLeft();
outer.animate({
scrollLeft: leftPos + 200
}, 800,function() {//NOTE function added here to get rid of left button
if (leftPos>=(actualWidth-400)) {setInvisible($('#left-button'));}
});
});
$(window).resize(function() {
updateUI();
});
});

Unable to combine functions in to one file

I have two functions, one to show a gallery of images and one for a smooth scroll up icon. The problem is when I use them separately, both of them works. But when I put them in the same file only the first one works. I can t figure out the problem. I am using jquery-2.0.3
Here is my Code:
$(function() {
$('.demo li').picEyes();
// Caching the Scroll Top Element
// console.log("function move to top");
var ScrollButton = $("#scroll");
$(window).scroll(function() {
// console.log($(this).scrollTop());
if ($(this).scrollTop() >= 50) {
ScrollButton.show()
} else {
ScrollButton.hide();
}
});
// Click On Button To Scroll To Top Of The Page
ScrollButton.click(function() {
$("html,body").animate({
scrollTop: 0
}, 800);
});
});
the code of picEyes function:
(function($){
$.fn.picEyes = function(){
var $obj = this;
var num,zg = $obj.length - 1;
var win_w = $(window).width();
var win_h = $(window).height();
var eyeHtml = '<div class="picshade"></div>'
+'<a class="pictures_eyes_close" href="javascript:;"></a>'
+'<div class="pictures_eyes">'
+'<div class="pictures_eyes_in">'
+'<img src="" />'
+'<div class="next"></div>'
+'<div class="prev"></div>'
+'</div>'
+'</div>'
+'<div class="pictures_eyes_indicators"></div>';
$('body').append(eyeHtml);
$obj.click(function() {
$(".picshade").css("height", win_h);
var n = $(this).find("img").attr('src');
$(".pictures_eyes img").attr("src", n);
num = $obj.index(this);
popwin($('.pictures_eyes'));
});
$(".pictures_eyes_close,.picshade,.pictures_eyes").click(function() {
$(".picshade,.pictures_eyes,.pictures_eyes_close,.pictures_eyes_indicators").fadeOut();
$('body').css({'overflow':'auto'});
});
$('.pictures_eyes img').click(function(e){
stopPropagation(e);
});
$(".next").click(function(e){
if(num < zg){
num++;
}else{
num = 0;
}
var xx = $obj.eq(num).find('img').attr("src");
$(".pictures_eyes img").attr("src", xx);
stopPropagation(e);
popwin($('.pictures_eyes'));
});
$(".prev").click(function(e){
if(num > 0){
num--;
}else{
num = zg;
}
var xx = $obj.eq(num).find('img').attr("src");
$(".pictures_eyes img").attr("src", xx);
stopPropagation(e);
popwin($('.pictures_eyes'));
});
function popwin(obj){
$('body').css({'overflow':'hidden'});
var Pwidth = obj.width();
var Pheight = obj.height();
obj.css({left:(win_w - Pwidth)/2,top:(win_h - Pheight)/2}).show();
$('.picshade,.pictures_eyes_close').fadeIn();
indicatorsList();
}
function updatePlace(obj){
var Pwidth = obj.width();
var Pheight = obj.height();
obj.css({left:(win_w - Pwidth)/2,top:(win_h - Pheight)/2});
}
function indicatorsList(){
var indHtml = '';
$obj.each(function(){
var img = $(this).find('img').attr('src');
indHtml +='<img src="'+img+'"/>';
});
$('.pictures_eyes_indicators').html(indHtml).fadeIn();
$('.pictures_eyes_indicators a').eq(num).addClass('current').siblings().removeClass('current');
$('.pictures_eyes_indicators a').click(function(){
$(this).addClass('current').siblings().removeClass('current');
var xx = $(this).find('img').attr("src");
$(".pictures_eyes img").attr("src", xx);
updatePlace($('.pictures_eyes'));
});
}
function stopPropagation(e) {
e = e || window.event;
if(e.stopPropagation) {
e.stopPropagation();
} else {
e.cancelBubble = true;
}
}
}
})(jQuery);
You should add click event handler, when DOM will be ready, do like this:-
$(function () {
$('.demo li').picEyes();
// Caching the Scroll Top Element
// console.log("function move to top");
//var ScrollButton =ScrollButton.click
var ScrollButton = $("#scroll")
$(window).scroll(function () {
// console.log($(this).scrollTop());
if ($(this).scrollTop() >= 50) {
ScrollButton.show()
} else {
ScrollButton.hide();
}
});
// Click On Button To Scroll To Top Of The Page
ScrollButton.click(function () {
$("html,body").animate({
scrollTop: 0
}, 800);
});
});
I bet both scripts have own ScrollButton element, and while gallery is loaded it owerwrites behaviour of other ScrollButton element.
I put the call of picEyes function outside of the main function and somehow worked !

Converting a manual slideshow to automatic

I followed a tutorial and created a simple manual loop slideshow. I'm trying to make it so it changes the slide automatically even if the prev/next buttons aren't clicked. I tried a crude approach by setting a delay between automatic click events on the "next" button but for some reason it clicks it only once and stops. My js knowledge is very limited and can't figure it out, any input is appreciated. This is the script so far:
$(function() {
var ul = $(".slider ul");
var slide_count = ul.children().length;
var slide_width_pc = 100.0 / slide_count;
var slide_index = 0;
var first_slide = ul.find("li:first-child");
var last_slide = ul.find("li:last-child");
last_slide.clone().prependTo(ul);
first_slide.clone().appendTo(ul);
ul.find("li").each(function(indx) {
var left_percent = (slide_width_pc * indx) + "%";
$(this).css({"left":left_percent});
$(this).css({width:(100 / slide_count) + "%"});
});
ul.css("margin-left", "-100%");
$(".slider .prev").click(function() {
console.log("prev button clicked");
slide(slide_index - 1);
});
$(".slider .next").click(function() {
console.log("next button clicked");
slide(slide_index + 1);
});
function slide(new_slide_index) {
var margin_left_pc = (new_slide_index * (-100) - 100) + "%";
ul.animate({"margin-left": margin_left_pc}, 400, function() {
if(new_slide_index < 0) {
ul.css("margin-left", ((slide_count) * (-100)) + "%");
new_slide_index = slide_count - 1;
}
else if(new_slide_index >= slide_count) {
ul.css("margin-left", "-100%");
new_slide_index = 0;
}
slide_index = new_slide_index
});
}
});
Here is an approach to make it sliding automatically...
But if user clicks on prev/next, it holds the automatic feature for a defined "idle" time.
It need two lines added to your click handlers:
var autoEnabled = true; // ADDED
$(".slider .prev").click(function() {
console.log("prev button clicked");
slide(slide_index - 1);
autoEnabled = false; // ADDED
disabledCount = 0; // ADDED
});
$(".slider .next").click(function() {
console.log("next button clicked");
slide(slide_index + 1);
autoEnabled = false; // ADDED
disabledCount = 0; // ADDED
});
And this to cyclically slide or check if it can re-enable itself.
// ----------------- Automatic sliding interval with "idle time" to re-enable on user click
var idleTime = 5000; // Time without manual click to re-enable automatic sliding.
var autoSlideDelay = 1000; // Time between each slide when automatic.
var disabledCount = 0;
var autoSlide = setInterval(function(){
if(autoEnabled || disabledCount >= idleTime/autoSlideDelay ){
disabledCount = 0;
autoEnabled = true;
slide(slide_index + 1);
}else{
disabledCount++;
}
},autoSlideDelay);
var break_auto_slide = false;
function auto_silde()
{
if(break_auto_slide)
{
break_auto_slide = false;
return;
}
slide(slide_index + 1);
setTimeout(auto_silde,1000 /* time in ms*/);
}
setTimeout will call the function in a specified timeout in milliseconds.
Variable break_auto_slide - set it to true to stop the automatic slide. Next time the function is called it will return without setting a new timer and will reset this variable so auto mode can be turned on again.

Jquery Carousel - calculations if active slide is not one with specific ID then to slide to it.

The question isn't massively helpful I suppose so I'll try to be as clear as I can.
So I have a setup where my header has 4 anchor texts in them. The First part of the body has a custom jquery carousel in it.
What I'm trying to acheive is basically make it so that when any of the four anchor links in the header are clicked they scroll to a specific slide which I have given an ID. The issue I have of course is allowing for the carousel to have any slide active and having the anchor links calculate which slide is active and how much it needs to slide to get to the correct slide.
Here is the jquery for the carousel:
var carousel; // used as the object for the carousel
var carousels = []; // will hold any and all carousels on the page
var preventTimeouts = false;
var intervals = [];
$(document).ready(function () {
carousels.push(new carousel('slideshow_window', 'slidesHolder', '.slide', 920, 10000, 1000, true));
});
carousel = function CarouselSlider(windowName, slideCollectionWrapper,slideCollection, slideWidth, slideChangeInterval, slideChangeSpeed, requireNavButtons) {
// Variables
var slideWidth = slideWidth; // the width of each slide
var slides_array = $(slideCollection).toArray();
var numberOfSlides = slides_array.length;
var slideChangeInterval = slideChangeInterval; // how often the slides will automatically change
var slideChangeSpeed = slideChangeSpeed; // how fast the slides change
var slideIntervalId; // holds the interval event (the event for the next time that the slides should change)
var animating = false; // used to track whether an animation is underway
var currentPosition = 0; // used to highlight the centre image to begin with
var requireNavButtons = requireNavButtons;
var windowName = windowName;
var collectionWrapper = slideCollectionWrapper;
// Carousel
$('#' + windowName).append("<div id=\"" + collectionWrapper + "\"></div>"); // set up the collection wrapper
$('#' + collectionWrapper).css('width', slideWidth * numberOfSlides);
$('#' + collectionWrapper).css('position', "relative");
for (var i = 0; i < slides_array.length; i++) // add items from the collection to the wrapper
$('#' + collectionWrapper).append(slides_array[i]);
$('#' + collectionWrapper).css('left', 920 - slideWidth);
// for (i = 0; i < slides_array.length; i++) { // run one round of the carousel to ensure correct positioning
// currentposition++;
// moveslide(true, true); // set 'forced' to true to disable the animation
// }
function changePosition(forwards) {
forwards ? currentPosition++ : currentPosition--;
moveSlide(forwards, false);
}
function moveSlide(forwards, forced) {
var nextSlide;
animating = true;
if (forwards) {
nextSlide = currentPosition % numberOfSlides;
var t_dur = forced ? 0 : slideChangeSpeed;
$('#' + collectionWrapper).append(slides_array[nextSlide]);
$('#' + collectionWrapper).append(slides_array[nextSlide + 1 > numberOfSlides - 1 ? 0 : nextSlide + 1]); // load the next two slides
$('#' + collectionWrapper)
.animate({ left: "-=" + slideWidth, queue: false },
t_dur,
function () {
$('#' + collectionWrapper + ' ' + slideCollection + ':first').remove();
$('#' + collectionWrapper).css('left', 0);
animating = false;
});
}
else {
nextSlide = (currentPosition % numberOfSlides);
$('#' + collectionWrapper).prepend(slides_array[nextSlide - 1 < 0 ? numberOfSlides + nextSlide : nextSlide]);
$('#' + collectionWrapper).prepend(slides_array[nextSlide < 0 ? numberOfSlides + nextSlide : nextSlide]);
$('#' + collectionWrapper).css('left', 0 - slideWidth); // increase offset to account for prepended slides
$('#' + collectionWrapper)
.animate({ left: "+=" + slideWidth, queue: false },
slideChangeSpeed,
function () {
$('#' + collectionWrapper + ' ' + slideCollection + ':last').remove();
animating = false;
});
}
}
/*
Navigation buttons
*/
$("#next").click(function () {
if (!animating) { // only queue one click at a time
changePosition(true);
}
});
$("#prev").click(function () {
if (!animating) {
changePosition(false);
}
});
$("#prevSearch").click(function () {
if (!animating) {
changePosition(false);
}
});
$("#prevSearch2").click(function () {
$("#modalContainer").hide();
if (!animating) {
changePosition(false);
}
});
}

.next() not working as intended

So,
if($(this).hasClass('active')){
$(this).removeClass('active');
$(this).prev().addClass('active');
}
works fine, it adds the class "active" to this previous div of the same kind.
if($(this).hasClass('active')){
$(this).removeClass('active');
$(this).next().addClass('active');
}
However, adds the class to the next div (as i intend for it to do) for about 0.5 of a second BUT then removes it.
Here's ALL of the jQuery (as per your comments below) - Please do not comment on my horrible code organization
$(window).load(function () {
// Initial variables
var numberSlides = 0;
var currentSlide = 1;
var ready = true;
var pageWidthR = $(document).width() - 352;
var pageWidthL = $(document).width() - 352;
// Update number of slides by number of .slide elements
$('#features-slider .slide').each(function () {
numberSlides++;
});
// Go through each slide and move it to the left of the screen
var i = 0;
$($('#features-slider .slide').get().reverse()).each(function () {
if (i == 0) {
} else {
var newWidth = i * 115;
$(this).css('left', '-' + newWidth + '%');
}
i++;
});
// Animate the first slide in
$('#features-slider .slide:last-child').addClass('active').animate({
left: 0
}, 1500);
// Remove the loading message
$('#loading').fadeOut(1000, function () {
$('#loading').remove();
// Now that we're done - we can show it
$('#features-slider').show();
});
/***** Left and Right buttons *****/
/* Right */
$('#rightbutton').click(function () {
var numberSlides = 0;
$('#features-slider .slide').each(function () {
numberSlides++;
});
var index = $('.slide.active').index() + 1;
if (!$('.slide').is(':animated') && index != 1) {
$('#features-slider .slide').each(function () {
if ($(this).hasClass('active')) {
var currentLeft = $(this).css('left');
var newLeft = parseInt(currentLeft) + 115;
} else {
var currentLeft = $(this).css('left');
var newLeft = parseInt(currentLeft) + 115;
}
$(this).animate({
left: newLeft + '%'
}, 1500);
if ($(this).hasClass('active')) {
$(this).removeClass('active');
$(this).prev().addClass('active');
}
});
}
});
/* Left */
$('#leftbutton').click(function () {
var numberSlides = 0;
$('#features-slider .slide').each(function () {
numberSlides++;
});
var index = $('.slide.active').index() + 1;
if (!$('.slide').is(':animated') && index != numberSlides) {
$('#features-slider .slide').each(function () {
if ($(this).hasClass('active')) {
var currentLeft = $(this).css('left');
var newLeft = parseInt(currentLeft) - 115;
} else {
var currentLeft = $(this).css('left');
var newLeft = parseInt(currentLeft) - 115;
}
$(this).animate({
left: newLeft + '%'
}, 1500);
if ($(this).hasClass('active')) {
$(this).next().addClass('active');
$(this).removeClass('active').not($(this).next());
}
});
}
});
});
$(document).ready(function () {
// Hide the slider and show a loading message while we do stuff and the images / DOM loads - Also disable overflow on the body so no horizontal scrollbar is shown
$('body').css('overflow-x', 'hidden');
$('#features-slider').hide();
$('#loading').html('<center> <img id="loader" src="/wp-content/themes/responsive/library/images/ajax-loader.gif" /> Loading</center>');
});
RESOLVED
New left button function :
$('#leftbutton').click(function(){
var numberSlides = 0;
$('#features-slider .slide').each(function(){
numberSlides++;
});
var index = $('.slide.active').index()+1;
if( !$('.slide').is(':animated') && index != numberSlides ){
var done = false;
$('#features-slider .slide').each(function(){
if($(this).hasClass('active')){
var currentLeft = $(this).css('left');
var newLeft = parseInt(currentLeft)-115;
} else {
var currentLeft = $(this).css('left');
var newLeft = parseInt(currentLeft)-115;
}
$(this).animate({left: newLeft+'%'}, 1500);
if($(this).hasClass('active') && done == false){
$(this).next().addClass('active');
$(this).removeClass('active');
done = true;
}
});
});
If you're iterating forward through the elements, then it should be clear what's going on - you add the "active" class to the next element, and then the next iteration takes it away.
This is just a guess however as you did not post enough code for me (or anybody else) to be sure.
edit — ok now that you've updated the question, it's clear that the guess was correct. The .each() function will iterate forward through the elements. When an element has the "active" class, and the code removes it and adds it to the next element, then on the next iteration the work is undone.
Since you are referencing this and by the behavior you're describing, you are likely iterating a loop for a list of elements. As a result, you are completing the action you want but the next iteration is removing the previous changes due to your usage of removing a class and then adding the class back.
As it stands now, your code does not illustrate how this occurence can be happening.
Update:
As suspected, you seem to be looping as signified by: each(function(){. While iterating through your objects the class is being pushed forward and is not acting as desired. You are stating add the class to the next element, but remove it from the current element, and this behavior continues through your iteration.
On a side note, update your code to call removeClass() on the current object first, before adding it to the next object:
if ($(this).hasClass('active')) {
$(this).removeClass('active').next().addClass('active');
}

Categories