Using jQuery to scroll and reposition images inside a overflow:hidden DIV

Brad Bansner
Brad Bansner used Ask the Experts™
on
On this test page:
http://www.partnersdesign.net/lieverhymanpotter 

I've got a series of 2000px wide images with position:absolute, spaced out at 2000px intervals so they are all lined up left-to-right (but only the left-most image is visible).

In the attached script, every three seconds I animate anything with class=slide 2000px to the left, which slides the whole series to the left.

Then what I am trying to do is reposition the left-most image that just slid off the screen, 12000px to the right, so it put back at the end of the line again.

I think I have close to having this work, but there are some obvious problems. And the positioning is different when you view this in different browsers, which I don't quite understand.

I'm wondering if something about the way I'm doing my callback is incorrect.

Anyway, would appreciate another set of eyes on this. Thank you!

var curImg=1;
var maxImg=6;
var intervalID=setInterval(homeAnimation,3000);

function homeAnimation(){
	console.log('curImg='+curImg);
	console.log('position='+$('#slide'+curImg).position().left);

	$('.slide').animate({left:'-=2000px'}, function(){
		$('#slide'+curImg).animate({right:'+=12000px'});
	});

	if (curImg===maxImg){curImg=1;} else {curImg++;}
};

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Michel PlungjanIT Expert
Top Expert 2009

Commented:
var curImg=1;
var maxImg=6;
var intervalID=setInterval(homeAnimation,3000);

function homeAnimation(){
      console.log('curImg='+curImg);
      console.log('position='+$('#slide'+curImg).position().left);

      $('.slide').animate({left:'-=2000px'});

      if (curImg===maxImg) {
          curImg=1;
          $('#slide'+curImg).animate({right:'+=12000px'});
        }
        else {curImg++;}
};
Brad BansnerWeb Developer

Author

Commented:
That doesn't seem to have really done anything. Safari is still not animating the right distance, nor is Chrome.
Michel PlungjanIT Expert
Top Expert 2009

Commented:
Here ya go.

You can set the position when they slide back instead of sliding them
And move the counter if you want to reset immediately after slide 5

var curImg=1,maxImg,pos=[];

$(function(){
  var intervalID=setInterval(homeAnimation,3000);
  maxImg=$('.slide').length;
  $('.slide').each(function(i) { pos[i] = $(this).position().left});
});

function homeAnimation(){
  $('.slide').animate({left:'-=2000px'});
  if (curImg===maxImg){
    curImg=1;
    $('.slide').each(function(i) {
      $(this).animate({left:pos[i]});
    });
  } else {
    curImg++;
  }
};

Open in new window

Success in ‘20 With a Profitable Pricing Strategy

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Brad BansnerWeb Developer

Author

Commented:
That results in a visible re-shuffle (at the end of the series) that I wanted to avoid.

I tried modifying my original script to adjust the z-index values on the fly (it makes sure that the next image to be animated has a higher z-index than the current one, so when the current one flips back to the end of the line, it slides under instead of over), and that seems to have fixed the slides so it is now a seamless, endless loop. Great!

However, the positioning of the animated slides only seems to work properly in Firefox. In Chrome and Safari, they are offset too far to the left by 226px (this amount varies depending on how wide you have your browser window).

The original positioning of the first slide (before the script is run) is set like this:

#slide1{width:978px;height:481px;top:0px;left:50%;margin-left:-1000px;padding:262px 0px 0px 1022px;}

The DIV is 2000px wide, so I set left to 50% then reduce the left margin by -1000px, which centers it on the screen no matter how wide your browser window is. That works fine in all browsers.

Then, the animation simply moves everything to the left 2000px. The 2nd slide has CSS positioning like this:

#slide2{width:2000px;height:743px;top:0px;left:50%;margin-left:1000px;padding:0px;}

Again, 50% left, plus 1000px this time (positive) on the left margin (because I want it positioned 2000px to the right of the first slide, so they butt up against each other).

Yet, when I do this:

$('.slide').animate({left:'-=2000px'});

...instead of slide #2 being centered on the screen, it is offset to the left. Slide #3 is offset to the left by the same amount... the amount of offset does not change no matter how many times I let the entire series animate.

I don't understand why these values aren't lining up. I'm not sure if this is a CSS problem, or a problem with my script, or just a general browser inconsistency thing and I need to try something else? Or perhaps something is going wrong in the interactions between the jQuery animation and the way I am positioning things in CSS?

I feel like I must be really close to getting this right.

var curImg=1;
var nextImg;
var maxImg=6;
var newZindex;
var intervalID=setInterval(homeAnimation,3000);

function homeAnimation(){
	if (curImg===maxImg){
		nextImg=1;
	} else {
		nextImg=curImg+1;
	}

	newZindex=parseInt($('#slide'+nextImg).css('z-index'))+1;

	console.log('curImg='+curImg);
	console.log('nextImg='+nextImg);
	console.log('position='+$('#slide'+curImg).css('left'));
	console.log('newZindex='+newZindex);
	console.log(' ');

	$('.slide').animate({left:'-=2000px'});
	$('#slide'+nextImg).css('z-index', newZindex);
	$('#slide'+curImg).animate({left:'+=12000px'});

	if (curImg===maxImg){
		curImg=1;
	} else {
		curImg++;
	}
};

Open in new window

Michel PlungjanIT Expert
Top Expert 2009

Commented:
Just take my code, change the slide when counter is max to no slide and you will be fine
Brad BansnerWeb Developer

Author

Commented:
I'm not sure exactly what you mean by that last statement.

And also, the Safari/Chrome positioning still doesn't work.
Michel PlungjanIT Expert
Top Expert 2009

Commented:
$('.slide').each(function(i) {
      $(this).css({left:pos[i]});
    });

Open in new window

Michel PlungjanIT Expert
Top Expert 2009

Commented:
Or css("left",pos[ i])
Brad BansnerWeb Developer

Author

Commented:
I can't get it to work, and positioning still wrong in Safari/Chrome. Here is what I have:

var curImg=1,maxImg,pos=[];

$(function(){
	var intervalID=setInterval(homeAnimation,3000);
	maxImg=$('.slide').length;
	$('.slide').each(function(i){
		pos[i]=$(this).position().left
	});
});

function homeAnimation(){
	$('.slide').animate({left:'-=2000px'});
	if (curImg===maxImg){
		curImg=1;
		$('.slide').each(function(i){
			$(this).css({left:pos[i]});
		});
	} else {
		curImg++;
	}
};

Open in new window

IT Expert
Top Expert 2009
Commented:
This is starting to annoy me.

I think it is worth starting from scratch soon

I thought I had it with this one:

var curImg=0,maxImg,pos=[];

$(function(){
  maxImg=$('.slide').length;
  $('.slide').each(function(i) { pos[i] = $(this).position().left});
  var intervalID=setInterval(homeAnimation,3000);
});

function homeAnimation(){
  $('.slide').animate({left:'-=2000px'});
  curImg++;
  if (curImg===maxImg){
    $('.slide').each(function(i) {
      console.log(curImg,this.id,pos[i])
      $(this).hide().animate({left:pos[i]},function(){$(this).show("slow")});
    });
   curImg=0;
  }
};

Open in new window

Brad BansnerWeb Developer

Author

Commented:
I copied and pasted that code, the scrolling is working:

http://www.partnersdesign.net/lieverhymanpotter

After the last slide, it goes blank, then the 1st slide reappears.

Are you able to view this in either Safari or Chrome? The slides are still not positioned right, after the 1st slide is replaced.
Michel PlungjanIT Expert
Top Expert 2009

Commented:
Yeah I see it and have no idea why
Brad BansnerWeb Developer

Author

Commented:
OK, good enough, you did solve my scrolling problem. Thanks!
Christopher KileSenior Software Analyst

Commented:
http://cssherald.com/153/google-chrome-and-apple-safari-css-only-hack/
http://stackoverflow.com/questions/3795888/extra-padding-on-chrome-safari-webkit-any-ideas

Here's a couple of links that might help you attack the Safari/Chrome issue (not surprising they have the same issue, they are using the same underlying WebKit API).

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial