Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'Wheel' events on touch screens

I have this fiddle https://jsfiddle.net/316n1xmL/1/ which works perfectly how I need it to on desktop. Counts up or down based on wheel scroll direction and adds and removes classes. The issue I am running into is how to do this on touch screens.

I have tried hammer.js but their documentation is really bad and not clear.

Sadly the site I am building is using bootstrap 4 which means I cannot use juqery mobile since BS4 uses jquery 3 which does not support jquery mobile.

Any help is appreciated

// Scroll Direction Plugin Move Later to own file

!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a:a(jQuery)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||f>n)&&(f=n,d(g,n)&&(f/=40)),d(g,n)&&(j/=40,l/=40,m/=40),j=Math[j>=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120===0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b),d=c["offsetParent"in a.fn?"offsetParent":"parent"]();return d.length||(d=a("body")),parseInt(d.css("fontSize"),10)||parseInt(c.css("fontSize"),10)||16},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})});

$(document).ready(function() {
    
    var counter = 0;
    var scrollThreshold = 15;

    var tiles = $('.list-tile');

    $(window).on('wheel', function(event){
        // deltaY obviously records vertical scroll, deltaX and deltaZ exist too
        if(event.originalEvent.deltaY < 0){
          // wheeled up
          counter--;
            if (Math.abs(counter) >= scrollThreshold) {
                tiles.filter('.animate-up').not('.first').last().removeClass('animate-up');
                counter = 0;
            }
        }
        else {
            // wheeled down
            counter++;
            if (counter >= scrollThreshold) {
                tiles.not('.animate-up').eq(0).addClass('animate-up');
                counter = 0;
            }
        }
      });

});
.hero-list {
  height: 100vh;
  width: 100%;
  touch-action: pan-x;
  user-select: none;
  -webkit-user-drag: none;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  position: relative;
  overflow: hidden;
}
.hero-list .hero-list-container {
  position: relative;
  z-index: 901;
  height: 100vh;
  overflow: hidden;
}
.hero-list .hero-list-container .list-tile {
  width: 100%;
  height: 100vh;
  margin: 0 auto;
  position: absolute;
  top: 0;
  left: 0;
  box-sizing: border-box;
  overflow: hidden;
  transform: translate3d(0, 100%, 0);
  transition-duration: 1s;
  transition-property: transform;
  transition-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1);
  transition-delay: 0s;
}
.hero-list .hero-list-container .list-tile:nth-of-type(2) {
  background-color: green;
}
.hero-list .hero-list-container .list-tile:nth-of-type(3) {
  background-color: blue;
}
.hero-list .hero-list-container .list-tile .module-background {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
  display: block;
  transition-duration: 1s;
  transition-property: transform;
  transition-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1);
  transition-delay: 0s;
  transform: translate3d(0, -20%, 0) scale(1.5);
}
.hero-list .hero-list-container .list-tile.animate-up {
  transform: translate3d(0, 0%, 0) scale(1) !important;
}
.hero-list .hero-list-container .list-tile.animate-up .module-background {
  transform: translate3d(0, 0%, 0) scale(1) !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="hero-list">
				<div class="hero-list-container">
					<div class="list-tile animate-up">
						<div class="module-background" style="background-image: url('https://thomasstorage1.blob.core.windows.net/wp-media/2017/11/tech-background.png');
				background-size: cover;">

						</div>
					</div>

					<div class="list-tile">
						<div class="module-background" style="background-image: url('https://thomasstorage1.blob.core.windows.net/wp-media/2017/11/tech-background.png');
				background-size: cover;">

						</div>
					</div>

					<div class="list-tile">
						<div class="module-background" style="background-image: url('https://thomasstorage1.blob.core.windows.net/wp-media/2017/11/tech-background.png');
				background-size: cover;">

						</div>
					</div>

					<div class="list-tile">
						<div class="module-background" style="background-image: url('https://thomasstorage1.blob.core.windows.net/wp-media/2017/11/tech-background.png');
				background-size: cover;">

						</div>
					</div>
				</div>
			</div>
like image 627
OMGDrAcula Avatar asked Jun 04 '18 21:06

OMGDrAcula


People also ask

What is a wheel event gesture?

The wheel event fires when the user rotates a wheel button on a pointing device (typically a mouse).

Does touch trigger click event?

When a visitor clicks on an image the click event will be triggered. However when someone touches the image, that same click event will be triggered, even if a touchstart event is available as well.

What is mouse wheel event?

Definition and Usage The onwheel event occurs when the mouse wheel is rolled up or down over an element. The onwheel event also occurs when the user scrolls or zooms in or out of an element by using a touchpad (like the "mouse" of a laptop).

What is a touchmove event?

Definition and Usage The touchmove event occurs when the user moves the finger across the screen. The touchmove event will be triggered once for each movement, and will continue to be triggered until the finger is released. Note: The touchmove event will only work on devices with a touch screen.

What is the wheel event?

The wheel event fires when the user rotates a wheel button on a pointing device (typically a mouse). This event replaces the non-standard deprecated mousewheel event. Note: Don't confuse the wheel event with the scroll event.

Why doesn't the wheel event dispatch a scroll event?

The default action of a wheel event is implementation-specific, and doesn't necessarily dispatch a scroll event. Even when it does, the delta* values in the wheel event don't necessarily reflect the content's scrolling direction.

How many times does the touchmove event trigger?

The touchmove event will be triggered once for each movement, and will continue to be triggered until the finger is released. Note: The touchmove event will only work on devices with a touch screen.


1 Answers

You need to refactor a little bit Your plugin by detecting touch events. Hammer is a great library which can cover all the gesture types. If You need something lighter and straightforward, You can anyway add this functionality by yourself in plain JavaScript:

Add feature detection and touch handlers:

if("ontouchstart" in window){
   el.addEventListener('touchstart', touchStartHandler);
   el.addEventListener('touchmove', touchMoveHandler);
   el.addEventListener('touchend', touchEndHandler);
}

Put the code which is actually inside Your onwheel handler in its own function.

Now, You should decide what behavior You are about to implement in Your plugin: i.e. either if the scroll should happen during swipe down, or only after the finger has been released. Use that function inside the desired touch handler, either inside the touchmove or inside the touchend event.

As You need to use latest jQuery, I believe You don't need extra backward cross-browser compatibility, anyway here is an example: https://stackoverflow.com/a/27024624/4845566.

Lastly, You can add some more usability to Your plugin by allowing touch actions to be slightly diagonal, as by using the thumb is. Here is a nice discussion about this topic with all the source code You need: A simple swipe detection on vanilla js

like image 121
deblocker Avatar answered Oct 05 '22 23:10

deblocker