前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SNS项目笔记<六>--手势Gestures

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

作者头像
stormKid
发布2018-09-12 15:41:15
1.6K0
发布2018-09-12 15:41:15
举报
文章被收录于专栏:计算机编程

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

1、angular处理事件源码:

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

代码语言:javascript
复制
/**
 * @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; }
}

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

代码语言:javascript
复制
// 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
代码语言:javascript
复制
//html
<ion-item (tap)=parentClick($event)>
      <button  ion-button block (click)="childClick($event)">子控件点击</button>
</ion-item>

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

错误写法2
代码语言:javascript
复制
//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,两个方法同时运行。

正确写法
代码语言:javascript
复制
//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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.08.29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、angular处理事件源码:
  • 2、实际运用手势来处理事件冲突
    • 错误写法1
      • 错误写法2
        • 正确写法
          • 附上angular语法防止事件冒泡的文章: angular4 防止事件冒泡
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档