Reputation: 1230
I am building a simple carousel where the active dots will change active state once the user scrolls horizontally. However, the jQuery left position return value is not changing when I scroll:
li_left = li.position().left; // this is not changing value in console.log()
Any ideas why this is happening? Full code below. If you run you can see that li_left
is not changing in console.
var $div = $('.carousel__list');
var divleft = $div.position().left;
$('.carousel').scroll(function() {
console.log('Scroll started')
$('.carousel li').each(function() {
li = $(this);
li_left = li.position().left;
console.log('li_left', li_left)
if (li_left >= divleft && li_left + li.width() <= divleft + $div.width()) {
$(this).css({
opacity: '1'
})
$(this).siblings('li').css({
opacity: '0.2'
});
return false;
}
});
})
.carousel {
width: 400px;
overflow-x: auto;
}
.carousel__list,
carousel__dots {
list-style: none;
padding: 0;
margin: 0;
}
.carousel__list {
width: 3000px;
position: relative;
}
.carousel li {
display: inline-block;
background-color: grey;
width: 140px;
height: 140px;
margin: 20px;
}
.dots {
margin: 30px auto 50px auto;
display: flex;
padding: 0;
justify-content: center;
}
.dots li {
background-color: blue;
width: 6px;
height: 6px;
border-radius: 50%;
list-style: none;
margin: 0 5px 0 0;
display: inline-block;
opacity: 0.2
}
.dots li.active {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="carousel">
<ul class="carousel__list">
<li>Slide 1</li>
<li>Slide 2</li>
<li>Slide 3</li>
<li>Slide 4</li>
<li>Slide 5</li>
</ul>
</div>
<ol class="dots">
<li class="active"></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ol>
For reference the following is a jsfiddle link I was trying to adapt into my solution. In this example the position().left
is changing:
Upvotes: 0
Views: 1325
Reputation: 1230
Apologies, I was targeting the wrong selector. I must be tired. Below is the correct solution with the active dots changing:
var $div = $('.carousel__list');
var divleft = $div.position().left;
$('.carousel').scroll(function() {
console.log('Scroll started')
$('.carousel__list li').each(function() {
li = $(this);
li_left = li.offset().left;
console.log('li', li)
console.log('li_left', li_left)
if (li_left >= divleft && li_left + li.width() <= divleft + $div.width()) {
var index = $(this).index();
$(this).css({opacity: '1'});
$('.dots li:eq('+index+')').css({opacity: '1'});
$(this).siblings('li').css({opacity: '0.2'});
$('.dots li:eq('+index+')').siblings('li').css({opacity: '0.2'});
return false;
}
});
})
.carousel {
width: 400px;
overflow-x: auto;
}
.carousel__list, carousel__dots {
list-style: none;
padding: 0;
margin: 0;
}
.carousel__list {
width: 3000px;
position: relative;
}
.carousel li {
display: inline-block;
background-color: grey;
width: 200px;
height: 200px;
margin: 20px;
}
.dots {
margin: 30px auto 50px auto;
display: flex;
padding: 0;
justify-content: center;
}
.dots li {
background-color: blue;
width: 6px;
height: 6px;
border-radius: 50%;
list-style: none;
margin: 0 5px 0 0;
display: inline-block;
opacity: 0.2
}
.dots li.active {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="carousel">
<ul class="carousel__list">
<li>Slide 1</li>
<li>Slide 2</li>
<li>Slide 3</li>
<li>Slide 4</li>
<li>Slide 5</li>
</ul>
</div>
<ol class="dots">
<li class="active"></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ol>
Upvotes: 0
Reputation: 1179
I've changed some of your code, take a look:
var moveSpace = $('.carousel__list li').outerWidth();
$('.carousel').scroll(function() {
var activeDot = Math.round(Math.abs($('.carousel__list').position().left / moveSpace)) + 1;
$('.dots li.active').removeClass('active');
$('.dots li:nth-child(' + activeDot + ')').addClass('active');
})
$('.dots li').click(function() {
var id = $(this).data("id");
var scrollSpace = id * moveSpace;
$('.carousel').scrollLeft(scrollSpace);
});
.carousel {
width: 400px;
overflow-x: auto;
}
.carousel__list,
carousel__dots {
list-style: none;
padding: 0;
margin: 0;
}
.carousel__list {
width: 1200px;
position: relative;
}
.carousel li {
display: inline-block;
background-color: grey;
width: 140px;
height: 140px;
margin: 20px;
}
.dots {
margin: 30px auto 50px auto;
display: flex;
padding: 0;
justify-content: center;
}
.dots li {
background-color: blue;
width: 6px;
height: 6px;
border-radius: 50%;
list-style: none;
margin: 0 5px 0 0;
display: inline-block;
opacity: 0.2;
cursor: pointer;
}
.dots li.active {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="carousel">
<ul class="carousel__list">
<li>Slide 1</li>
<li>Slide 2</li>
<li>Slide 3</li>
<li>Slide 4</li>
<li>Slide 5</li>
</ul>
</div>
<ol class="dots">
<li class="active" data-id="0" ></li>
<li data-id="1" ></li>
<li data-id="2" ></li>
<li data-id="3" ></li>
<li data-id="4" ></li>
</ol>
Also JS Fiddle demo: http://jsfiddle.net/Vy33z/105/
Upvotes: 1
Reputation: 89
use offset instead of position. position.left is not changing, because the li element does not change his position compared to his parent.
off = li.offset();
li_left = off.left;
Upvotes: 0