Summary: | REGRESSION (iOS 11.3 beta): touchmove preventDefault() no longer respected | ||||||||
---|---|---|---|---|---|---|---|---|---|
Product: | WebKit | Reporter: | Steve <steve> | ||||||
Component: | UI Events | Assignee: | Nobody <webkit-unassigned> | ||||||
Status: | RESOLVED INVALID | ||||||||
Severity: | Critical | CC: | anand.thakker, atrigol, dave+webkit, dino, herr.ernst, john.firebaugh, mansing.choy, oliverzy, rbyers, steipete, webkit-bug-importer | ||||||
Priority: | P2 | Keywords: | InRadar | ||||||
Version: | Safari 11 | ||||||||
Hardware: | iPhone / iPad | ||||||||
OS: | iOS 11 | ||||||||
Attachments: |
|
Created attachment 333141 [details]
Comparison.mov
Attaching Comparison.mov video that demonstrates the change in behavior from iOS 11.2.5 (left) with iOS 11.3 Beta (right).
This is now correct behaviour. touchstart and touchmove event listeners on body, document and window are now passive by default, which means they cannot preventDefault. In order to actually preventDefault from those listeners, you need to explicitly put {passive:false} as an option in addEventListener. Thanks Dean! We noticed it wasn't listed in the Safari release notes: https://developer.apple.com/library/content/releasenotes/General/WhatsNewInSafari/Articles/Safari_11_1.html#//apple_ref/doc/uid/TP40014305-CH14-SW1 It seems like it's a big enough change that it should be listed there? Or is there another, more specific, document somewhere that mentions this change? https://github.com/mapbox/mapbox-gl-js/issues/6095 It's unfortunate that WebKit hasn't implemented `touch-action: none` (https://bugs.webkit.org/show_bug.cgi?id=133112), which was the recommended way of dealing with this change when it was rolled out in Chrome. * https://bugs.chromium.org/p/chromium/issues/detail?id=639227 * https://github.com/WICG/interventions/issues/18 * https://tech.slashdot.org/story/17/11/08/1135240/how-chrome-broke-the-web As you can see from the above links, that roll out caused a lot of developer angst, to put it mildly. Now WebKit is rolling out a similar change, but one that requires a different work around? I agree with Steve that this is likely to be a significant compatibility issue. This is especially causing issues with 3rd-party frameworks like React, which makes currently makes it really hard to add these new parameters. https://github.com/facebook/react/issues/6436 It's also breaking our mobile product, where we already applied the `touch-action: none` workaround and now we're struggling to fix this again. +1 This change is breaking https://web-preview.pspdfkit.com/standalone/1 We supply `touch-action: none` here, so it works in latest Chrome. Yeah I mentioned back in August (https://bugs.webkit.org/show_bug.cgi?id=175869#c2) this breaks sites which have applied the simple high-performance workaround of applying touch-action (https://developers.google.com/web/updates/2017/01/scrolling-intervention). I'm worried that by shipping in this state, people will just start applying the simplest possible workaround - passive:false, and we'll be back to the same state with scrolling often being blocked on touch handlers. We designed this behavior carefully to ensure that in the 90% case, the simplest fix was also the highest-performing one (touch-action). It seems to me like it would be better to delay shipping this change until touch-action is supported. Some data from Chrome to help with the compat decision making here: touch-action is used on ~18% of all page views: https://www.chromestatus.com/metrics/css/timeline/popularity/421 Of course many of these are "touch-action: manipulation", which does work fine in WebKit. Looking at some internal metrics (TouchAction.EffectiveTouchAction), I see that touch-actions not supported in WebKit are used as follows (as a fraction of all touch gestures): none: 1% pan-y: 2.4% pan-x pan-y: 0.5% This means that there's an upper bound of about 4% of all touches which could be broken by ignoring preventDefault without honoring these touch-action values. Of course not all of these will be for listeners on the document. We have separate metrics (Event.Touch.TargetAndDispatchResult) which show that about 35% of touch event dispatches occur on "root scroller" handlers (i.e. those impacted by this intervention). So a reasonable guess would be that roughly 1% of all touches would be broken by this. But what worries me more is that we've just recently seen usage of passive:false jump from 2% of all page views to 4%: https://www.chromestatus.com/metrics/feature/timeline/popularity/1418 If iOS 11.3 ships in this current state, I'm concerned we'll see this jump higher - reducing the utility of the passive touch listeners feature. I just loaded 11.3 on my iphone and in a few minutes I found a few sites that were broken... SortableJS is broken; http://rubaxa.github.io/Sortable/ It scrolls while dragging whereas this works correctly in Chrome. I see that window.Sortable is defined in about 500 sites (of 462k on http archive).. I haven't done a cross list of popularity of those sites. It is possible to get open layers scrolling the map at the same time as scrolling. It doesn't do it immediately but you need after you lift your finger and place it back down on the screen. https://openlayers.org/en/latest/examples/accessible.html Noting here that the bug, https://bugs.webkit.org/show_bug.cgi?id=184251 , involving TouchEvent#preventDefault() not working in a fairly straightforward circumstance, adds to the existing difficulties already discussed here in mitigating this breaking change. This breaks drag and drop in virtually any React application. https://github.com/facebook/react/issues/6436 More downstream issues caused by this change: * https://github.com/atlassian/react-beautiful-dnd/issues/413 * https://github.com/Shopify/draggable/issues/198 * https://github.com/lazd/iNoBounce/issues/45 fullPage.js is also affected by it! https://github.com/alvarotrigo/fullPage.js Dragging will show the white bands on iOS. |
Created attachment 333140 [details] ReproUnrespectedPreventDefault.html Steps to reproduce: - Open Safari on iPad with iOS11.3 (15E5167F) Beta - Load attach HTML file - Try to scroll the page - Notice that "rubberbanding" happens even though preventDefault() is being called on touchmove Environment: Reproduced on the following environments: - Safari on iPad Pro with iOS 11.3 (15E5167F) Beta - Safari on iPad Mini 2 with iOS 11.3 (15E5167F) Beta Unable to reproduce on: - Safari on iPad Pro with iOS 11.2