How to make a slider with touch event 'touchmove' with pure Javascript?

Question:

I have been planning to make a slider for my website but what I want is that from a smartphone with a finger slide the slider runs from one slide to the next and all that with pure javascript (without plugins or even Jquery).

This is the JavaScript code that I use to generate the automatic movement of the slider and also the sliding of the slider with a mouse click.

After seeing that it works well I tried to add the touchmove event but apparently it counts each pixel as a total slide of a slider, so if I do a long pass it gives a lot of runs.

Any ideas because it seems to me that I am quite close.

document.addEventListener('DOMContentLoaded', function (){
  var slider400 = document.querySelector('.slider-1'),
      flecha_right = document.querySelector('.right'),
      startx = 0,
      flecha_left = document.querySelector('.left');
  function init(){
    var last_slide = slider400.querySelector('.slide-div:last-child'),
        first_slide = slider400.querySelector('.slide-div:first-child');
    slider400.insertBefore(last_slide.cloneNode(true), first_slide);
    last_slide.remove();
    slider400.style.marginLeft = -100 + "%";
  }
  function avanzar(){
    var slider_margen = parseInt(slider400.style.marginLeft);
    if(-200 < slider_margen){
      slider400.style.marginLeft = slider_margen - 2 + "%";
      setTimeout(function(){
        avanzar();
      },0.1);
    }else{
      mover_slide();			
    };
  };
  function mover_slide(){
    var last_slide = slider400.querySelector('.slide-div:last-child'),
        first_slide = slider400.querySelector('.slide-div:first-child');
    slider400.appendChild(first_slide.cloneNode(true), last_slide);
    first_slide.remove();
    slider400.style.marginLeft = -100 + '%';
  };
  function retroceder(){
    var slider_margen = parseInt(slider400.style.marginLeft);
    if(0 > slider_margen){
      slider400.style.marginLeft = slider_margen + 2 + "%";
      setTimeout(function(){
        retroceder();
      },0.1);
    }else{
      mover_slide_2();
    };
  };
  function mover_slide_2(){
    var last_slide = slider400.querySelector('.slide-div:last-child'),
        first_slide = slider400.querySelector('.slide-div:first-child');
    slider400.insertBefore(last_slide.cloneNode(true), first_slide);
    last_slide.remove();
    slider400.style.marginLeft = -100 + '%';
  };
  flecha_left.addEventListener('click',function(){
    clearInterval(temporizador);
    retroceder();
  });
  flecha_right.addEventListener('click',function(){
    clearInterval(temporizador);
    avanzar();
  });
  slider400.addEventListener('touchmove',function(e){
    var touchobj = e.changedTouches[0];
    var dist = parseInt(touchobj.clientX) - startx;
    if(0 < dist){
      avanzar();
    }else if(0 > dist){
      retroceder();
    }
    e.preventDefault();
    clearInterval(temporizador);
  });
  init();
  var temporizador = setInterval(avanzar,9000);
});
section{
  background:#fff;
  overflow:hidden;
  margin-left:;
}
main section .slider-1{
  width:300%;
  position:relative;
  cursor:-webkit-grab;
  cursor:-moz-grab;
  cursor:-ms-grab;
  cursor:grab;
  box-sizing:content-box;
  display:-moz-flex;
  display:-webkit-flex;
  display:-ms-flex;
  display:flex;
  margin-left:-100%;
}
main section .slider-1:active{
  cursor:-webkit-grabbing;
  cursor:-moz-grabbing;
  cursor:-ms-grabbing;
  cursor:grabbing;
}
main section .slider-1 p{
  color:#900;
  padding-top:1em;
  font-family:'UbuntuCondensed-Regular';
  text-align:center;
}
main section .slider-1 h1{
  font-family:'Montserrat-Bold';
  text-align:center;
  width:95%;
  margin:0 auto;
  padding-bottom:1em;
}
main section .slider-1 .slide-div img{
  width:95%;
  text-align:center;
}
main section .slide-div{
  /*padding:0.5em 0.5em;*/
  width:33.3333%;
  position:relative;
  display:inline-block;
  box-sizing:border-box;
  padding:0;
  text-align:center;
  vertical-align:top;
  margin:0;
}
/*main section .slide-div:first-child{
margin-left:0 !important;
}
main section .slide-div:last-child{
margin-right:0 !important;
}*/
main section .slide-div .borde{
  margin:0.5em 0.5em;
  border:1px solid #c0c0c0;
  border-radius:8px;
  padding:0.5em 0.5em;
  box-sizing:border-box;
}
main section .flecha{
  position:absolute;
  top:60%;
  cursor:pointer;
  z-index:8;
  transform:translateY(20%);
}
main section .right{
  right:0;
}
main section .left{
  left:0;
}
main section .flecha li{
  display:table-cell;
  height:4em;
  width:2em;
  vertical-align:middle;
  text-align:center;
  background:rgba(0,0,0,.3);
  color:rgba(255,255,255,.8);
}
main section .flecha:active li{
  background:rgba(0,0,0,.5);
  color:rgba(255,255,255,1);
}
<main>
  <section>
    <a class="flecha right"><li class="fa fa-arrow-right"></li></a>
    <a class="flecha left"><li class="fa fa-arrow-left"></li></a>
    <div class="slider-1">
      <div class="slide-div slide1">
        <div class="borde">
          <p>Es un hecho:</p>
          <h1>El 96% de usuarios rechazan una página web por su apariencia.</h1>
          <img src="img/slides1/slide1-1.png" alt="" title="">
        </div>
      </div>
      <div class="slide-div slide2">
        <div class="borde">
          <p>Es un hecho:</p>
          <h1>El 96% de usuarios rechazan una página web por su apariencia.</h1>
          <img src="img/slides1/slide1-2.png" alt="" title="">
        </div>
      </div>
      <div class="slide-div slide3">
        <div class="borde">
          <p>Es un hecho:</p>
          <h1>El 96% de usuarios rechazan una página web por su apariencia.</h1>
          <img src="img/slides1/slide1-3.png" alt="" title="">
        </div>
      </div>
    </div>
  </section>
</main>

Answer:

I mark the idea because I don't remember the Javascript syntax very well.

What I have done in an application is:

  1. Take the width of the screen and save it in some variable. (broad)
  2. Detect the initial touch. (x1)
  3. Detect the finishing touch. (x2)
  4. Make the difference. (diff = x2- x1)
  5. Convert the difference to a proportional of the width. (prop = (diff * width) / 100)
  6. Make the comparison of whether it is forward or backward when detecting the end of the touch.

Edit I removed the pseudocode and did a little research and I leave you the code in javascript that would go instead of the listener you have for touchmove:

var ancho = slider400.offsetWidth;
var x1;
var x2;

slider400.addEventListener('touchstart',function(e){
    var touchobj = e.changedTouches[0];
    x1 = parseInt(touchobj.clientX);
    e.preventDefault();
    clearInterval(temporizador);
});
slider400.addEventListener('touchend',function(e){
    var touchobj = e.changedTouches[0];
    x2 = parseInt(touchobj.clientX);

    var dif = x2 - x1;
    var prop = (ancho * dif) / 100;

    if (prop > 20) {
        avanzar();
    } else if (prop < -20) {
        retroceder();
    }

    e.preventDefault();
    clearInterval(temporizador);
});
Scroll to Top