Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
}
}
}
}
@ghost

This comment has been minimized.

Copy link

@ghost ghost commented Aug 7, 2013

Thanks, this works great. Is there a way to also add a click event to this? Thanks

@pglatz

This comment has been minimized.

Copy link

@pglatz pglatz commented Aug 7, 2013

Sorry, I just commented from the wrong account :(

Thanks, this works great. Is there a way to also add a click event to this? Thanks

@stillfire

This comment has been minimized.

Copy link

@stillfire stillfire commented Nov 28, 2013

Where exactly does this get implemented?

@sardbaba

This comment has been minimized.

Copy link

@sardbaba sardbaba commented Apr 19, 2014

@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

This comment has been minimized.

Copy link

@sanoopuio sanoopuio commented Jul 3, 2014

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

This comment has been minimized.

Copy link

@sampaka 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

This comment has been minimized.

Copy link

@birkmarcus birkmarcus commented Sep 29, 2014

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

This comment has been minimized.

Copy link

@SuperFuentes SuperFuentes commented Oct 23, 2014

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

This comment has been minimized.

Copy link

@scrivenerb scrivenerb commented Jan 12, 2015

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

This comment has been minimized.

Copy link

@zdnvck 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

This comment has been minimized.

Copy link

@scrivenerb scrivenerb commented Jan 28, 2015

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

@julpod

This comment has been minimized.

Copy link

@julpod 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

This comment has been minimized.

Copy link

@chrisrcooper chrisrcooper commented May 20, 2015

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

This comment has been minimized.

Copy link

@studermartin studermartin commented Jun 9, 2015

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

This comment has been minimized.

Copy link

@AnastasiaD AnastasiaD commented Oct 12, 2015

Works well, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.