yaqoob
yaqoob

Reputation: 1062

jQuery Stop Scrolling at the last element

I'm trying the make the scroll functionality between thumbnails of a gallery. so far the thumbnails are scrolling, but there's a small problem though. If the scroll reaches at the last thumbnail it keeps scrolling towards right direction (if you are scrolling towards right) same happening with the left part.

2nd problem is that, if there's only one thumbnail that is only one li its still scroll.

The jQuery:

var min = left = $('.thumbs ul').offset().left;
var max = $('.thumbs li').length * 160 + min;

$('.right').click(function () {
    var width = $('.thumbs').width();
    if (left > width - max) {
        left -= width;
        if (left < width - max) left = width - max;
        $('.thumbs ul').stop().animate({ 'left': left }, 1000);
    }
});

$('.left').click(function () {
    var width = $('.thumbs').width();
    if (left < min) {
        left += width;
        if (left > min) left = min;
        $('.thumbs ul').stop().animate({ 'left': left }, 1000);
    }
});

The HTML:

 <a class="arrow left">&larr;</a>

<div class="thumbs">
    <ul>
        <li><a href="#"><img src="http://placehold.it/100x100" /></a></li>
        <li><a href="#"><img src="http://placehold.it/100x100" /></a></li>
        <li><a href="#"><img src="http://placehold.it/100x100" /></a></li>
        <li><a href="#"><img src="http://placehold.it/100x100" /></a></li>
        <li><a href="#"><img src="http://placehold.it/100x100" /></a></li>
        <li><a href="#"><img src="http://placehold.it/100x100" /></a></li>
        <li><a href="#"><img src="http://placehold.it/100x100" /></a></li>
        <li><a href="#"><img src="http://placehold.it/100x100" /></a></li>
    </ul>
</div> <a class="arrow right">&rarr;</a>

Here's the JSFiddle

The Solution:

The scrolling should stop when it reaches last thumbnail, from both sides (left and right). and if there's not enough thumbails to scroll for, then it should keep still.

Please help, thank you :)

Upvotes: 2

Views: 1613

Answers (3)

Guffa
Guffa

Reputation: 700840

Calculate the boundaries of the movement, and make sure that it doesn't scroll outside that. As it scrolls to a negative position the minimum is -(sum of images - width of thumbs), and the maximum is 0.

var left = 0;

function scroll(dx) {
    var width = $('.thumbs').width() - 40;
    var min = width - $('.thumbs li').length * 110;
    var l = Math.min(0, Math.max(min, left + width * dx));
    if (l != left) {
        left = l;
        $('.thumbs ul').stop().animate({ 'left': left }, 1000);
    }
}

$('.right').click(function () {
    scroll(-1.0);
});

$('.left').click(function () {
    scroll(1.0);
});

Demo: http://jsfiddle.net/Guffa/k9fxb1hp/3/

Right now it scrolls in steps of the full width of the visible thumbs. You could change the 1.0 into for example 0.8 if you want it to scroll 80% of the width.

Upvotes: 3

Tim Mullen
Tim Mullen

Reputation: 624

You could measure the position of the last li in the list by using the :last-child selector and adjust the max so it reflects the width of the li.

var min = $('.thumbs li').position().left;
var left = $('.thumbs ul:last-child').position().left;
var max = $('.thumbs li').length * 110 - min;

$('.right').click(function () {
    var width = $('.thumbs').width();
    if (left > (width - max)) {
        left -= width;
        if (left < width - max) left = width - max;
        $('.thumbs ul').stop().animate({ 'left': left }, 1000);
    }
});

$('.left').click(function () {
    var width = $('.thumbs').width();
    if (left < min) {
        left += width;
        if (left > min) left = min;
        $('.thumbs ul').stop().animate({ 'left': left }, 1000);
    }
});

See JSFiddle.

Upvotes: 2

omikes
omikes

Reputation: 8543

Have you considered an infinitely looping scroll?

$('.arrow-next').click(function() {
    $(".slider").animate({left: "-=25px"}, 600, function(){
        var left = $(this).css('left');
        $(this).css('left', left == "0px" ? "175px" : left);
    });   
});

$('.arrow-prev').click(function() {
    $(".slider").animate({left: "+=25px"}, 600, function(){
        var left = $(this).css('left');
        $(this).css('left', left == "200px" ? "25px" : left);
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="width: 150px">
    <button type="button" class="arrow-prev">></button>
    <br>
        <div style="display: inline-block; width: inherit; overflow: hidden;">
    <div id="before" style="position: absolute; left: 0px; height: 25px; width: 50px; background-color:white; z-index: 5; vertical-align:middle;"></div>
    <div style="position: absolute; left: 25px; height: 25px; width: 25px; background-color:red; vertical-align:middle;" class="slider"></div>
    <div style="position: absolute; left: 50px; height: 25px; width: 25px; background-color:purple; vertical-align:middle;" class="slider"></div>
    <div style="position: absolute; left: 75px; height: 25px; width: 25px; background-color:blue; vertical-align:middle;" class="slider"></div>
    <div style="position: absolute; left: 100px; height: 25px; width: 25px; background-color:green; vertical-align:middle;" class="slider"></div>
    <div style="position: absolute; left: 125px; height: 25px; width: 25px; background-color:greenyellow; vertical-align:middle;" class="slider"></div>
    <div style="position: absolute; left: 150px; height: 25px; width: 25px; background-color:yellow; vertical-align:middle;" class="slider"></div>
    <div style="position: absolute; left: 175px; height: 25px; width: 25px; background-color:orange; vertical-align:middle;" class="slider"></div>
    <div id="after" style="position: absolute; left: 175px; height: 25px; width: 50px; background-color:white; z-index: 5; vertical-align:middle;"></div>
        </div>
    <br>
    <br>
    <br>    <button type="button" class="arrow-next" style="display:inline-block">
        <</button>
</div>

Upvotes: 1

Related Questions