ionic-framework: bug: tap click activates buttons without scrollEvents, but scrollEvents introduces perf issues
Bug Report
Ionic version:
[ ] 4.x [x] 5.x
Current behavior:
When scrolling an ion-list with clickable ion-items (button="true"), the item the user touches in order to scroll plays its “activated” style or animation (i.e. ripple effect on Android, darkened background on iOS). This happens even if the user is not “clicking” on that item.
Expected behavior:
When scrolling the list, the touched item should not change in appearance (play the ripple effect or change the background). These styles should only activate when the user taps/clicks an item to select it.
Steps to reproduce:
- Create a basic Ionic app (
ionic start) - Add an
ion-listto one of the pages containing enoughion-items to enable scrolling - Scroll the list with the app running in a mobile-ish environment (i.e. emulated touch enabled via devtools in a browser, or run on a physical device)
Related code:
StackBlitz: https://stackblitz.com/edit/ionic-list-ripple-bug
Snippet from Angular template:
<ion-list>
<ion-item *ngFor="let i of range(100)" button="true" detail="false">
Item #{{i}}
</ion-item>
</ion-list>
The
rangefunction is defined as follows:range(n) { return Array.from(Array(n).keys()); }
Other information:
This bug seems similar/identical to that identified in #15752. That issue references 7f38d377 as fixing the problem, but since I can reproduce it in a recent Ionic version, it seems to have reappeared(?).
Ionic info:
Note: I created the above StackBlitz example by forking https://stackblitz.com/edit/ionic-v4-angular-tabs. That codebase does not run as-is via
ionic serveornpm start, andionic infofails with an error:[WARN] You are not in an Ionic project directory. Project context may be missing.To at least provide some useful
ionic infooutput, I ranionic initto make the directory an Ionic project. However, some Angular packages are still not installed (since StackBlitz magically makes things work), and the example may not be runnable locally without some additional installations and setup work.
[WARN] Error loading @ionic/angular-toolkit package.json: Error: Cannot find module '@ionic/angular-toolkit/package'
Require stack:
- <path to global node_modules>\@ionic\cli\lib\project\index.js
- <path to global node_modules>\@ionic\cli\lib\index.js
- <path to global node_modules>\@ionic\cli\index.js
- <path to global node_modules>\@ionic\cli\bin\ionic
[WARN] Error loading @angular/cli package.json: Error: Cannot find module '@angular/cli/package'
Require stack:
- <path to global node_modules>\@ionic\cli\lib\project\index.js
- <path to global node_modules>\@ionic\cli\lib\index.js
- <path to global node_modules>\@ionic\cli\index.js
- <path to global node_modules>\@ionic\cli\bin\ionic
[WARN] Error loading @angular-devkit/build-angular package.json: Error: Cannot find module
'@angular-devkit/build-angular/package'
Require stack:
- <path to global node_modules>\@ionic\cli\lib\project\index.js
- <path to global node_modules>\@ionic\cli\lib\index.js
- <path to global node_modules>\@ionic\cli\index.js
- <path to global node_modules>\@ionic\cli\bin\ionic
Ionic:
Ionic CLI : 6.11.0
Ionic Framework : @ionic/angular 5.3.2
@angular-devkit/build-angular : not installed
@angular-devkit/schematics : 10.1.0
@angular/cli : not installed
@ionic/angular-toolkit : not installed
Utility:
cordova-res : 0.15.1
native-run : 1.0.0
System:
NodeJS : v14.4.0
npm : 6.14.5
OS : Windows 10
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 8
- Comments: 18 (7 by maintainers)
Commits related to this issue
- fix(all): ripple effect is no longer added when scrolling (#25352) resolves #22030 — committed to ionic-team/ionic-framework by liamdebeasi 2 years ago
Yes please fix this 😕
Any news about this bug?
I found a fix. Just add the empty attribute ‘scroll-events’ to the ion-content e.g.:
<ion-content scroll-events>...</ion-content>. This workaround has some performance implications. This was the breaking commit fd1b44a40b741088e099f6538dd14caa0dc5540c by @liamdebeasi. This disable alsoionScrollStartandionScrollEndevents not justionScrollas stated in the docs:https://github.com/ionic-team/ionic-framework/blob/181fc59ab7569ea41656cc21b225a0ffdbe5b1a1/core/src/components/content/content.tsx#L86-L90
ionScrollStartandionScrollEndare required to disable and enable the button activation onionScrollStartsee here:https://github.com/ionic-team/ionic-framework/blob/181fc59ab7569ea41656cc21b225a0ffdbe5b1a1/core/src/utils/tap-click.ts#L143-L149
Update
Here is another workaround without performance regression
BTW @liamdebeasi you may refactor all the tap-click stuff and the scroll listeners to work with passive listeners where possible (keep ssr in mind while refactoring, update: here https://github.com/ionic-team/ionic-framework/blob/dea9248763737164e17678119c775cdfc0e53ccd/core/src/utils/gesture/listener.ts you will have all the functionality you will need)
Still there. For such a basic building block of a mobile-first UI framework, it should rather be considered quite important to fix. In fact, there are numerous other scrolling issues on mobile, e.g. with toggle switches.
Thanks for the update. We are looking into updating the tap click utility for modern browsers, so this context helps.
I can confirm the bug and a fix would be great. As @maciejgoscinski mentioned, this seems pretty important as the user UI experience is not so nice right now. @DavidWiesner thanks for the workaround. Does work well.
Hi everyone,
I have an experimental fix that I am working on to resolve this issue. Can you all give this a try and let me know if you run into any issues? Using the new PointerEvents API, we can listen for the
pointercancelevent to ensure that the activated/ripple effect state is not added while scrolling. This is good as it lets us avoid having to listen for thescrollevent onion-contentwhich adds consistent main thread work while scrolling.This build works on all Ionic packages (
@ionic/angular,@ionic/react, etc)Note: This is an Ionic 6 build and is subject to all Ionic 6 breaking changes.
Similar issue for
<ion-card>when it has a routerLink on it. You can swipe content inside of it, which triggers the animation of the card tap (but not the click handler / routerLink itself).This is also the issue for ripple effect, if a component has a
routerLinkprop.Ripple effect is activated whenever I scroll a list of IonItem’s. Very ugly.