mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-24 23:01:57 +08:00
@ -1,5 +1,6 @@
|
|||||||
import { Component, ComponentInterface, Event, EventEmitter, Listen, Prop } from '@stencil/core';
|
import { Component, ComponentInterface, Event, EventEmitter, Listen, Prop } from '@stencil/core';
|
||||||
|
|
||||||
|
import { GESTURE_CONTROLLER } from '../../utils/gesture/gesture-controller';
|
||||||
import { now } from '../../utils/helpers';
|
import { now } from '../../utils/helpers';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -13,6 +14,9 @@ import { now } from '../../utils/helpers';
|
|||||||
export class Backdrop implements ComponentInterface {
|
export class Backdrop implements ComponentInterface {
|
||||||
|
|
||||||
private lastClick = -10000;
|
private lastClick = -10000;
|
||||||
|
private blocker = GESTURE_CONTROLLER.createBlocker({
|
||||||
|
disableScroll: true
|
||||||
|
});
|
||||||
|
|
||||||
@Prop({ context: 'document' }) doc!: Document;
|
@Prop({ context: 'document' }) doc!: Document;
|
||||||
|
|
||||||
@ -37,11 +41,13 @@ export class Backdrop implements ComponentInterface {
|
|||||||
@Event() ionBackdropTap!: EventEmitter<void>;
|
@Event() ionBackdropTap!: EventEmitter<void>;
|
||||||
|
|
||||||
componentDidLoad() {
|
componentDidLoad() {
|
||||||
registerBackdrop(this.doc, this);
|
if (this.stopPropagation) {
|
||||||
|
this.blocker.block();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUnload() {
|
componentDidUnload() {
|
||||||
unregisterBackdrop(this.doc, this);
|
this.blocker.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Listen('touchstart', { passive: false, capture: true })
|
@Listen('touchstart', { passive: false, capture: true })
|
||||||
@ -78,18 +84,3 @@ export class Backdrop implements ComponentInterface {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const BACKDROP_NO_SCROLL = 'backdrop-no-scroll';
|
|
||||||
const activeBackdrops = new Set();
|
|
||||||
|
|
||||||
function registerBackdrop(doc: Document, backdrop: any) {
|
|
||||||
activeBackdrops.add(backdrop);
|
|
||||||
doc.body.classList.add(BACKDROP_NO_SCROLL);
|
|
||||||
}
|
|
||||||
|
|
||||||
function unregisterBackdrop(doc: Document, backdrop: any) {
|
|
||||||
activeBackdrops.delete(backdrop);
|
|
||||||
if (activeBackdrops.size === 0) {
|
|
||||||
doc.body.classList.remove(BACKDROP_NO_SCROLL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
--keyboard-offset: 0px;
|
--keyboard-offset: 0px;
|
||||||
--offset-top: 0px;
|
--offset-top: 0px;
|
||||||
--offset-bottom: 0px;
|
--offset-bottom: 0px;
|
||||||
|
--overflow: auto;
|
||||||
|
|
||||||
display: block;
|
display: block;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -75,11 +76,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.scroll-y {
|
.scroll-y {
|
||||||
overflow-y: auto;
|
overflow-y: var(--overflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
.scroll-x {
|
.scroll-x {
|
||||||
overflow-x: auto;
|
overflow-x: var(--overflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
.overscroll::before,
|
.overscroll::before,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Component, ComponentInterface, Element, Event, EventEmitter, EventListenerEnable, Listen, Method, Prop, QueueApi, State, Watch } from '@stencil/core';
|
import { Component, ComponentInterface, Element, Event, EventEmitter, EventListenerEnable, Listen, Method, Prop, QueueApi, State, Watch } from '@stencil/core';
|
||||||
|
|
||||||
import { Animation, Config, Gesture, GestureDetail, MenuChangeEventDetail, MenuControllerI, MenuI, Mode, Side } from '../../interface';
|
import { Animation, Config, Gesture, GestureDetail, MenuChangeEventDetail, MenuControllerI, MenuI, Mode, Side } from '../../interface';
|
||||||
|
import { GESTURE_CONTROLLER } from '../../utils/gesture/gesture-controller';
|
||||||
import { assert, isEndSide as isEnd } from '../../utils/helpers';
|
import { assert, isEndSide as isEnd } from '../../utils/helpers';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -16,6 +17,7 @@ export class Menu implements ComponentInterface, MenuI {
|
|||||||
private animation?: Animation;
|
private animation?: Animation;
|
||||||
private lastOnEnd = 0;
|
private lastOnEnd = 0;
|
||||||
private gesture?: Gesture;
|
private gesture?: Gesture;
|
||||||
|
private blocker = GESTURE_CONTROLLER.createBlocker({ disableScroll: true });
|
||||||
|
|
||||||
mode!: Mode;
|
mode!: Mode;
|
||||||
|
|
||||||
@ -195,6 +197,7 @@ export class Menu implements ComponentInterface, MenuI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidUnload() {
|
componentDidUnload() {
|
||||||
|
this.blocker.destroy();
|
||||||
this.menuCtrl!._unregister(this);
|
this.menuCtrl!._unregister(this);
|
||||||
if (this.animation) {
|
if (this.animation) {
|
||||||
this.animation.destroy();
|
this.animation.destroy();
|
||||||
@ -403,6 +406,7 @@ export class Menu implements ComponentInterface, MenuI {
|
|||||||
if (this.backdropEl) {
|
if (this.backdropEl) {
|
||||||
this.backdropEl.classList.add(SHOW_BACKDROP);
|
this.backdropEl.classList.add(SHOW_BACKDROP);
|
||||||
}
|
}
|
||||||
|
this.blocker.block();
|
||||||
this.isAnimating = true;
|
this.isAnimating = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,6 +419,9 @@ export class Menu implements ComponentInterface, MenuI {
|
|||||||
// emit opened/closed events
|
// emit opened/closed events
|
||||||
this._isOpen = isOpen;
|
this._isOpen = isOpen;
|
||||||
this.isAnimating = false;
|
this.isAnimating = false;
|
||||||
|
if (!this._isOpen) {
|
||||||
|
this.blocker.unblock();
|
||||||
|
}
|
||||||
|
|
||||||
// add/remove backdrop click listeners
|
// add/remove backdrop click listeners
|
||||||
this.enableListener(this, 'body:click', isOpen);
|
this.enableListener(this, 'body:click', isOpen);
|
||||||
|
@ -57,7 +57,6 @@ export class ReorderGroup implements ComponentInterface {
|
|||||||
queue: this.queue,
|
queue: this.queue,
|
||||||
gestureName: 'reorder',
|
gestureName: 'reorder',
|
||||||
gesturePriority: 90,
|
gesturePriority: 90,
|
||||||
disableScroll: true,
|
|
||||||
threshold: 0,
|
threshold: 0,
|
||||||
direction: 'y',
|
direction: 'y',
|
||||||
passive: false,
|
passive: false,
|
||||||
|
@ -18,6 +18,10 @@ body.backdrop-no-scroll {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.backdrop-no-scroll .ion-page > ion-content {
|
||||||
|
--overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Ionic Colors
|
// Ionic Colors
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
@ -29,8 +29,8 @@ export class GestureController {
|
|||||||
*/
|
*/
|
||||||
createBlocker(opts: BlockerConfig = {}): BlockerDelegate {
|
createBlocker(opts: BlockerConfig = {}): BlockerDelegate {
|
||||||
return new BlockerDelegate(
|
return new BlockerDelegate(
|
||||||
this.newID(),
|
|
||||||
this,
|
this,
|
||||||
|
this.newID(),
|
||||||
opts.disable,
|
opts.disable,
|
||||||
!!opts.disableScroll
|
!!opts.disableScroll
|
||||||
);
|
);
|
||||||
@ -95,10 +95,16 @@ export class GestureController {
|
|||||||
|
|
||||||
disableScroll(id: number) {
|
disableScroll(id: number) {
|
||||||
this.disabledScroll.add(id);
|
this.disabledScroll.add(id);
|
||||||
|
if (this.disabledScroll.size === 1) {
|
||||||
|
this.doc.body.classList.add(BACKDROP_NO_SCROLL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enableScroll(id: number) {
|
enableScroll(id: number) {
|
||||||
this.disabledScroll.delete(id);
|
this.disabledScroll.delete(id);
|
||||||
|
if (this.disabledScroll.size === 0) {
|
||||||
|
this.doc.body.classList.remove(BACKDROP_NO_SCROLL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
canStart(gestureName: string): boolean {
|
canStart(gestureName: string): boolean {
|
||||||
@ -140,7 +146,7 @@ export class GestureDelegate {
|
|||||||
private ctrl?: GestureController;
|
private ctrl?: GestureController;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
ctrl: any,
|
ctrl: GestureController,
|
||||||
private id: number,
|
private id: number,
|
||||||
private name: string,
|
private name: string,
|
||||||
private priority: number,
|
private priority: number,
|
||||||
@ -199,8 +205,8 @@ export class BlockerDelegate {
|
|||||||
private ctrl?: GestureController;
|
private ctrl?: GestureController;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
ctrl: GestureController,
|
||||||
private id: number,
|
private id: number,
|
||||||
ctrl: any,
|
|
||||||
private disable: string[] | undefined,
|
private disable: string[] | undefined,
|
||||||
private disableScroll: boolean
|
private disableScroll: boolean
|
||||||
) {
|
) {
|
||||||
@ -253,4 +259,5 @@ export interface BlockerConfig {
|
|||||||
disableScroll?: boolean;
|
disableScroll?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const gestureController = new GestureController(document);
|
const BACKDROP_NO_SCROLL = 'backdrop-no-scroll';
|
||||||
|
export const GESTURE_CONTROLLER = new GestureController(document);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { QueueApi } from '@stencil/core';
|
import { QueueApi } from '@stencil/core';
|
||||||
|
|
||||||
import { gestureController } from './gesture-controller';
|
import { GESTURE_CONTROLLER } from './gesture-controller';
|
||||||
import { createPointerEvents } from './pointer-events';
|
import { createPointerEvents } from './pointer-events';
|
||||||
import { createPanRecognizer } from './recognizers';
|
import { createPanRecognizer } from './recognizers';
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ export function createGesture(config: GestureConfig): Gesture {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const pan = createPanRecognizer(finalConfig.direction, finalConfig.threshold, finalConfig.maxAngle);
|
const pan = createPanRecognizer(finalConfig.direction, finalConfig.threshold, finalConfig.maxAngle);
|
||||||
const gesture = gestureController.createGesture({
|
const gesture = GESTURE_CONTROLLER.createGesture({
|
||||||
name: config.gestureName,
|
name: config.gestureName,
|
||||||
priority: config.gesturePriority,
|
priority: config.gesturePriority,
|
||||||
disableScroll: config.disableScroll
|
disableScroll: config.disableScroll
|
||||||
|
Reference in New Issue
Block a user