2016-10-08 29 views
4

我试图找出如何处理混合设备,当涉及到绑定触摸和点击事件,但我找不到任何解决方案似乎工作(我没有混合设备,所以我不能直接测试,但由于失败的尝试甚至不能在普通设备上工作,所以我认为它们不能在混合设备上工作)。如何正确处理点击/触摸事件中的混合设备?

问题是,在混合设备上,您必须同时覆盖触摸和点击事件,而不是两次触发功能。所以,如果你看看我的失败尝试(2和3),你可以看到我绑定到touchendclick,但似乎有某种语法错误或某种东西,因为这不会导致事件实际触发。

第一个解决方案工作正常,但那是我刚刚使用事件触发类型中的一个或另一个。

我试过到目前为止:

- 工作在触摸设备上,然后单击设备:

_renderer.listenGlobal('document', 'ontouchstart' in window ? 'touchend' : 'click', (e) => { 

    console.log('works'); 
}); 

- 不会触发任何触摸或点击设备:

_renderer.listenGlobal('document', 'touchend click', (e) => { 

    console.log('works'); 

    e.stopPropagation(); 
}); 

- 不会触发任何触摸或点击设备:

_renderer.listenGlobal('document', 'touchend, click', (e) => { 

    console.log('works'); 

    e.stopPropagation(); 
}); 

正如你所看到的第一个例子覆盖2/3的设备类型,而另一个则涵盖0

我怎样才能确保我的功能将在每个正常运行设备?

回答

4

你可以使用几毫秒的主题和去抖,所以你只能有一个事件,基本上是这样的:

import {Component, Renderer} from '@angular/core' 
import { Subject } from 'rxjs/Subject'; 
import 'rxjs/add/operator/debounceTime'; 

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <h2>Hello {{name}}</h2> 
    </div> 
    `, 
}) 
export class App { 
    name = 'Angular2'; 
    subject = new Subject(); 

    constructor(renderer: Renderer) { 
    renderer.listenGlobal('document', 'touchend', (e) => { 
     console.log('touchend'); 
     this.subject.next(e); 
    }); 
    renderer.listenGlobal('document', 'click', (e) => { 
     console.log('click'); 
     this.subject.next(e); 
    }); 

    this.subject.debounceTime(100).subscribe(event => { 
     console.log(event); //do stuff here 
    }) 
    } 
} 

因此,当您使用的混合设备,你会得到这样的: enter image description here

有两件事被解雇了,但你的Observable只能得到一件。

你可以在此玩弄plunker

+0

我很好奇,我会更彻底地检查这一点。 – Chrillewoodz

3

只需在您的组件上添加(tap)指令而不是(click)指令,并将hammerjs添加到index.html文件中。

Angular 2将为您完成所有工作。

例子:

<my-component (tap)="doSomething()"></my-component> 

在您的index.html附加:

<script src="hammer.min.js"></script> 

要获得hammerjs

npm install hammerjs --save 

与此点击水龙头将正常工作。 如果您想要更多地控制水龙头,或者想要在运行时将事件绑定到您的元素,请尝试类似这样的操作。

_hammerEvents: HammerManager; 

public bindTapEvent(element: ElementRef):void{ 
    this._hammerEvents = new Hammer(element.nativeElement); 
    this._hammerEvents.on("tap", (event:any) => { /* do something */}); 
} 
+0

你能解释一下为什么我需要锤子吗? – Chrillewoodz

+0

@Chrillewoodz Angular 2已经有一个为这种情况提供的指令(tap),这个指令响应tap事件(ontouchstart,touchend)并且可以处理点击事件。在引擎盖下Angular 2会检查hammerjs是否被加载。 –

+0

你知道如何将水龙头绑定到文档吗?我得到一个错误,说它没有实现 – Chrillewoodz

相关问题