1

Based on TweenMax, the ScrollTo Plugin and ScrollMagic (this is probably not where the problem came from):

I wanna have a hero section on top of a page, only tweening downwards if the user is scrolling from the very beginning. Everything works as expected on my laptop (MBP). Following problem: If I use a touch-device (iPhone SE, iOS 12.4.1) and use a short touch gesture, the window is tweening to the destination withouth any issue. But if I keep my finger on the screen, the page starts to flicker and jumps back to the top after the tween finished.

Codepen

Since it's not working with Codepen on my mobile device:

Reduced test

Is there any way to fix this behaviour? Already tried to toggle preventDefault with eventListeners on Callbacks as well as setting the position again onComplete.

Flickering and Jumping on iOS


var vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);


// assume the feature isn't supported
var supportsPassive = false;
// create options object with a getter to see if its passive property is accessed
var opts = Object.defineProperty && Object.defineProperty({}, 'passive', { get: function(){ supportsPassive = true }});
// create a throwaway element & event and (synchronously) test out our options
document.addEventListener('test', function() {}, opts);

// var allowScroll = true;

function preventDefault(e) {
    e = e || window.event;
    if (e.preventDefault) {
        e.preventDefault();
    }
    //  if (e.stopImmediatePropagation) {
    //      e.stopImmediatePropagation();
    //  }
    if (e.stopPropagation) {
        e.stopPropagation();
    }
    e.returnValue = false;
}
function getBodyScrollTop() {
    var el = document.scrollingElement || document.documentElement;
    return el.scrollTop;
    // return window.pageYOffset
}
function setBodyScrollTop(scrollTop) {
    var el = document.scrollingElement || document.documentElement;
    el.scrollTop = scrollTop;
    // window.pageYOffset = scrollTop;
}
function addMousewheelListener() {
    if (e.addEventListener)
    {
        // IE9, Chrome, Safari, Opera
        e.addEventListener("mousewheel", preventScroll, supportsPassive ? { passive: false } : false);
        // Firefox
        e.addEventListener("DOMMouseScroll", preventScroll, supportsPassive ? { passive: false } : false);
    }
    // IE 6/7/8
    else
    {
        e.attachEvent("onmousewheel", preventScroll);
    }
}
function removeMousewheelListener() {
    if (e.removeEventListener)
    {
        // IE9, Chrome, Safari, Opera
        e.removeEventListener("mousewheel", preventScroll, supportsPassive ? { passive: false } : false);
        // Firefox
        e.removeEventListener("DOMMouseScroll", preventScroll, supportsPassive ? { passive: false } : false);
    }
    // IE 6/7/8
    else
    {
        e.detachEvent("onmousewheel", preventScroll);
    }
}
function removeTouchListeners(e) {
    window.removeEventListener("touchmove",  preventScroll);
    window.removeEventListener("touchstart", removeTouchListeners);
    window.removeEventListener("touchend",   removeTouchListeners);
}
function preventScroll(e) {
    // if(TweenMax.isTweening(window) || !allowScroll) {
        // e.preventDefault();
        // e.stopImmediatePropagation();
        preventDefault(e)
    // }
}
function deactivateScroll() {
    // allowScroll = false;
    console.log('fired 1');
    // window.addEventListener("touchstart", preventScroll, { passive: false });
    window.addEventListener("touchmove", preventScroll, { passive: false });
    addMousewheelListener();
}
function activateScroll() {
    // allowScroll = true;
    removeMousewheelListener();
    // var scrollTop = y;
    // var scrollTop = getBodyScrollTop;
    // setBodyScrollTop(scrollTop);
    window.addEventListener("touchstart", removeTouchListeners, { passive: false });
    window.addEventListener("touchend", removeTouchListeners, { passive: false });
    // var event1 = new Event('touchstart');
    // var event2 = new Event('touchmove'); 
    // var event3 = new Event('touchend'); 
    // window.dispatchEvent(event1); 
    // window.dispatchEvent(event2); 
    // window.dispatchEvent(event3);
}

var ctrl = new ScrollMagic.Controller();
var sceneLeave = new ScrollMagic.Scene({
  triggerElement: "#content",
  triggerHook: "onEnter",
  offset: 1
})
  .addTo(ctrl)
  .on("enter", function(event) {
    TweenMax.to(window, 1, {
      scrollTo: {
        y: "#content",
        autoKill: false
      },
      onStart: deactivateScroll,
      onComplete: activateScroll
    });
  });
Jakob Grommas
  • 31
  • 1
  • 3
  • This may be a bug in iOS itself. See the thread on [GreenSock's forums](https://greensock.com/forums/topic/21243-scrollto-plugin-jumping-on-ongoing-touch-gestures/) for more details. – Zach Saucier Sep 05 '19 at 15:03
  • Hehe, it’s my thread, but thanks for researching!! I’ll have a look what the next updates will bring as long as there is nothing to fix it. – Jakob Grommas Sep 05 '19 at 15:21
  • I know, I'm currently working as a GreenSock employee :) I just like to make sure that anyone who comes across GSAP posts on StackOverflow know that things like this are not just ignored, especially if they post on the GreenSock forums. – Zach Saucier Sep 05 '19 at 15:24

0 Answers0