专栏首页计算机编程SNS项目笔记<六>--手势Gestures

SNS项目笔记<六>--手势Gestures

移动开发与PC开发大相径庭,PC上最多的是鼠标点击事件,但是手机上面的手势事件却又很多,最常见的开发问题是处理父控件与子控件事件冲突问题,这就要我们十分了解手势了。ionic使用的是angular的库,用hammer来解决移动端的屏幕手势。

1、angular处理事件源码:

这里直接贴上angular源码地址:angular源码之hammer_gestures <这里方便它更新后的修改> 这里又贴上该地址的源码以便说明:

/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */

import {Inject, Injectable, InjectionToken} from '@angular/core';

import {DOCUMENT} from '../dom_tokens';

import {EventManagerPlugin} from './event_manager';

const EVENT_NAMES = {
  // pan
  'pan': true,
  'panstart': true,
  'panmove': true,
  'panend': true,
  'pancancel': true,
  'panleft': true,
  'panright': true,
  'panup': true,
  'pandown': true,
  // pinch
  'pinch': true,
  'pinchstart': true,
  'pinchmove': true,
  'pinchend': true,
  'pinchcancel': true,
  'pinchin': true,
  'pinchout': true,
  // press
  'press': true,
  'pressup': true,
  // rotate
  'rotate': true,
  'rotatestart': true,
  'rotatemove': true,
  'rotateend': true,
  'rotatecancel': true,
  // swipe
  'swipe': true,
  'swipeleft': true,
  'swiperight': true,
  'swipeup': true,
  'swipedown': true,
  // tap
  'tap': true,
};

/**
 * A DI token that you can use to provide{@link HammerGestureConfig} to Angular. Use it to configure
 * Hammer gestures.
 *
 * @experimental
 */
export const HAMMER_GESTURE_CONFIG = new InjectionToken<HammerGestureConfig>('HammerGestureConfig');

export interface HammerInstance {
  on(eventName: string, callback?: Function): void;
  off(eventName: string, callback?: Function): void;
}

/**
 * @experimental
 */
@Injectable()
export class HammerGestureConfig {
  events: string[] = [];

  overrides: {[key: string]: Object} = {};

  buildHammer(element: HTMLElement): HammerInstance {
    const mc = new Hammer(element);

    mc.get('pinch').set({enable: true});
    mc.get('rotate').set({enable: true});

    for (const eventName in this.overrides) {
      mc.get(eventName).set(this.overrides[eventName]);
    }

    return mc;
  }
}

@Injectable()
export class HammerGesturesPlugin extends EventManagerPlugin {
  constructor(
      @Inject(DOCUMENT) doc: any,
      @Inject(HAMMER_GESTURE_CONFIG) private _config: HammerGestureConfig) {
    super(doc);
  }

  supports(eventName: string): boolean {
    if (!EVENT_NAMES.hasOwnProperty(eventName.toLowerCase()) && !this.isCustomEvent(eventName)) {
      return false;
    }

    if (!(window as any).Hammer) {
      throw new Error(`Hammer.js is not loaded, can not bind ${eventName} event`);
    }

    return true;
  }

  addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
    const zone = this.manager.getZone();
    eventName = eventName.toLowerCase();

    return zone.runOutsideAngular(() => {
      // Creating the manager bind events, must be done outside of angular
      const mc = this._config.buildHammer(element);
      const callback = function(eventObj: HammerInput) {
        zone.runGuarded(function() { handler(eventObj); });
      };
      mc.on(eventName, callback);
      return () => mc.off(eventName, callback);
    });
  }

  isCustomEvent(eventName: string): boolean { return this._config.events.indexOf(eventName) > -1; }
}

源码上的手势都可以这样来使用:

// html:
<ion-item (xxx)=method($event)></ion-item>

// ts:
method(event){ //TODO ideal }

即通过dom绑定来绑定一个处理事件的方法。

源码中跟我们划分好了有pan【随手指移动跟随事件】、pinch【双手指捏合事件】、press【长按事件】、rotate【手势翻转事件】、swipe【手指迅速滑动事件】、tap【短时间触摸事件】

这里说明各大事件是使用场景:pinch事件是在图片放大缩小的时候,拇指与食指进行缩放操作就可以使用pinch事件来实现,pan事件与swipe事件可以用来处理左右滑动等问题,rotate可以使用来实现使用操作杆等3D手势,tap可以代替点击click事件,press就不用详细说明了,大家都懂。

2、实际运用手势来处理事件冲突

错误写法1
//html
<ion-item (tap)=parentClick($event)>
      <button  ion-button block (click)="childClick($event)">子控件点击</button>
</ion-item>

此时父控件手势完全遮盖住了子控件,造成button点击无效。

错误写法2
//html
<ion-item (tap)=parentClick($event)>
      <button  ion-button block (tap)="childClick($event)">子控件点击</button>
</ion-item>

//html
<ion-item (click)=parentClick($event)>
      <button  ion-button block (click)="childClick($event)">子控件点击</button>
</ion-item>

这是我们常见的写法,两个同时用click或者tap来完成点击事件的处理,在实际操作中造成事件冒泡,点击button,两个方法同时运行。

正确写法
//html
<ion-item (click)=parentClick($event)>
      <button  ion-button block (tap)="childClick($event)">子控件点击</button>
</ion-item>

由于错误写法1我们了解到,tap事件是触摸事件,并不是点击事件,在触发的时候会隔离事件冒泡,虽然不能一起使用,但是可以在click事件上阻止click触发,所以我们在子控件上使用tap,父控件上使用click,这样可以让我们的时间冒泡问题得以解决。

附上angular语法防止事件冒泡的文章: angular4 防止事件冒泡

timg.jpeg

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【vue随手笔记】Vue设置静态常量

    stormKid
  • SNS项目笔记<三>--fab与遮罩

    <b>在项目界面搭建过程中,使用fab的时候发现ionic自带的控件中并没有遮罩这样的属性这让我们实际操作起来很不舒服如下图所示:

    stormKid
  • NestJs 静态目录配置

    由于官方文档没有做详细解释说明,那么我们可以从此框架底层入手: 我们知道,nestjs底层用的是express,那么express是通过什么来完成静态目录构建...

    stormKid
  • JDBC URL 那些事儿

    JDBC是我们经常使用的,那URL中常用的那些参数你是否知道呢?本文梳理了常用的参数说明。

    问天丶天问
  • Yaml 速成查询表

    若是接触过编程数据结构的,对这个上手贼快. 写过json这些的...主要关注下缩进这些,理解下概念即可! 这里只列出非常高频且通用性高的使用姿势,个别骚姿势自行...

    CRPER
  • Golang Leetcode 345. Reverse Vowels of a String.go

    版权声明:原创勿转 https://blog.csdn.net/anakinsun/article/details/89088919

    anakinsun
  • vscode-setting.json配置

    xing.org1^
  • 快速搭建博客-高级篇-增加功能

    侧栏设置包括:侧栏位置、侧栏显示与否、文章间距、返回顶部按钮等等 打开 主题配置文件 找到sidebar字段

    瑞新
  • 前端-团队效率(二)代码规范

    // "javascript.suggest.autoImports": true,

    吴文周
  • JavaScript笔记总结(三)

    两个数字相加,返回数字相加的和;两个字符串相加,变量会连接成一个字符串;如果数字与字符串相加,返回字符串。

    宸寰客

扫码关注云+社区

领取腾讯云代金券