The Problem
Smooth scrolling on mobile devices is key to good user experience, though I think we all have experienced delayed or blocked scrolling behaviors.
The Cause
Event handlers may call preventDefault()
to cancel default behaviours. In our case, the browser does not know if preventDefault()
will be called before the touch handler finishes executing. So it waits for the handler to finish before triggering the scroll which is why we experience the delay.
The Solution
Fortunately this can be avoided by setting the passive option of relevant event listeners to true like this:
document.addEventListener(“touchstart”, handler, {passive: true})
To solve the problem, we need to tell the browser beforehand that the scroll will not be cancelled so that it does not wait for the handler to finish running. And this is exactly what passive: true
does.
Notes
Default Value
According to mdn,
If not specified, defaults to false – except that in browsers other than Safari and Internet Explorer, defaults to true for the wheel, mousewheel, touchstart and touchmove events.
There are two takeaways here:
- On modern browsers like Chrome (version 56 or later),
document.addEventListener(“touchstart”, handler)
is equal to
document.addEventListener(“touchstart”, handler, {passive: true})
-
passive: true
is only applied to handlers for these events:wheel
,mousewheel
,touchstart
andtouchmove
.
Prevent Scrolling
In some cases where we DO want to prevent scrolling (e.g. Google Map or other interactive iframes), we can easily cancel it by setting the following in CSS:
touch-action: none;
Top comments (0)