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:
- Take the width of the screen and save it in some variable. (broad)
- Detect the initial touch. (x1)
- Detect the finishing touch. (x2)
- Make the difference. (diff = x2- x1)
- Convert the difference to a proportional of the width. (prop = (diff * width) / 100)
- 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);
});