Home > other >  How to make image slider respond to thumb swipe
How to make image slider respond to thumb swipe

Time:06-07

Hi I am using the basic W3 slideshow layout but It is not very good for the mobile version of my site.

I searched very hard to find a solution to this but it's always download some plug-in to make it work or something that doesn't respond very well to swipes

$('.slider').on('touchstart', function(event) {
  const xClick = event.originalEvent.touches[0].pageX;
  
  $(this).one('touchmove', function(event) {
    const xMove = event.originalEvent.touches[0].pageX;
    const sensitivityInPx = 5;

    if (Math.floor(xClick - xMove) > sensitivityInPx) {
      $(this).slider('next');
    } 
    else if (Math.floor(xClick - xMove) < -sensitivityInPx) {
      $(this).slider('prev');
    }
  });
  
  $(this).on('touchend', function() {
    $(this).off('touchmove');
  });
});

let slideIndex = 1;
showSlides(slideIndex);

function plusSlides(n) {
  showSlides(slideIndex  = n);
}

function currentSlide(n) {
  showSlides(slideIndex = n);
}

function showSlides(n) {
  let i;
  let slides = document.getElementsByClassName("mySlides");
  let dots = document.getElementsByClassName("dot");
  
  if (n > slides.length) {
    slideIndex = 1
  }
  
  if (n < 1) {
    slideIndex = slides.length
  }
  
  for (i = 0; i < slides.length; i  ) {
    slides[i].style.display = "none";
  }
  
  for (i = 0; i < dots.length; i  ) {
    dots[i].className = dots[i].className.replace(" active", "");
  }
  
  slides[slideIndex - 1].style.display = "block";
  dots[slideIndex - 1].className  = " active";
}
* {
  box-sizing: border-box
}

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
}

body {
  margin: 0;
  font-family: Arial, Helvetica, sans-serif;
}

.mySlides {
  display: none
}

img {
  vertical-align: middle;
}

/* Slideshow container */

.slideshow-container {
  padding: 10px;
  max-width: 1000px;
  position: relative;
  margin: auto;
  -webkit-overflow-scrolling: touch;
}

/* Next & previous buttons */

.prev,
.next {
  cursor: pointer;
  position: absolute;
  top: 50%;
  width: auto;
  padding: 16px;
  margin-top: -22px;
  color: white;
  font-weight: bold;
  font-size: 18px;
  transition: 0.6s ease;
  border-radius: 0 3px 3px 0;
  user-select: none;
}

/* Position the "next button" to the right */

.next {
  right: 0;
  border-radius: 3px 0 0 3px;
}

/* On hover, add a black background color with a little bit see-through */

.prev:hover,
.next:hover {
  background-color: rgba(0, 0, 0, 0.8);
}

/* Caption text */

.text {
  color: #f2f2f2;
  font-size: 15px;
  padding: 8px 12px;
  position: absolute;
  bottom: 8px;
  width: 100%;
  text-align: center;
}

/* Number text (1/3 etc) */

.numbertext {
  color: #f2f2f2;
  font-size: 12px;
  padding: 8px 12px;
  position: absolute;
  top: 0;
}

/* The dots/bullets/indicators */

.dot {
  cursor: pointer;
  height: 15px;
  width: 15px;
  margin: 0 2px;
  background-color: #bbb;
  border-radius: 50%;
  display: inline-block;
  transition: background-color 0.6s ease;
}

.active,
.dot:hover {
  background-color: #717171;
}

/* Fading animation */

.fade {
  animation-name: fade;
  animation-duration: 1.5s;
}

@keyframes fade {
  from {
    opacity: .4
  }
  to {
    opacity: 1
  }
}

/* On smaller screens, decrease text size */

@media only screen and (max-width: 300px) {
  .prev,
  .next,
  .text {
    font-size: 11px
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="slider" >
  <!-- images -->
  <div >
    <!-- <div >1 / 3</div> -->
    <img src="http://upload.wikimedia.org/wikipedia/commons/7/73/Lion_waiting_in_Namibia.jpg" style="width:100%">
    <div >Caption Text</div>
  </div>

  <div >
    <img src="http://upload.wikimedia.org/wikipedia/commons/7/73/Lion_waiting_in_Namibia.jpg" style="width:100%">
  </div>

  <div >
    <img src="http://upload.wikimedia.org/wikipedia/commons/7/73/Lion_waiting_in_Namibia.jpg" style="width:100%">
  </div>

  <div >
    <img src="http://upload.wikimedia.org/wikipedia/commons/7/73/Lion_waiting_in_Namibia.jpg" style="width:100%">
  </div>

  <a  onclick="plusSlides(-1)">❮</a>
  <a  onclick="plusSlides(1)">❯</a>
</div>
<br>

<div style="text-align:center">
  <!-- dots-->
  <span  onclick="currentSlide(1)"></span>
  <span  onclick="currentSlide(2)"></span>
  <span  onclick="currentSlide(3)"></span>
  <span  onclick="currentSlide(4)"></span>
</div>

CodePudding user response:

Like i wrote in the comments, you have two typos: $(this).one('touchmove and .slider, which has to be $(this).on('touchmove and #slider.


But the main problem is your function slider(), which isn't defined. But you can use the function plusSlides(), that you are already using for the next and prev buttons.

Furthermore the touchmove event is firing very often until the touchend event is fired. Therefor the function plusSlides() is called multiple times. To fix this, stop the touchmove event listener when the function plusSlides() is called.

Working example:

$('#slider').on('touchstart', function(event) {
  const xClick = event.originalEvent.touches[0].pageX;

  $(this).on('touchmove', function(event) {
    const xMove = event.originalEvent.touches[0].pageX;
    const sensitivityInPx = 5;

    if (Math.floor(xClick - xMove) > sensitivityInPx) {
      plusSlides(1);
      $(this).off('touchmove');
    } 
    else if (Math.floor(xClick - xMove) < -sensitivityInPx) {
      plusSlides(-1);
      $(this).off('touchmove');
    }
  });
});

let slideIndex = 1;
showSlides(slideIndex);

function plusSlides(n) {
  showSlides(slideIndex  = n);
}

function currentSlide(n) {
  showSlides(slideIndex = n);
}

function showSlides(n) {
  let i;
  let slides = document.getElementsByClassName("mySlides");
  let dots = document.getElementsByClassName("dot");

  if (n > slides.length) {
    slideIndex = 1
  }
  if (n < 1) {
    slideIndex = slides.length
  }

  for (i = 0; i < slides.length; i  ) {
    slides[i].style.display = "none";
  }

  for (i = 0; i < dots.length; i  ) {
    dots[i].className = dots[i].className.replace(" active", "");
  }

  slides[slideIndex - 1].style.display = "block";
  dots[slideIndex - 1].className  = " active";
}
* {
  box-sizing: border-box
}

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
}

body {
  margin: 0;
  font-family: Arial, Helvetica, sans-serif;
}

.mySlides {
  display: none
}

img {
  vertical-align: middle;
}

/* Slideshow container */

.slideshow-container {
  padding: 10px;
  max-width: 1000px;
  position: relative;
  margin: auto;
  -webkit-overflow-scrolling: touch;
}

/* Next & previous buttons */

.prev,
.next {
  cursor: pointer;
  position: absolute;
  top: 50%;
  width: auto;
  padding: 16px;
  margin-top: -22px;
  color: white;
  font-weight: bold;
  font-size: 18px;
  transition: 0.6s ease;
  border-radius: 0 3px 3px 0;
  user-select: none;
}

/* Position the "next button" to the right */

.next {
  right: 0;
  border-radius: 3px 0 0 3px;
}

/* On hover, add a black background color with a little bit see-through */

.prev:hover,
.next:hover {
  background-color: rgba(0, 0, 0, 0.8);
}

/* Caption text */

.text {
  color: #f2f2f2;
  font-size: 15px;
  padding: 8px 12px;
  position: absolute;
  bottom: 8px;
  width: 100%;
  text-align: center;
}

/* Number text (1/3 etc) */

.numbertext {
  color: #f2f2f2;
  font-size: 12px;
  padding: 8px 12px;
  position: absolute;
  top: 0;
}

/* The dots/bullets/indicators */

.dot {
  cursor: pointer;
  height: 15px;
  width: 15px;
  margin: 0 2px;
  background-color: #bbb;
  border-radius: 50%;
  display: inline-block;
  transition: background-color 0.6s ease;
}

.active,
.dot:hover {
  background-color: #717171;
}

/* Fading animation */

.fade {
  animation-name: fade;
  animation-duration: 1.5s;
}

@keyframes fade {
  from {
    opacity: .4
  }
  to {
    opacity: 1
  }
}

/* On smaller screens, decrease text size */

@media only screen and (max-width: 300px) {
  .prev,
  .next,
  .text {
    font-size: 11px
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="slider" >
  <!-- images -->

  <div >
    <!-- <div >1 / 3</div> -->
    <img src="http://upload.wikimedia.org/wikipedia/commons/7/73/Lion_waiting_in_Namibia.jpg" style="width:100%">
    <div >Caption Text</div>
  </div>

  <div >
    <img src="http://upload.wikimedia.org/wikipedia/commons/7/73/Lion_waiting_in_Namibia.jpg" style="width:100%">
  </div>

  <div >
    <img src="http://upload.wikimedia.org/wikipedia/commons/7/73/Lion_waiting_in_Namibia.jpg" style="width:100%">
  </div>

  <div >
    <img src="http://upload.wikimedia.org/wikipedia/commons/7/73/Lion_waiting_in_Namibia.jpg" style="width:100%">
  </div>

  <a  onclick="plusSlides(-1)">❮</a>
  <a  onclick="plusSlides(1)">❯</a>

</div>
<br>

<div style="text-align:center">
  <!-- dots-->
  <span  onclick="currentSlide(1)"></span>
  <span  onclick="currentSlide(2)"></span>
  <span  onclick="currentSlide(3)"></span>
  <span  onclick="currentSlide(4)"></span>
</div>

  • Related