Reputation: 2661
I created a slider with 2 buttons, previous and next, allowing the user to interact with images by going forward or back. If at the first image and previous is fired, the last image is slid left into view. Opposite goes for the end of images case.
The problem I'm having is getting the width of the static images dynamically. When I use the browser console with the exact same selector and methods, I get the correct width, but when i console.log(width), the value is 0, which throws off the animation to slide 0px, hence no interaction.
Here is my JS:
$(document).ready(function () {
//initialize/cache variables needed in program
var sliderUL = $('div.content5').css('overflow', 'hidden').children('ul'); //we can chain variables, for example: we are setting the overflow of an element to hidden, and then we are getting the selected elements of 'ul'.
var imgs = sliderUL.find('img');
var imgWidth = imgs.eq(0).width(); //*SHOULD BE 400, but is 0*
var imgsLen = imgs.length; //5
var current = 1;
var totalImgsWidth = imgsLen * imgWidth; //2000
$('#slider-nav').show().find('button').on('click', function () {
//direction tells us what button is clicked, previous or next. This is needed for moving forward or backwards
var direction = $(this).data('dir'),
loc = imgWidth; //400, the amount needed to shift to new image, which also is the width of an image
//update current value
//if the user clicks on the next button, increase current by 1. else, decrease current by 1, meaning they clicked on the previous button.
(direction === 'next') ? ++current : --current;
//if on the first image and the user presses previous, set current equal to the last image
if (current === 0) {
current = imgsLen;
loc = totalImgsWidth - imgWidth;
//direction next means that it will animate left all the way over to the last image
direction = 'next';
} else if (current - 1 === imgsLen) {
//if the user is on the very last image and they press next, send them back to the first image
current = 1;
//send the img location back to 0 pixels, or the first image
loc = 0;
}
transition(sliderUL, loc, direction);
});
//params: 1.what we are animating 2.the location (margin) we're moving to 3.the direction we are moving
function transition(container, loc, direction) {
var unit; // -= OR +=
//as long as the user isn't trying to reset, the unit is either going to be equal to -= or +=
console.log(loc + ' and ' + direction);
if (direction && loc !== 0) {
//does direction equal next?
//if so, increment left sign, else, increment right sign
if (direction == 'next') {
unit = '-=';
} else {
unit = '+=';
}
// unit = (direction === 'next') ? '-=' : '+=';
}
console.log("you are on image: " + current + ", going " + unit);
container.animate({
//if unit isn't undefined, animate container. else, reset to 0/first img
'margin-left': unit ? (direction + loc) : loc // if true, -=400 OR +=400 if false, reset back to first image at 0
});
}
});
Here is my HTML:
<div class="content5">
<h1 class="content5_h1">Content #5 - The Obligatory Slider</h1>
<ul class="content5_imgs">
<li><img src="imgs/img1.jpg" alt="/" /></li>
<li><img src="imgs/img2.jpg" alt="/" /></li>
<li><img src="imgs/img3.jpg" alt="/" /></li>
<li><img src="imgs/img4.jpg" alt="/" /></li>
<li><img src="imgs/img5.jpg" alt="/" /></li>
</ul>
</div>
<div id="slider-nav">
<button data-dir="prev">Previous</button>
<button data-dir="next">Next</button>
</div>
and finally, here is my CSS:
.content5 {
width:400px;
margin:auto;
height: 368px;
overflow: scroll;
}
.content5_imgs {
width:10000px;
height: 250px;
list-style: none;
padding: 0px;
}
.content5_imgs li {
float:left;
}
#slider-nav {
display: none;
margin-top: 1em;
width:170px;
margin:auto;
padding-top: 10px;
}
#slider-nav button {
padding:1em;
margin-right: 1em;
border-radius:10px;
cursor: pointer;
background-color: Lime;
}
I tried chaining the variables, and I tried even changing the selectors for imgWidth including first() and [0].
Any insight is helpful.
Upvotes: 0
Views: 490
Reputation: 4588
JavaScript will return a width of 0 if the image hasn't loaded yet.
To work around this, any code that depends on content to be loaded, rather than just the DOM being ready, needs to be called on
$(window).load()
Instead of $(document).ready().
More information: Official way to ask jQuery wait for all images to load before executing something
Upvotes: 1