Refine width of element
Instead of animating a fixed distance in pixels, the ideal is to calculate the width that each element of the slider occupies and displaces that same measure.
In jQuery you have the method outerWidth()
that returns you to width
+padding
+margin
of the element, thus allowing to obtain the total width that it occupies:
// obter largura do slide com margin e padding incluído
var w = $('.slide').outerWidth(true);
// deslocar essa medida para a direita
$(".slider2").animate({ "margin-left": "+="+w+"px" });
// deslocar essa medida para a esquerda
$(".slider2").animate({ "margin-left": "-="+w+"px" });
var w = $('.slide').outerWidth(true);
$( "#seta-direita" ).click(function() {
if (!$(".slider2").is(':animated'))
{
if ($(".slider2").offset().left < 8)
{
$(".slider2").animate({ "margin-left": "+="+w+"px" });
}
return false;
}
});
$( "#seta-esquerda" ).click(function() {
if (!$(".slider2").is(':animated'))
{
if ($(".slider2").offset().left > -187)
{
$(".slider2").animate({ "margin-left": "-="+w+"px" });
}
return false;
}
});
html {
background-color: #bcbcbc;
}
.slider1 {
overflow: hidden;
height: 50px;
width: 130px;
float: left;
}
.slider2 {
background-color: #FFF;
width: 500px;
}
.slide {
float: left;
background-color: yellow;
margin-left: 11px;
height: 50px;
width: 50px;
}
#seta-esquerda {
cursor: pointer;
font-family: verdana;
font-size: 13px;
}
#seta-direita {
cursor: pointer;
font-family: verdana;
font-size: 13px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="slider1">
<div class="slider2">
<div class="slide">a</div>
<div class="slide">a</div>
<div class="slide">a</div>
<div class="slide">a</div>
<div class="slide">a</div>
</div>
</div>
<div id="setas">
<div id="seta-esquerda">Esquerda</div>
<div id="seta-direita">Direita</div>
</div>
Also in the Jsfiddle.
Optimize code
You can also optimize your code so you don’t use any fixed value for navigational control.
Since scrolling is not supposed to allow more than the first one to move to the right or to allow more to move than the last one when moving to the left, the total number of slides serves as a control.
$('.slide-nav').click(function(){
var $slider = $('.slider2');
if (!$slider.is(':animated')) {
var count = $('.slide').size(),
slidePx = $slider.find(':first-child').outerWidth(true),
slideTo = $(this).attr('class').split(' ')[1],
slidePos = parseInt($slider.css("margin-left")),
offset = (slidePx-slidePos)/slidePx;
if (slideTo=="left" && (offset<count)) {
var direcao = '-';
}
else if (slideTo=="right" && (offset>1)) {
var direcao = '+';
}
else {
return;
}
$(".slider2").animate({ "margin-left": direcao+"="+slidePx+"px" });
}
});
html {
background-color: #bcbcbc;
}
.slider1 {
overflow: hidden;
height: 50px;
width: 130px;
float: left;
}
.slider2 {
background-color: #FFF;
width: 500px;
}
.slide {
float: left;
background-color: yellow;
margin-left: 11px;
height: 50px;
width: 50px;
}
.slide-nav {
cursor: pointer;
font-family: verdana;
font-size: 13px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="slider1">
<div class="slider2">
<div class="slide">A</div>
<div class="slide">B</div>
<div class="slide">C</div>
<div class="slide">D</div>
<div class="slide">E</div>
</div>
</div>
<div id="setas">
<div class="slide-nav left">Esquerda</div>
<div class="slide-nav right">Direita</div>
</div>
Also in the Jsfiddle.
HTML
In HTML there is no optimization, there is a change in triggers navigation to enable jQuery and CSS optimization:
<div class="slider1">
<div class="slider2">
<div class="slide">A</div>
<div class="slide">B</div>
<div class="slide">C</div>
<div class="slide">D</div>
<div class="slide">E</div>
</div>
</div>
<div id="setas">
<!-- mesma classe para ação e segunda classe para direção -->
<div class="slide-nav left">Esquerda</div>
<div class="slide-nav right">Direita</div>
</div>
jQuery
The code in jQuery can then be optimized as detailed below, so that there are no fixed values in the shift control of the slider which contributes to a more flexible application of the same, as well as less or no maintenance when changing the dimensions of the slider and/or their slides:
/*!
* Ao clicar em qualquer seta de navegação
*/
$('.slide-nav').click(function(){
var $slider = $('.slider2'); // colocar em cache o elemento a deslocar
// se não estiver animado
if (!$slider.is(':animated')) {
var count = $('.slide').size(), // total de slides
slidePx = $slider.find(':first-child').outerWidth(true), // largura de um slide
slideTo = $(this).attr('class').split(' ')[1], // para onde deslocar
slidePos = parseInt($slider.css("margin-left")), // posição atual
offset = (slidePx-slidePos)/slidePx; // quantos estão deslocados
// se a deslocar para esquerda e não estamos no último
if (slideTo=="left" && (offset<count)) {
var direcao = '-';
}
// se a deslocar para direita e não estamos no primeiro
else if (slideTo=="right" && (offset>1)) {
var direcao = '+';
}
// caso nenhum dos em cima, não fazer nada
else {
return;
}
// animar para a direção apurada a distância apurada
$(".slider2").animate({ "margin-left": direcao+"="+slidePx+"px" });
}
});
CSS
In CSS the formatting of triggers navigation to become unique which contributes to a code reduction:
.slide-nav {
cursor: pointer;
font-family: verdana;
font-size: 13px;
}
In cases where it is necessary to apply a specific formatting to one of the triggers, can be done as follows:
.slide-nav.left {
/* formatação apenas para "esquerda" */
}
.slide-nav.right {
/* formatação apenas para "direita" */
}