Skip to content

Commit 058fecc

Browse files
committed
revert(ripple): handle touch events
Reverts the `ripple(): handle touch events` commit from PR#7299. With the current touch solution, ripples are showing up twice on click. This is because after a `touchstart` event, the touch browser fires a `mousedown` event. This causes the ripple renderer to fade in another ripple from the `mousedown` event. There are solutions like: * Timeout to ignore `mousedown` events * Calling `preventDefault` / `stopPropagation` on `touchstart` * Listening to `pointerdown`, `pointerup`, `pointerleave` events * Using feature detecton (as in Modernizr) All of those solutions have negative aspects on the UX of the ripples and need to be evaluated with more testing. For now the ripples are broken and should be fixed as soon as possible. This is going to be revisited.
1 parent 630dfad commit 058fecc

File tree

2 files changed

+15
-45
lines changed

2 files changed

+15
-45
lines changed

src/lib/core/ripple/ripple-renderer.ts

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ export class RippleRenderer {
4040
/** Element which triggers the ripple elements on mouse events. */
4141
private _triggerElement: HTMLElement | null;
4242

43-
/** Whether the pointer is currently being held on the trigger or not. */
44-
private _isPointerDown: boolean = false;
43+
/** Whether the mouse is currently down or not. */
44+
private _isMousedown: boolean = false;
4545

4646
/** Events to be registered on the trigger element. */
4747
private _triggerEvents = new Map<string, any>();
@@ -62,12 +62,8 @@ export class RippleRenderer {
6262

6363
// Specify events which need to be registered on the trigger.
6464
this._triggerEvents.set('mousedown', this.onMousedown.bind(this));
65-
this._triggerEvents.set('touchstart', this.onTouchstart.bind(this));
66-
67-
this._triggerEvents.set('mouseup', this.onPointerUp.bind(this));
68-
this._triggerEvents.set('touchend', this.onPointerUp.bind(this));
69-
70-
this._triggerEvents.set('mouseleave', this.onPointerLeave.bind(this));
65+
this._triggerEvents.set('mouseup', this.onMouseup.bind(this));
66+
this._triggerEvents.set('mouseleave', this.onMouseup.bind(this));
7167

7268
// By default use the host element as trigger element.
7369
this.setTriggerElement(this._containerElement);
@@ -77,7 +73,7 @@ export class RippleRenderer {
7773
/**
7874
* Fades in a ripple at the given coordinates.
7975
* @param x Coordinate within the element, along the X axis at which to start the ripple.
80-
* @param Y Coordinate within the element, along the Y axis at which to start the ripple.
76+
* @param y Coordinate within the element, along the Y axis at which to start the ripple.
8177
* @param config Extra ripple options.
8278
*/
8379
fadeInRipple(x: number, y: number, config: RippleConfig = {}): RippleRef {
@@ -126,7 +122,7 @@ export class RippleRenderer {
126122
this.runTimeoutOutsideZone(() => {
127123
rippleRef.state = RippleState.VISIBLE;
128124

129-
if (!config.persistent && !this._isPointerDown) {
125+
if (!config.persistent && !this._isMousedown) {
130126
rippleRef.fadeOut();
131127
}
132128
}, duration);
@@ -182,14 +178,18 @@ export class RippleRenderer {
182178
/** Function being called whenever the trigger is being pressed. */
183179
private onMousedown(event: MouseEvent) {
184180
if (!this.rippleDisabled) {
185-
this._isPointerDown = true;
186-
this.fadeInRipple(event.clientX, event.clientY, this.rippleConfig);
181+
this._isMousedown = true;
182+
this.fadeInRipple(event.pageX, event.pageY, this.rippleConfig);
187183
}
188184
}
189185

190-
/** Function being called whenever the pointer is being released. */
191-
private onPointerUp() {
192-
this._isPointerDown = false;
186+
/** Function being called whenever the trigger is being released. */
187+
private onMouseup() {
188+
if (!this._isMousedown) {
189+
return;
190+
}
191+
192+
this._isMousedown = false;
193193

194194
// Fade-out all ripples that are completely visible and not persistent.
195195
this._activeRipples.forEach(ripple => {
@@ -199,22 +199,6 @@ export class RippleRenderer {
199199
});
200200
}
201201

202-
/** Function being called whenever the pointer leaves the trigger. */
203-
private onPointerLeave() {
204-
if (this._isPointerDown) {
205-
this.onPointerUp();
206-
}
207-
}
208-
209-
/** Function being called whenever the trigger is being touched. */
210-
private onTouchstart(event: TouchEvent) {
211-
if (!this.rippleDisabled) {
212-
const {clientX, clientY} = event.touches[0];
213-
this._isPointerDown = true;
214-
this.fadeInRipple(clientX, clientY, this.rippleConfig);
215-
}
216-
}
217-
218202
/** Runs a timeout outside of the Angular zone to avoid triggering the change detection. */
219203
private runTimeoutOutsideZone(fn: Function, delay = 0) {
220204
this._ngZone.runOutsideAngular(() => setTimeout(fn, delay));

src/lib/core/ripple/ripple.spec.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -104,20 +104,6 @@ describe('MatRipple', () => {
104104
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(2);
105105
});
106106

107-
it('should launch ripples on touchstart', fakeAsync(() => {
108-
dispatchTouchEvent(rippleTarget, 'touchstart');
109-
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(1);
110-
111-
tick(RIPPLE_FADE_IN_DURATION);
112-
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(1);
113-
114-
dispatchTouchEvent(rippleTarget, 'touchend');
115-
116-
tick(RIPPLE_FADE_OUT_DURATION);
117-
118-
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0);
119-
}));
120-
121107
it('removes ripple after timeout', fakeAsync(() => {
122108
dispatchMouseEvent(rippleTarget, 'mousedown');
123109
dispatchMouseEvent(rippleTarget, 'mouseup');

0 commit comments

Comments
 (0)