I have a series of cells in an angular component:
<table>
<thead role="rowgroup">
<tr><th>M</th><th>T</th><th>O</th><th>T</th><th>F</th><th>L</th><th>S</th></tr>
</thead>
<tbody #body appSwipePaint>
<tr *ngFor="let week of weeks" role="rowgroup">
<td *ngFor="let day of week">
<ng-container *ngIf="!!day.fromMs">
<div (click)="book(day)" class="day">
{{ day.fromMs | date: 'dd' }}
</div>
</ng-container>
</td>
</tr>
</tbody>
</table>
My component looks like this:
I want my users to be able to touch a date and swipe over to mark multiple dates. I've created a directive I'm attaching to my tbody to do this:
@Directive({selector: '[appSwipePaint]'})
export class SwipePaintDirective {
private isPainting = false;
private days: HTMLElement[] = [];
constructor(private el: ElementRef) {
this.el.nativeElement.addEventListener('pointerdown', (evt: PointerEvent) => this.touchStart(evt));
this.el.nativeElement.addEventListener('pointermove', (evt: PointerEvent) => this.touchMove(evt));
this.el.nativeElement.addEventListener('pointerup', (evt: PointerEvent) => this.touchEnd(evt));
}
touchStart($event: PointerEvent) {
this.isPainting = true;
}
touchMove($event: PointerEvent) {
const el = document.elementFromPoint($event.x, $event.y) as HTMLElement;
if (this.isPainting && !this.days.includes(el)) {
this.days.push(el);
el.click();
}
}
touchEnd($event: PointerEvent) {
this.isPainting = false;
this.days = [];
}
}
This works fine on desktop. Browsers will detect that the PointerEvent enters each cell I'm pointing at as long as the mousebutton is pressed.
But when I test the page using a mobile device, or use simulated touch events in chrome dev-tools, the PointerEvents will only detect a touchstart and a touchmove within the cell which reported the touchstart. When I move the touch point outside the cell, it will no longer detect.
Why is that? What am I doing wrong?
The solution was simple, but not at all intuitive. It was mentioned here: `pointermove` event not working with touch. Why not?
Add touch-action: none;
to the container element, which in this case appears to be tbody td
.