Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Horizontal scrolling list center when needed

I have to move a horizontal navigation bar when clicked on a link in the list. I have created a JSFiddle to illustrate my problem.

When a user clicks on a link in the list, the list needs to scroll to the left or right. This part is already finished.

When you click on the link, the active link needs to be centered inside the list.

Link to JSFiddle: https://jsfiddle.net/7yq0jq9s/2/

html

<div class="container">
<ul>
    <li class="active"> <a href="#">1</a>

    </li>
    <li> <a href="#">2</a>

    </li>
    <li> <a href="#">3</a>

    </li>
    <li> <a href="#">4</a>

    </li>
    <li> <a href="#">5</a>

    </li>
    <li> <a href="#">6</a>

    </li>
    <li> <a href="#">7</a>

    </li>
    <li> <a href="#">8</a>

    </li>
</ul>

CSS

div.container {
    width: 600px;
    overflow: hidden;
}

ul {
    white-space: nowrap;
}

ul li {
    display: inline-block;
    background: green;
}

ul li a {
    padding: 80px;
    display: block;
    color: white;
    font-weight: bold;
    text-decoration: none;
}

ul li.active {
    background: blue;

}

JS

$(document).ready(function () {
var scrollTo = 0;
$('body').on('click', "a", function () {
    var activeItem = $('li.active');
    var selectedItem = $(this).parent()

    var activeIndex = $('li').index(activeItem);
    var selectedIndex = $('li').index(selectedItem);

    if (selectedIndex > activeIndex) {
        scrollTo -= selectedItem.position().left - activeItem.position().left;
        console.log('Scroll right');
    } else {
        scrollTo += Math.abs(selectedItem.position().left - activeItem.position().left);
        console.log('Scroll left');
        if (scrollTo >= 0) {
            scrollTo = 0;
        }
    }

    $('ul').css('transform', 'translateX(' + scrollTo + 'px)');
    activeItem.removeClass('active');
    selectedItem.addClass('active');

});
});
like image 440
joeri claes Avatar asked Mar 17 '23 10:03

joeri claes


1 Answers

I think it's easier to just get the absolute position of the clicked element and calculate the middle position of the container instead of checking if it needs to scroll left or right:

    var scrollTo = 0;
    $('body').on('click', "a", function () {
        var activeItem = $('li.active');
        var selectedItem = $(this).parent()

        var activeIndex = $('li').index(activeItem);
        var selectedIndex = $('li').index(selectedItem);
        
        scrollTo =- selectedItem.position().left + $('.container').width() / 2 - selectedItem.width() / 2;

        $('ul').css('transform', 'translateX(' + scrollTo + 'px)');
        activeItem.removeClass('active');
        selectedItem.addClass('active');

    });
div.container {

    width: 600px;

    overflow: hidden;

}

ul {

    white-space: nowrap;
    transition: all ease 750ms;
    position:relative;
}

ul li {

    display: inline-block;

    background: green;

}

ul li a {

    padding: 80px;

    display: block;

    color: white;

    font-weight: bold;

    text-decoration: none;

}

ul li.active {

    background: blue;

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="container">
    <ul>
        <li class="active"> <a href="#">1</a>

        </li>
        <li> <a href="#">2</a>

        </li>
        <li> <a href="#">3</a>

        </li>
        <li> <a href="#">4</a>

        </li>
        <li> <a href="#">5</a>

        </li>
        <li> <a href="#">6</a>

        </li>
        <li> <a href="#">7</a>

        </li>
        <li> <a href="#">8</a>

        </li>
    </ul>
</div>
like image 72
Andy Avatar answered Mar 29 '23 17:03

Andy