I'm trying to find out how to work with hybrid devices when it comes to binding touch and click events, but I can't find any solution that actually seems to work (I haven't got a hybrid device so I cannot test directly but since the failed attempts doesn't even work on normal devices I assume they don't work on a hybrid device either).
The problem is that on a hybrid device you have to cover both touch and click events without firing the functions twice. So if you look at my failed attempts (2 and 3) you can see that I bind to both touchend
and click
, but there appears to be some sort of syntax error or something because this causes none of the events to actually fire.
The first solution works fine but that's when I'm just using one or the other of the event firing types.
What I've tried so far:
1 - Works on touch devices and click devices:
_renderer.listenGlobal('document', 'ontouchstart' in window ? 'touchend' : 'click', (e) => {
console.log('works');
});
2 - Doesn't fire on either touch or click devices:
_renderer.listenGlobal('document', 'touchend click', (e) => {
console.log('works');
e.stopPropagation();
});
3 - Doesn't fire on either touch or click devices:
_renderer.listenGlobal('document', 'touchend, click', (e) => {
console.log('works');
e.stopPropagation();
});
As you can see the first example covers 2/3 device types, while the other ones cover 0.
How can I make sure that my functions will run properly on every device?
You could use a Subject and debounce for a couple of milliseconds so you only have one event, something like this:
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
})
}
}
So when you use hybrid devices, you will get this:
Two events were fired, but you only get one on your Observable.
You can play around in this plunker