JavaScript/jQuery image slider issue - javascript

Fiddle: https://jsfiddle.net/8na2n5L2/
I'm trying to create an image slider, but for some reason just can't wrap my head around why this isn't working. I'm basically trying to create a slider where images come in from the right (off screen), and the center image gets pushed to the left (off screen). Then, when it comes time for that left image to go to the center again, it quickly goes back to the right again before going to the center.
jQuery(document).ready (function () {
var images = [];
//store the images in an array
jQuery('.main-image-slider').each( function () {
images.push(jQuery(this));
});
var i = 0;
var max = images.length - 1;
setInterval( function () {
if ( i > max) {
i = 0;
}
images[i].removeClass('main-image-slider-left').addClass('main-image-slider-right').delay(100).queue(function () {
images[i].removeClass('main-image-slider-right').addClass('main-image-slider-center').dequeue();
i++;
});
if (images[i - 1]) {
images[i - 1].removeClass('main-image-slider-center').addClass('main-image-slider-left');
}
}, 3000);
});

I get this console error "Uncaught TypeError: Cannot read property
'removeClass' of undefined".
This error is because the code will run i++ first, then run images[i].removeClass('main-image-slider-right')....
images[i].removeClass('main-image-slider-left').addClass('main-image-slider-right').delay(100).queue(function() {
// the 'i' is already added 1, so it may equal images[max], so you got that error
images[i].removeClass('main-image-slider-right').addClass('main-image-slider-center').dequeue();
});
You can move i++ into queue:
images[i].removeClass('main-image-slider-left').addClass('main-image-slider-right').delay(100).queue(function() {
images[i].removeClass('main-image-slider-right').addClass('main-image-slider-center').dequeue();
// after all the animation is done, at the end of queue update 'i'.
i++;
});
You can try this.
Note: don't forget to remove the i++ at the end of code.
Update
Update the jsfiddle code
At the edge of slides it will not update the class with if (images[i - 1]), wee need always update the class of previous slide. So I changed the code to
images[i == 0 ? images.length - 1 : i - 1].removeClass('main-image-slider-center').addClass('main-image-slider-left');

Related

JSFiddle Slider code not working in browser

I'm a little lost. I have used this JSFiddle code regarding a solution to my problem. http://jsfiddle.net/f8d1js04/2/ (thank you MartinWebb) - and the question(for context) is posed here; Add Fade Effect in Slideshow (Javascript) - MartinWebb's solution is towards the bottom.
Essentially I am rendering a slider onto the page. Now when I put random image links into the imgArray on the JSFiddle, it behaves perfectly. However, when I do it on my page and in my files (in the dom), after the last image, there is a gap - time w/ no image showing, and then it continues to run. How do I get rid of this momentary gap?
Also any ideas on what could be causing this to happen on the browser instead of the JSFiddle?
Sincerely thank you for any help & assistance!
var curIndex = 0,
imgDuration = 3000,
slider = document.getElementById("slider"),
slides = slider.childNodes; //get a hook on all child elements, this is live so anything we add will get listed
imgArray = [
'http://placehold.it/300x200',
'http://placehold.it/200x100',
'http://placehold.it/400x300'];
//
// Dynamically add each image frame into the dom;
//
function buildSlideShow(arr) {
for (i = 0; i < arr.length; i++) {
var img = document.createElement('img');
img.src = arr[i];
slider.appendChild(img);
}
// note the slides reference will now contain the images so we can
access them
}
//
// Our slideshow function, we can call this and it flips the image instantly, once it is called it will roll
// our images at given interval [imgDuration];
//
function slideShow() {
function fadeIn(e) {
e.className = "fadeIn";
};
function fadeOut(e) {
e.className = "";
};
// first we start the existing image fading out;
fadeOut(slides[curIndex]);
// then we start the next image fading in, making sure if we are at the end we restart!
curIndex++;
if (curIndex == slides.length) {
curIndex = 0;
}
fadeIn(slides[curIndex]);
// now we are done we recall this function with a timer, simple.
setTimeout(function () {
slideShow();
}, imgDuration);
};
// first build the slider, then start it rolling!
buildSlideShow(imgArray);
slideShow();

How to evenly time fading transitions?

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);
}

How to reinitialise jScrollPane without losing features added in the first initialisation?

I'm having trouble with jScrollPane's reinitialise() method. Whenever I call it, stuff that I implemented in the first initialisation stops working...
In my current code, I'm doing something like this:
$('.scrollable').each(function(){
var e = $(this),
parent = e.parent();
e.jScrollPane({
// parameters
});
var api = e.data('jsp'),
arrowup = e.find('.jspArrowUp'),
arrowdw = e.find('.jspArrowDown');
if ( api.getIsScrollableV() ) {
e.addClass('scrolled-top');
parent.addClass('scroll-parent');
}
e.scroll(function(){
var scrbef = api.getContentPositionY(),
scrmax = api.getContentHeight() - this.clientHeight,
scraft = scrmax - scrbef,
dlayup = (scrbef - 220)/100,
dlaydw = (scraft - 220)/100,
opacup = dlayup > 1 ? 1 : dlayup < 0 ? 0 : dlayup,
opacdw = dlaydw > 1 ? 1 : dlaydw < 0 ? 0 : dlaydw;
if ( scrbef === 0 ) {
e.addClass('scrolled-top').removeClass('scrolled-bot');
} else if ( scraft === 0 ) {
e.addClass('scrolled-bot').removeClass('scrolled-top');
} else {
e.removeClass('scrolled-top scrolled-bot');
}
arrowup.css('opacity', opacup);
arrowdw.css('opacity', opacdw);
});
So far, so good. What that does is:
initialise jScrollPane on the .scrollable elements
depending on the content position, add or remove scrolled-top or scrolled-bot classes.
controls the opacity of the arrows depending on the content's position (there's a lot of padding at the top and bottom, so I only want the arrows to appear when the actual content has reached the border of the screen).
Right after that bit, I have this:
var throttleTimeout;
$(window).resize(function(){
if ( !throttleTimeout ) {
throttleTimeout = setTimeout( function(){
api.reinitialise();
throttleTimeout = null;
}, 500
);
}
});
$('.deployer').click(function(e){
api.reinitialise();
});
});
Now, that is pretty straightforward; the code to reinitialise when the window is resized comes straight from the documentation.
However, as soon as either reinitialise() is called, so after resizing the window or clicking on the .deployer element, the previous code which controlled the arrows' opacity stops working – although, weirdly enough, the scrolled-top and scrolled-bot classes still get added or removed properly.
Does anyone know what might be causing this behaviour and how to fix it?
Cheers.
Found what was happening.
Whenever you reinitialise, basically everything gets resetted, so the elements that were previously stored in arrowup and arrowdw don't exist anymore. Adding
var arrowup = e.find('.jspArrowUp'),
arrowdw = e.find('.jspArrowDown');
again after each reinitialise() made the trick.

Simple loop for images

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);

JQuery image slider and CSS transition works only once

I'm trying to learn jQuery plugins. I'm creating a image sliding plugin. This is how I've developed so far.
(function($){
$.imageSlider = function(selector, settings) {
//settings
var config = {
'delay':2000,
'speed':500
};
if(settings) {
$.extend(config, settings);
}
//vars
var obj = $(selector);
obj.children('img').css('transition','width 2s, height 2s, transform 2s');
var image = obj.children('img');
var count = image.length;
var i = 0;
image.eq(0).show(); //first image showing
//begin the image loop
setInterval ( function() {
image.eq(i).fadeOut(config.speed);
i = (i+1 == count) ? 0 : i+1;
image.eq(i).fadeIn(config.speed);
image.eq(i).css("transform","rotate(360deg)");
}, config.delay
);
return this;
}
})(jQuery);
But my the issue is the rotation happens only once cycle.
JSFiddle http://jsfiddle.net/va45D/1/
After all 3 images loaded as the way I wanted, then It doesn't applies the transition.
Please help me to understand whats happening here.
Hie Shan,
I can reproduce your problem, you're right. After the second time that you rotate your images they will not rotate anymore. I'm using Firefox 25.
To solve you problem I made these updates:
setInterval( function() {
image.eq(i).fadeOut(config.speed);
image.eq(i).css("transform","rotate(0deg)");
i = (i+1 == count) ? 0 : i+1;
image.eq(i).fadeIn(config.speed);
image.eq(i).css("transform","rotate(360deg)");
}, config.delay
);
When your loop over, the element keeps the same value at the end of the loop, so when your run it for the first time your have all your img elements at 0deg, at the end you transform them to 360deg position. The next time that you run your loop (this explain the problem that you have on your 2nd time), all your images starts on 360deg. If you rotate 360deg to 360deg you have the same position because there is no interval between the actual position and the new one. This can be really visible if you update your code to 45deg, as you can see on this fiddle.
Before start the process I defined a transformation that returns your element to 0 degrees. Maybe this solution solves your problem.
Here is the JSFiddle
Thanks!

Categories

Resources