Calculate the size of the div

3

I'm working on a simple "divs slider" script! Just have a problem, when you start to move left and right it cuts a piece of the divs, I need to move it exactly in a way that it does not cut the divs or appear more than the 2 divs.

Follow script and jsFiddle :

$( "#seta-direita" ).click(function() {
    if (!$(".slider2").is(':animated')){
        if ($(".slider2").offset().left < 300){
            $(".slider2").animate({ "margin-left": "+=65px" });
        }
        return false;
    }
});

$( "#seta-esquerda" ).click(function() {
    if (!$(".slider2").is(':animated')){
        if ($(".slider2").offset().left > -1300){
            $(".slider2").animate({ "margin-left": "-=65px" });
        }
        return false;
    }
});
    
asked by anonymous 09.11.2014 / 01:04

2 answers

3

Determine element width

Instead of animating a fixed distance in pixels, the ideal is to calculate the width that each element of the slider occupies and move that same measurement.

In jQuery you have the outerWidth() method that returns you to width + padding + margin of the element, thus allowing get 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><divclass="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>

Example also in JSFiddle .

Optimize code

You can also optimize your code so that you do not use any fixed value for navigation control.

As a result of moving the slides, it is not possible to move more than the first one when moving to the right or to move more than the last when moving to the left, the total number of slides serves as a control indicator. / p>

$('.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><divclass="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>

Example also in JSFiddle .

HTML

In HTML there is no optimization, there is a change in the triggers navigation to allow optimization of jQuery and CSS:

<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 jQuery code can then be optimized as detailed below, so that there are no fixed values in the slider shift control which contributes to a more flexible application of it less or no maintenance when we change the slider dimensions and / or its 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 becomes unique which contributes to a reduction of code:

.slide-nav {
    cursor: pointer;
    font-family: verdana;
    font-size: 13px;
}

In cases where it is necessary to apply a specific formatting to one of triggers , it can be done as follows:

.slide-nav.left {
  /* formatação apenas para "esquerda" */
}

.slide-nav.right {
  /* formatação apenas para "direita" */
}
    
09.11.2014 / 04:49
2

You're doing the wrong account for the offset:

largura das caixas + margin+left = deslocamento
50px + 11px = 61px

Move +/- 61px , instead of 65px.

View your jsFiddle updated here.

    
09.11.2014 / 01:29