Reputation: 43
Example: jsfiddle
<style>
#slider-outer {
width: 400px;
overflow: hidden;
}
#slider-inner {
width: 1200px;
overflow: visible;
height: 200px;
position: relative;
}
#slider-inner div {
background: ;
width: 200px;
height: 200px;
float: left;
}
.a{background: red;}
.b{background: green;}
.c{background: blue;}
.d{background: yellow;}
.e{background: grey;}
.f{background: coral;}
.g{background: olive;}
</style>
<div id="slider-outer">
<div id="slider-inner">
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
<div class="e"></div>
<div class="f"></div>
<div class="g"></div>
</div>
</div>
$(document).ready(function(){
$('#slider-inner').click(function(){
var scrollAmount = $(this).width() - $(this).parent().width();
var currentPos = Math.abs(parseInt($(this).css('left')));
var remainingScroll = scrollAmount - currentPos;
var nextScroll = Math.floor($(this).parent().width() / 2);
if (remainingScroll < nextScroll) {
nextScroll = remainingScroll;
}
if (currentPos < scrollAmount) {
$(this).animate({'left':'-=' + nextScroll}, 'slow');
console.log(currentPos)
}
else {
$(this).animate({'left':'0'}, 'fast');
}
});
});
I am going through the process of learning jQuery and some javascript and I came across this example of a simple slider and was going through the lines of code and understand how it all works. I understood everything except for the value that thevar = currentPos
returns to the console.
The value returns 0 on the first click, this confuses me as I think it should be -200px
because the slider-inner is moving -200px
to the left?
Could someone please explain why the variable is returning the value it is to the console?
Thanks
Upvotes: 0
Views: 543
Reputation: 12402
If you look at the CSS rule for #slider-inner
, you'll see that it does not have an explicit left
set.
#slider-inner {
width: 1200px;
overflow: visible;
height: 200px;
position: relative;
}
Because there is no explicit left
value, it defaults to auto
. Since #slider-inner
is relatively positioned and it also has no right
property specified, it receives no offset.
This means left
is effectively 0px
(which is exactly what you get when you when $(this).css('left')
runs on the first click). var currentPos = Math.abs(parseInt($(this).css('left')));
parses that value into an absolute integer, 0
, and stores it in the variable currentPos
. If you look at all the code that comes after that:
var remainingScroll = scrollAmount - currentPos;
var nextScroll = Math.floor($(this).parent().width() / 2);
if (remainingScroll < nextScroll) {
nextScroll = remainingScroll;
}
if (currentPos < scrollAmount) {
$(this).animate({'left':'-=' + nextScroll}, 'slow');
console.log(currentPos)
}
else {
$(this).animate({'left':'0'}, 'fast');
}
});
});
Nothing in there assigns a new value to currentPos
, so the value remains 0
. The zero you get from parsing the string into an integer is a literal, not a reference to the current value of .left
. Even if it were a live reference to the .left
property of the DOM element, it would not be -200
, the .animate
method runs asynchronously, console.log
is called immediately after it, it might have moved a few pixles to the left in the time between calling .animate
and the console output, but certainly not the full 200 pixels.
Upvotes: 0
Reputation: 17735
The console.log
statement is not waiting for the animation to complete and even if it did, currentPos
will remain at 0, as the animation doesn't alter the value of the variable.
A better way to understand the difference is so:
if (currentPos < scrollAmount) {
$(this).animate({'left':'-=' + nextScroll}, 'slow', function(){
console.log("After the animation has completed: " + $(this).css('left'));
});
console.log("Before the animation has completed: " + $(this).css('left'))
}
The third argument to .animate()
is an anonymous function that will be executed when the animation is finished.
This will output:
Before the animation has completed: 0px
After the animation has completed: -200px
Which is hopefully more in line with what you expect.
Upvotes: 4