Closed greg-md closed 1 year ago
Thanks for the issue! This issue has been labeled as needs reproduction
. This label is added to issues that need a code reproduction.
Please reproduce this issue in an Ionic starter application and provide a way for us to access it (GitHub repo, StackBlitz, etc). Without a reliable code reproduction, it is unlikely we will be able to resolve the issue, leading to it being closed.
If you have already provided a code snippet and are seeing this message, it is likely that the code snippet was not enough for our team to reproduce the issue.
For a guide on how to create a good reproduction, see our Contributing Guide.
Can you provide a runnable sample? For complex things like gestures, runnable samples help us triage quickly.
@liamdebeasi here is a sample https://stackblitz.com/edit/angular-7mwuay
Another thing to mention, if I listen directly to touchmove
events, then first 4 events are CustomEvent
events if I start swiping from a swiper container. This could be a reason why gesture events are not catch after that.
this.listModal.nativeElement.addEventListener("touchmove", (e: any) => {
console.log('touchmove', e.touches ? e.touches[0].clientY : null, e);
}, false);
Thanks, I can reproduce this behavior. The reason this is happening is Swiper is emitting artificial touchstart
and touchmove
events via CustomEvent. The native events should have information regarding x and y coordinates. Ionic's gesture utility uses this information to calculate whether or not a gesture should activate. Swiper's artificial events do not contain this information, so Ionic's gestures never activates.
This isn't an Ionic bug, so I recommend reporting this to the Swiper team. It's generally a bad practice to interfere or simulate native events since it can cause issues with other libraries that depend on them.
@liamdebeasi I understand, but why gesture should care about custom events? They might contain anything. I think they just needs to be ignored.
From my knowledge, all non trusted events should be ignored. https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted
I understand, but why gesture should care about custom events?
The gesture utility was created before I started working on this project, but my best guess is that this was just never considered as a use case. That being said, it's probably safe to only listen for trusted events as you noted.
Actually it looks like this causes issues with testing. Libraries such as Playwright generate trusted events, but Cypress does not seem to. Making this change would likely break developers tests, so this isn't a change we can make.
I'll see if there's an alternative.
@liamdebeasi I think you can try to validate if the untrusted event meets some requirements, if not, to ignore it.
The way we'd check is if isTrusted: false
. We could check for the existence of other data such as pointer coordinates, but I think that is too brittle since that data can be incorrect when creating an untrusted event.
As a workaround, you can call stopPropagation()
on the untrusted events:
<swiper-container style="width: 100%; height: 100px; background: azure;" (touchstart)="suppress($event)">
...
</swiper-container>
suppress(ev: any) {
if (!ev.isTrusted) {
ev.stopPropagation();
}
}
A couple things to note about this:
touchstart
events even when there was never a touch event to begin with. This code works by suppressing the untrusted touchstart
event and letting the trusted touchstart
event bubble.The root issue here is Swiper is doing something it should not be doing. This is impacting other libraries that are used in conjunction with Swiper. While it is unfortunate that Swiper is impacting Ionic's gestures in this way, this is not an Ionic bug. I recommend filing feedback with the Swiper team to explain how Swiper's behavior has impacted your application.
I think it is debatable on which side is the issue. I still think the issue is on the Ionic's side, as Ionic do not handle custom events properly. This way you might have conflicts with any library which introduces untrusted custom events incompatible with ionic's business logic. And they have all the right to do it, cause that's how custom events works and the only common parameter is the detail
which could be of any type. 😞 https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent
The issue here is not that Ionic is incompatible with CustomEvent. CustomEvent as an API does not impact Ionic's gesture utility. The issue here is Swiper has chosen to use CustomEvent to simulate a native browser event but without the expected payload.
In other words, Swiper is attempting to create a touchstart event, but it is not following the touchstart specification. This is not a pattern Ionic should account for as Swiper's simulated touchstart
payload is incorrect.
Swiper can fix this issue on their end by using the TouchEvent constructor to generate an actual touchstart
event with the correct payload. The event will not be a trusted event, but the payload will match the specification and Ionic's gesture utility should work as intended.
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.
Prerequisites
Ionic Framework Version
v7.x
Current Behavior
The only events that are triggered are
canStart
andonWillStart
. Other events are not triggered.Expected Behavior
To produce
onStart
,onMove
andonEnd
events.Steps to Reproduce
Code Reproduction URL
https://stackblitz.com/edit/angular-7mwuay
Ionic Info
Additional Information
I couldn't find anything related on SwiperJS docs to change this behaviour. But if I listen directly to touchmove events on the same container, the events are fired, so I expect there is something broken on the ionic side.