mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 19:21:34 +08:00
fix(content): tap-click deadlock (#17170)
fixes #17138 fixes #16863 fixes #16191 fixes #16911
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
import { Component, ComponentInterface, Element, Event, EventEmitter, Method, Prop, QueueApi } from '@stencil/core';
|
import { Component, ComponentInterface, Element, Event, EventEmitter, Listen, Method, Prop, QueueApi } from '@stencil/core';
|
||||||
|
|
||||||
import { Color, Config, Mode, ScrollBaseDetail, ScrollDetail } from '../../interface';
|
import { Color, Config, Mode, ScrollBaseDetail, ScrollDetail } from '../../interface';
|
||||||
import { isPlatform } from '../../utils/platform';
|
import { isPlatform } from '../../utils/platform';
|
||||||
@ -113,8 +113,14 @@ export class Content implements ComponentInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidUnload() {
|
componentDidUnload() {
|
||||||
if (this.watchDog) {
|
this.onScrollEnd();
|
||||||
clearInterval(this.watchDog);
|
}
|
||||||
|
|
||||||
|
@Listen('click', { capture: true })
|
||||||
|
onClick(ev: Event) {
|
||||||
|
if (this.isScrolling) {
|
||||||
|
ev.preventDefault();
|
||||||
|
ev.stopPropagation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,14 +275,15 @@ export class Content implements ComponentInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private onScrollEnd() {
|
private onScrollEnd() {
|
||||||
|
|
||||||
clearInterval(this.watchDog);
|
clearInterval(this.watchDog);
|
||||||
this.watchDog = null;
|
this.watchDog = null;
|
||||||
|
if (this.isScrolling) {
|
||||||
this.isScrolling = false;
|
this.isScrolling = false;
|
||||||
this.ionScrollEnd.emit({
|
this.ionScrollEnd.emit({
|
||||||
isScrolling: false
|
isScrolling: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hostData() {
|
hostData() {
|
||||||
return {
|
return {
|
||||||
|
@ -37,6 +37,12 @@
|
|||||||
--ion-background-color-rgb: 0,0,0;
|
--ion-background-color-rgb: 0,0,0;
|
||||||
--ion-text-color-rgb: 255,255,255;
|
--ion-text-color-rgb: 255,255,255;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[f] {
|
||||||
|
background: green;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
class PageOne extends HTMLElement {
|
class PageOne extends HTMLElement {
|
||||||
@ -74,6 +80,15 @@
|
|||||||
<ion-button class="next">Go to Page Three</ion-button>
|
<ion-button class="next">Go to Page Three</ion-button>
|
||||||
</ion-nav-push>
|
</ion-nav-push>
|
||||||
</div>
|
</div>
|
||||||
|
<div f></div>
|
||||||
|
<div f></div>
|
||||||
|
<div f></div>
|
||||||
|
<div f></div>
|
||||||
|
<div f></div>
|
||||||
|
<div f></div>
|
||||||
|
<div f></div>
|
||||||
|
<div f></div>
|
||||||
|
|
||||||
</ion-content>
|
</ion-content>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ export function startTapClick(doc: Document, config: Config) {
|
|||||||
let lastTouch = -MOUSE_WAIT * 10;
|
let lastTouch = -MOUSE_WAIT * 10;
|
||||||
let lastActivated = 0;
|
let lastActivated = 0;
|
||||||
let cancelled = false;
|
let cancelled = false;
|
||||||
let scrolling = false;
|
let scrollingEl: HTMLElement | undefined;
|
||||||
|
|
||||||
let activatableEle: HTMLElement | undefined;
|
let activatableEle: HTMLElement | undefined;
|
||||||
let activeRipple: Promise<() => void> | undefined;
|
let activeRipple: Promise<() => void> | undefined;
|
||||||
@ -15,12 +15,8 @@ export function startTapClick(doc: Document, config: Config) {
|
|||||||
const useRippleEffect = config.getBoolean('animated', true) && config.getBoolean('rippleEffect', true);
|
const useRippleEffect = config.getBoolean('animated', true) && config.getBoolean('rippleEffect', true);
|
||||||
const clearDefers = new WeakMap<HTMLElement, any>();
|
const clearDefers = new WeakMap<HTMLElement, any>();
|
||||||
|
|
||||||
function onBodyClick(ev: Event) {
|
function isScrolling() {
|
||||||
if (cancelled || scrolling) {
|
return scrollingEl !== undefined && scrollingEl.parentElement !== null;
|
||||||
ev.preventDefault();
|
|
||||||
ev.stopPropagation();
|
|
||||||
cancelled = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Touch Events
|
// Touch Events
|
||||||
@ -59,15 +55,16 @@ export function startTapClick(doc: Document, config: Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function pointerDown(ev: any) {
|
function pointerDown(ev: any) {
|
||||||
if (activatableEle || scrolling) {
|
cancelled = false;
|
||||||
|
if (activatableEle || isScrolling()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cancelled = false;
|
scrollingEl = undefined;
|
||||||
setActivatedElement(getActivatableTarget(ev), ev);
|
setActivatedElement(getActivatableTarget(ev), ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
function pointerUp(ev: UIEvent) {
|
function pointerUp(ev: UIEvent) {
|
||||||
if (scrolling) {
|
if (isScrolling()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setActivatedElement(undefined, ev);
|
setActivatedElement(undefined, ev);
|
||||||
@ -145,13 +142,12 @@ export function startTapClick(doc: Document, config: Config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doc.addEventListener('click', onBodyClick, true);
|
doc.addEventListener('ionScrollStart', ev => {
|
||||||
doc.addEventListener('ionScrollStart', () => {
|
scrollingEl = ev.target as HTMLElement;
|
||||||
scrolling = true;
|
|
||||||
cancelActive();
|
cancelActive();
|
||||||
});
|
});
|
||||||
doc.addEventListener('ionScrollEnd', () => {
|
doc.addEventListener('ionScrollEnd', () => {
|
||||||
scrolling = false;
|
scrollingEl = undefined;
|
||||||
});
|
});
|
||||||
doc.addEventListener('ionGestureCaptured', cancelActive);
|
doc.addEventListener('ionGestureCaptured', cancelActive);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user