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: /
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');
});
});
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/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');
});
});
Share
Improve this question
edited Apr 15, 2015 at 19:45
w00d
5,60614 gold badges55 silver badges86 bronze badges
asked Apr 15, 2015 at 19:16
joeri claesjoeri claes
431 silver badge4 bronze badges
3 Answers
Reset to default 6I 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./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>
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./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>
I think you just needed to change one little bit on line 10:
if (selectedIndex = activeIndex) {
https://jsfiddle/7yq0jq9s/3/