JavaScript Scroll Event for Iphone/Ipad

javascript scroll event for iPhone/iPad?

The iPhoneOS does capture onscroll events, except not the way you may expect.

One-finger panning doesn’t generate any events until the user stops panning—an onscroll event is generated when the page stops moving and redraws—as shown in Figure 6-1.

Sample Image

Similarly, scroll with 2 fingers fires onscroll only after you've stopped scrolling.

Sample Image

The usual way of installing the handler works e.g.

window.addEventListener('scroll', function() { alert("Scrolled"); });
// or
$(window).scroll(function() { alert("Scrolled"); });
// or
window.onscroll = function() { alert("Scrolled"); };
// etc

(See also https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html)

Browser scroll event doesn't fire often enough on iOS and Android devices

Pre-iOS 8:

It's not an issue of the scroll event being fired enough. Instead, browsers on iOS stop refreshing (i.e. "repainting") the screen while in the middle of a scroll gesture.

Safari WebKit, which is the HTML rendering component that is mandatorily used in all iOS browsers per Apple's policy, halts repainting during scroll gestures to conserve battery life and reduce heat. Note that JavaScript does continue to function normally in the background during a scroll gesture, even if the screen can't reflect any real-time changes that were made to the DOM during a scroll gesture. As soon as the gesture ends, a paint event is immediately fired, and the screen updates. However, timer loops, such as those that are setup via setInterval, do not fire during scroll gestures.

It's also worth noting that if you move your fingers very slowly when initiating a scroll, the scroll gesture doesn't take effect until after you've moved your finger approximately 10 pixels away from its starting position. During movement within this 10-pixel radius, the screen continues to be refreshed instantaneously. The moment that WebKit decides that your finger has moved far enough to initiate scrolling, screen refreshes are disabled until the scrolling gesture ends.

The reason this problem doesn't affect "some" web pages or JavaScript libraries is that they effectively "freeze" the page's scrolling, and instead emulate scrolling by intercepting touch events and then adjusting the body.scrollTop property accordingly. They freeze the page's scrolling by attaching an event handler to the onscroll event, and issue an event.preventDefault() command from within the event handler.

iOS 8 and later:

Apple is making the scroll event more fluid in iOS 8:

http://developer.telerik.com/featured/scroll-event-change-ios-8-big-deal/

How to debounce or throttle scroll events in iOS devices ( Safari )

If all of the rows has equal heights, you can try calculate the initial height of the scrolling area and use Intersection Observer to determine which rows are visible.

Is it recreate in variable memory for each scroll event?

Yes, the variables in the function will be recreated on every scroll events. But in your case, you can put some variables outside of the function to save a bit.

As per MDN, you shouldn't call expensive DOM manipulations directly in the function. Instead, it is recommended to throttle the event using requestAnimationFrame(), setTimeout(), or a CustomEvent. You can learn more at here.

Following is the improved example of your code:

let scrollPos;
const elHeader = document.querySelector("header");
const elOffer = document.querySelector(".offer");
// Note: I'm assuming that `documentOffset` don't need to be updated on every scroll events.
// Update it as `scrollPos` if it need to be updated on every scroll events.
const documentOffset = elOffter.offsetTop;;

const stickyNearOfferClose = () => {

// Note: Please move the following line in the scroll event
// if it's also needed to be called on every scroll events.
elHeader.classList.toggle("sticky", window.scrollY);

if (scrollPos >= documentOffset) {
elHeader.classList.add("hide");
} else {
elHeader.classList.remove("hide");
}
};

window.addEventListener("scroll", function () {
scrollPos = window.scrollY;
requestAnimationFrame(stickyNearOfferClose);
});


Related Topics



Leave a reply



Submit