#javascript #angular #click #touch
#javascript #angular #нажмите #коснитесь
Вопрос:
Я пытаюсь выяснить, как работать с гибридными устройствами, когда дело доходит до привязки событий касания и нажатия, но я не могу найти никакого решения, которое на самом деле работает (у меня нет гибридного устройства, поэтому я не могу тестировать напрямую, но поскольку неудачные попытки не работают даже на обычных устройствах, я не могу найти какое-либо решение).предположим, что они также не работают на гибридном устройстве).
Проблема в том, что на гибридном устройстве вы должны охватывать как события касания, так и нажатия, не вызывая функции дважды. Итак, если вы посмотрите на мои неудачные попытки (2 и 3), вы можете увидеть, что я привязываюсь к обоим touchend
и click
, но, похоже, есть какая-то синтаксическая ошибка или что-то в этом роде, потому что это не приводит к фактическому запуску ни одного из событий.
Первое решение работает нормально, но это когда я просто использую один или другой из типов запуска событий.
Что я пробовал до сих пор:
1 — Работает на сенсорных устройствах и устройствах щелчка:
_renderer.listenGlobal('document', 'ontouchstart' in window ? 'touchend' : 'click', (e) => {
console.log('works');
});
2 — Не срабатывает ни на устройствах touch, ни на устройствах click:
_renderer.listenGlobal('document', 'touchend click', (e) => {
console.log('works');
e.stopPropagation();
});
3 — Не срабатывает ни на устройствах touch, ни на устройствах click:
_renderer.listenGlobal('document', 'touchend, click', (e) => {
console.log('works');
e.stopPropagation();
});
Как вы можете видеть, первый пример охватывает 2/3 типов устройств, в то время как другие охватывают 0.
Как я могу убедиться, что мои функции будут работать правильно на каждом устройстве?
Ответ №1:
Вы можете использовать тему и отменить ее на пару миллисекунд, чтобы у вас было только одно событие, что-то вроде этого:
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
})
}
}
Итак, когда вы используете гибридные устройства, вы получите это:
Были запущены два события, но вы получаете только одно на своем наблюдаемом.
Вы можете поиграть с этим плунжером
Комментарии:
1. Я заинтригован, я проверю это более тщательно.
Ответ №2:
Просто добавьте директиву (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 */});
}
Комментарии:
1. Можете ли вы объяснить немного подробнее, зачем мне нужен hammerjs?
2. @Chrillewoodz В Angular 2 уже есть директива (tap), которая была предоставлена для этих случаев, эта директива реагирует на событие нажатия (ontouchstart, touchend) и будет работать с событиями нажатия. Под капотом Angular 2 проверит, был ли загружен hammerjs.
3. Знаете ли вы, как привязать нажатие к документу? Я получаю сообщение об ошибке, в котором говорится, что оно не реализовано
4. Спасибо @dlcardozo. Это работает как шарм. Я тестировал на настольных компьютерах, телефонах adnroid, а также на iPad с iOS 12.
5. Это должен быть правильный ответ. Отлично работает для Angular и было недостающим знанием, в котором я нуждался.