Calculate the size of the div

Asked

Viewed 1,413 times

3

I’m working on a simple "Divs slider" script! There’s only one problem, when you start moving left and right it cuts a piece of Divs, I need it to move exactly in a way that it doesn’t cut the Divs or appear more than the 2 Divs.

Follows 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;
    }
});

2 answers

3


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" */
}

2

You are doing the wrong account for displacement:

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

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

See your updated jsFiddle here.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.