[jquery] How to make Bootstrap carousel slider use mobile left/right swipe

DEMO JSSFIDDLE

  <div class="col-md-4">
          <!--Carousel-->
          <div id="sidebar-carousel-1" class="carousel slide" data-ride="carousel">
            <ol class="carousel-indicators grey">
              <li data-target="#sidebar-carousel-1" data-slide-to="0" class="active"></li>
              <li data-target="#sidebar-carousel-1" data-slide-to="1"></li>
              <li data-target="#sidebar-carousel-1" data-slide-to="2"></li>
            </ol>
            <div class="carousel-inner">
              <div class="item active">
                <a href="" data-lightbox="image-1" title="">
                <img src="http://shrani.si/f/3D/13b/1rt3lPab/2/img1.jpg" alt="...">
                </a>
              </div>
              <div class="item">
                <a href="" data-lightbox="image-1" title="">
                <img src="http://shrani.si/f/S/jE/UcTuhZ6/1/img2.jpg" alt="...">
                </a>                  </div>
              <div class="item">
                <a href="" data-lightbox="image-1" title="">
                <img src="http://shrani.si/f/h/To/1yjUEZbP/img3.jpg" alt="...">
                </a>                  </div>
            </div>
             <!-- Controls -->
        <a class="left carousel-control" href="#sidebar-carousel-1" data-slide="prev">
          <span class="glyphicon glyphicon-chevron-left"></span>
        </a>
        <a class="right carousel-control" href="#sidebar-carousel-1" data-slide="next">
          <span class="glyphicon glyphicon-chevron-right"></span>
        </a>
                  </div><!--/Carousel--></div>

What I want to do is to add left/right touch swipe functionality for mobile devices only. How can I do that?

Also, how do I make prev/next buttons, that appear on hover, smaller for mobile/ipad versions?

Thanks

This question is related to jquery html css twitter-bootstrap-3 carousel

The answer is


For anyone finding this, swipe on carousel appears to be native as of about 5 days ago (20 Oct 2018) as per
https://github.com/twbs/bootstrap/pull/25776

https://deploy-preview-25776--twbs-bootstrap4.netlify.com/docs/4.1/components/carousel/


I needed to add this functionality to a project I was working on recently and adding jQuery Mobile just to solve this problem seemed like overkill, so I came up with a solution and put it on github: bcSwipe (Bootstrap Carousel Swipe).

It's a lightweight jQuery plugin (~600 bytes minified vs jQuery Mobile touch events at 8kb), and it's been tested on Android and iOS.

This is how you use it:

$('.carousel').bcSwipe({ threshold: 50 });

See this solution: Bootstrap TouchCarousel. A drop-in perfection for Twitter Bootstrap's Carousel (v3) to enable gestures on touch devices. http://ixisio.github.io/bootstrap-touch-carousel/


Checked solution is not accurate, sometimes mouse-right-click triggers right-swipe. after trying different plugins for swipe i found an almost perfect one.

touchSwipe

i said "almost" because this plugin does not support future elements. so we would have to reinitialize the swipe call when the swipe content is changed by ajax or something. this plugin have lots of options to play with touch events like multi-finger-touch,pinch etc.

http://labs.rampinteractive.co.uk/touchSwipe/demos/index.html

solution 1 :

$("#myCarousel").swipe( {
            swipe:function(event, direction, distance, duration, fingerCount, fingerData) {

                if(direction=='left'){
                    $(this).carousel('next');
                }else if(direction=='right'){
                    $(this).carousel('prev');
                }

            }
        });

solution 2:(for future element case)

function addSwipeTo(selector){
            $(selector).swipe("destroy");
            $(selector).swipe( {
                swipe:function(event, direction, distance, duration, fingerCount, fingerData) {
                    if(direction=='left'){
                        $(this).carousel('next');
                    }else if(direction=='right'){
                        $(this).carousel('prev');
                    }
                }
            });
}
addSwipeTo("#myCarousel");

I'm a bit late to the party, but here's a bit of jQuery I've been using:

$('.carousel').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).carousel('next');
        }
        else if( Math.floor(xClick - xMove) < -sensitivityInPx ){
            $(this).carousel('prev');
        }
    });
    $(this).on('touchend', function(){
        $(this).off('touchmove');
    });
});

No need for jQuery mobile or any other plugins. If you need to adjust the sensitivity of the swipe adjust the 5 and -5. Hope this helps someone.


Same functionality I prefer than using much heavy jQuery mobile is Carousel Swipe. I suggest directly jump in to source code on github, and copy file carousel-swipe.js in to your project directory.

Use swiper events as bellow:

$('#carousel-example-generic').carousel({
      interval: false 
  });

If anyone is looking for the angular version of this answer then I would suggest creating a directive would be a great idea.

NOTE: ngx-bootstrap is used.

import { Directive, Host, Self, Optional, Input, Renderer2, OnInit, ElementRef } from '@angular/core';
import { CarouselComponent } from 'ngx-bootstrap/carousel';

@Directive({
  selector: '[appCarouselSwipe]'
})
export class AppCarouselSwipeDirective implements OnInit {
  @Input() swipeThreshold = 50;
  private start: number;
  private stillMoving: boolean;
  private moveListener: Function;

  constructor(
    @Host() @Self() @Optional() private carousel: CarouselComponent,
    private renderer: Renderer2,
    private element: ElementRef
  ) {
  }

  ngOnInit(): void {
    if ('ontouchstart' in document.documentElement) {
      this.renderer.listen(this.element.nativeElement, 'touchstart', this.onTouchStart.bind(this));
      this.renderer.listen(this.element.nativeElement, 'touchend', this.onTouchEnd.bind(this));
    }
  }

  private onTouchStart(e: TouchEvent): void {
    if (e.touches.length === 1) {
      this.start = e.touches[0].pageX;
      this.stillMoving = true;
      this.moveListener = this.renderer.listen(this.element.nativeElement, 'touchmove', this.onTouchMove.bind(this));
    }
  }

  private onTouchMove(e: TouchEvent): void {
    if (this.stillMoving) {
      const x = e.touches[0].pageX;
      const difference = this.start - x;
      if (Math.abs(difference) >= this.swipeThreshold) {
        this.cancelTouch();
        if (difference > 0) {
          if (this.carousel.activeSlide < this.carousel.slides.length - 1) {
            this.carousel.activeSlide = this.carousel.activeSlide + 1;
          }
        } else {
          if (this.carousel.activeSlide > 0) {
            this.carousel.activeSlide = this.carousel.activeSlide - 1;
          }
        }
      }
    }
  }

  private onTouchEnd(e: TouchEvent): void {
    this.cancelTouch();
  }

  private cancelTouch() {
    if (this.moveListener) {
      this.moveListener();
      this.moveListener = undefined;
    }
    this.start = null;
    this.stillMoving = false;
  }
}

in html:

<carousel appCarouselSwipe>

    ...

</carousel>

Reference


With bootstrap 4.2 its now very easy, you just need to pass the touch option in the carousel div as data-touch="true", as it accepts Boolean value only.

As in your case update bootstrap to 4.2 and paste(Or download source files) the following in exact order :

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

and then add the touch option in your bootstrap carousel div

    <div id="sidebar-carousel-1" class="carousel slide" data-ride="carousel" data-touch="true">

If you don't want to use jQuery mobile as like me. You can use Hammer.js

It's mostly like jQuery Mobile without unnecessary code.

$(document).ready(function() {
  Hammer(myCarousel).on("swipeleft", function(){
    $(this).carousel('next');
  });
  Hammer(myCarousel).on("swiperight", function(){
    $(this).carousel('prev');
  });
});

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to twitter-bootstrap-3

bootstrap 4 responsive utilities visible / hidden xs sm lg not working How to change the bootstrap primary color? What is the '.well' equivalent class in Bootstrap 4 How to use Bootstrap in an Angular project? Bootstrap get div to align in the center Jquery to open Bootstrap v3 modal of remote url How to increase Bootstrap Modal Width? Bootstrap datetimepicker is not a function How can I increase the size of a bootstrap button? Bootstrap : TypeError: $(...).modal is not a function Change arrow colors in Bootstraps carousel How to make a owl carousel with arrows instead of next previous Owl Carousel, making custom navigation Bootstrap change carousel height How can I change the width and height of slides on Slick Carousel? How to make Bootstrap carousel slider use mobile left/right swipe Bootstrap 3 Carousel Not Working Bootstrap carousel multiple frames at once Carousel with Thumbnails in Bootstrap 3.0 Fixed height and width for bootstrap carousel