Skip to content

Instantly share code, notes, and snippets.

@eristoddle
Forked from stovak/gist:1343996
Last active July 30, 2020 14:00
Show Gist options
  • Save eristoddle/5011106 to your computer and use it in GitHub Desktop.
Save eristoddle/5011106 to your computer and use it in GitHub Desktop.
Add Swipe to Drupal Views Slideshow and jQuery Cycle
Drupal.settings.isTouchDevice = function() {
return "ontouchstart" in window;
}
if ( Drupal.settings.isTouchDevice() ) {
Drupal.behaviors.jQueryMobileSlideShowTouchAdvance = {
attach: function(context, settings) {
self = Drupal.behaviors.jQueryMobileSlideShowTouchAdvance;
jQuery.each(jQuery(".views_slideshow_cycle_main.viewsSlideshowCycle-processed"), function(idx, value) {
value.addEventListener("touchstart", self.handleTouchStart);
jQuery(value).addClass("views-slideshow-mobile-processed");
})
jQuery(self).bind("swipe", self.handleSwipe);
},
detach: function() { }, original: { x: 0, y: 0},
changed: { x: 0, y: 0}, direction: { x: "", y: "" }, fired: false,
handleTouchStart: function(evt) {
self = Drupal.behaviors.jQueryMobileSlideShowTouchAdvance;
if (evt.touches) {
if (evt.targetTouches.length != 1) { return false; } // don't respond to gestures
if (evt.touches.length) { evt.preventDefault(); evt.stopPropagation() }
self.original = { x: evt.touches[0].clientX, y: evt.touches[0].clientY }
self.target = jQuery(this).attr("id").replace("views_slideshow_cycle_main_", "");
Drupal.viewsSlideshow.action({ "action": "pause", "slideshowID": self.target });
evt.target.addEventListener("touchmove", self.handleTouchMove);
evt.target.addEventListener("touchend", self.handleTouchEnd);
}
},
handleTouchMove: function(evt) {
self = Drupal.behaviors.jQueryMobileSlideShowTouchAdvance;
self.changed = {
x: (evt.touches.length) ? evt.touches[0].clientX: evt.changedTouches[0].clientX,
y: (evt.touches.length) ? evt.touches[0].clientY: evt.changedTouches[0].clientY
};
h = parseInt(self.original.x - self.changed.x), v = parseInt(self.original.y - self.changed.y);
if (h !== 0) { self.direction.x = (h < 0) ? "right":"left"; }
if (v !== 0) { self.direction.y = (v < 0) ? "up": "down"; }
if ((h+v) != 0) {
jQuery(self).trigger("swipe");
}
},
handleTouchEnd: function(evt) {
self = Drupal.behaviors.jQueryMobileSlideShowTouchAdvance;
evt.target.removeEventListener("touchmove", self.handleTouchMove);
evt.target.removeEventListener("touchend", self.handleTouchEnd);
self.fired = false;
},
handleSwipe: function(evt) {
self = Drupal.behaviors.jQueryMobileSlideShowTouchAdvance;
if (evt != undefined && self.fired == false) {
Drupal.viewsSlideshow.action({ "action": (self.direction.x == "left")?"nextSlide":"previousSlide", "slideshowID": self.target });
self.fired = true; //only fire advance once per touch
}
}
}
}
@sardbaba
Copy link

@stillfire - it seems to me that if you add this into a javascript file into your theme, you should get it working.
@pglatz - why (and how) you should add a click event on a touch device?

@sanoopuio
Copy link

Thanks very much it works great :) .

Right now it works for both swipe horizontally(sidewards) and swipe vertically(up and down) .

How can i disable swipe vertically(up and down) .

Thanks
Sanoop

@sampaka
Copy link

sampaka commented Sep 24, 2014

Works great for me! But I have the same question as @pglatz - I can know swip the slideshow but I cannot click on the image or title so it takes me to the original piece of content? Thanks in advance

@birkmarcus
Copy link

Thanks a lot for this! Works great. I would love a click event as well. This might not fit in with the swipe/portable code, but still nice to have for browsers. Anyone knows a code for that?

@SuperFuentes
Copy link

To add a click event, we added the following to the line after evt.target.removeEventListener("touchend", self.handleTouchEnd); (but, before the self.fired=false;)

if (!self.fired) {
            if(jQuery(this).parents(".views_slideshow_cycle_slide").length > 0) {
            var link = jQuery(this).parents(".views_slideshow_cycle_slide").find("a").attr("href");
            if (link.length > 0) document.location.href = link;
            }
        }

I am trying to stop the script from changing slides when swippping up and down, does anyone have the answer for that?

Thanks,

@scrivenerb
Copy link

I'm sorta guessing here, but if you want to disable the vertical swipe, it looks like you could just comment out the line:

y: (evt.touches.length) ? evt.touches[0].clientY: evt.changedTouches[0].clientY

in the handleTouchMove function.

@zdnvck
Copy link

zdnvck commented Jan 14, 2015

HI, thanx, working, but scrivenerb solution for disabling vertical swipe is not working for me, any idea? Thank you..

@scrivenerb
Copy link

It didn't work for us either. :-/

@julpod
Copy link

julpod commented Apr 24, 2015

I've modify a bit the js to:

  • Allow a distance between the start and end points.
  • Avoid the usage of preventDefault and StopPropagation to allow native slideshow behaviour (eg. click).
  • Avoid vertical swipe to allow default device scrolling.
  /** Swipe behavior for Views Slideshows. */
  Drupal.settings.isTouchDevice = function() {
    return "ontouchstart" in window;
  }

  if ( Drupal.settings.isTouchDevice() ) {
    Drupal.behaviors.jQueryMobileSlideShowTouchAdvance = {
      attach: function(context, settings) {
        self = Drupal.behaviors.jQueryMobileSlideShowTouchAdvance;
          jQuery.each(jQuery(".views_slideshow_cycle_main.viewsSlideshowCycle-processed"), function(idx, value) {
            value.addEventListener("touchstart", self.handleTouchStart);
            jQuery(value).addClass("views-slideshow-mobile-processed");
          })
          jQuery(self).bind("swipe", self.handleSwipe);
      },
      detach: function() { },
      original: { x: 0, y: 0},
      changed: { x: 0, y: 0},
      direction: { x: "", y: "" },
      fired: false,
      ratio: 25,
      handleTouchStart: function(evt) {
        self = Drupal.behaviors.jQueryMobileSlideShowTouchAdvance;
        if (evt.touches) {
          if (evt.targetTouches.length != 1) { return false; } // don't respond to gestures
          self.original = { x: evt.touches[0].clientX, y: evt.touches[0].clientY }
          self.target = jQuery(this).attr("id").replace("views_slideshow_cycle_main_", "");
          Drupal.viewsSlideshow.action({ "action": "pause", "slideshowID": self.target });
          evt.target.addEventListener("touchmove", self.handleTouchMove);
          evt.target.addEventListener("touchend", self.handleTouchEnd);
        }
      },
      handleTouchMove: function(evt) {
        self = Drupal.behaviors.jQueryMobileSlideShowTouchAdvance;
        self.changed = {
          x: (evt.touches.length) ? evt.touches[0].clientX: evt.changedTouches[0].clientX,
          y: (evt.touches.length) ? evt.touches[0].clientY: evt.changedTouches[0].clientY
        };
        h = parseInt(self.original.x - self.changed.x),
        v = parseInt(self.original.y - self.changed.y);
        if (h !== 0) { self.direction.x = (h < self.ratio) ? "right":"left"; }
        if (v !== 0) { self.direction.y = (v < self.ratio) ? "up": "down"; }

        if (h > self.ratio || h < self.ratio*-1) {
          jQuery(self).trigger("swipe");
        }
      },
      handleTouchEnd: function(evt) {
        self = Drupal.behaviors.jQueryMobileSlideShowTouchAdvance;
        evt.target.removeEventListener("touchmove", self.handleTouchMove);
        evt.target.removeEventListener("touchend", self.handleTouchEnd);
        self.fired = false;
      },
      handleSwipe: function(evt) {
        self = Drupal.behaviors.jQueryMobileSlideShowTouchAdvance;
        if (evt != undefined && self.fired == false) {
          Drupal.viewsSlideshow.action({ "action":  (self.direction.x == "left")?"nextSlide":"previousSlide", "slideshowID": self.target });
          self.fired = true; //only fire advance once per touch
        }
      }
    }
  }

You could modify the "ratio" property to extend or contract the distance.
Hope this helps somebody. :)

@chrisrcooper
Copy link

You can integrate touch or swipe control by integrating a simple JS plugin and activating a "click" on the controls. Here's a tutorial to Drupal touch slider or swiper with Views Slideshow. It's only a few lines of code.

@studermartin
Copy link

Replace lines
self = Drupal.behaviors.jQueryMobileSlideShowTouchAdvance;
by
var self = Drupal.behaviors.jQueryMobileSlideShowTouchAdvance;.
Overwise the global Variable self is changed which usually refers to the browser window, which may break other JavaScript code. In my case it broke JavaScript code from module ShareThis.

@AnastasiaD
Copy link

Works well, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment