Событие щелчка не срабатывает на сенсорном экране, когда палец немного двигается - PullRequest
1 голос
/ 29 октября 2019

Событие нажатия работает нормально при использовании мыши с компьютером. Даже когда я нажимаю кнопку мыши на кнопку перемещения курсора, а затем отпускаю кнопку мыши в области кнопок, событие нажатия срабатывает. Но то же самое с сенсорным экраном это не работает. Я знаю, что причина в том, что на сенсорном экране такое перетаскивание считается прокруткой. Событие щелчка срабатывает, когда я не слишком много двигаю пальцем по кнопке. Так что только вниз и вверх без движения. У моего клиента проблема в том, что он слишком сильно двигает пальцем и слишком сложно получить событие щелчка. Можно ли установить больший порог для того, сколько пальцев может двигаться, чтобы он все еще считался щелчком, а не прокруткой?

Я нашел эту статью, где сенсорные события обрабатываются самостоятельно, и переводил их в событие щелчка. http://phonegap -tips.com / Articles / fast-touch-обработка событий-устранение-click-delay.html Я бы не хотел идти по этому пути.

Есть ли у вас какие-либосовет, как я могу решить эту проблему?

Вот более подробно о событиях касания https://developer.mozilla.org/en-US/docs/Web/API/Touch_events Посмотрите на Обработка нажатий, там описано, как щелчок работает на сенсорных экранах. Тем не менее мне не удалось работать. Несколько месяцев назад я но evt.preventDefault(); обратился к своему обработчику событий touchmove, и это действительно исправило проблему, но в настоящее время это не так. :

html
<body (touchmove)="touchMoveEvent($event)"></body>

TypeScript
touchMoveEvent(ev: Event): void
{
    ev.preventDefault();
}

А вот базовый угловой пример обработчика кнопки и щелчка, который не работает, если пользователь слишком сильно двигает пальцем. Я не проверял, что такое порог, но я полагаю, что это что-то около 10px-20px.

<button (click)="onClickEventHandler($event)">Press button</button>

onClickEventHandler(ev: Event) {
  //do the thing here
}

Я проверил функциональность сенсорного экрана с помощью панели инструментов устройства Chrome devtools.

Ответы [ 3 ]

3 голосов
/ 03 ноября 2019

Вот хорошее решение. с помощью событий touchstart и touchend вы можете измерить расстояние между двумя точками и запустить событие щелчка, если события близки (в пикселях). прочитайте мои комментарии.

    class ScrollToClick {
        constructor(elem, maxDistance = 20) {
            this.elem = elem;
            this.start = null;
            this.maxDistance = maxDistance;

            // Bind the touches event to the element
            this.bindTouchEvents();
        }

        bindTouchEvents() {
            this.elem.addEventListener('touchstart', this.onTouchStart.bind(this), false);
            this.elem.addEventListener('touchend', this.onTouchEnd.bind(this), false);
        }

        onTouchStart(e) {
            // hold the touch start position
            this.start = e.touches[0];

            // clear the position after 2000 mil (could be set for less).
            setTimeout(() => { this.start = null; }, 2000);
        }

        onTouchEnd(e) {
            // if the timeout was called, there will be no start position
            if (!this.start) { return; }

            // calculate the distance between start and end position
            const end = e.changedTouches[0],
                dx = Math.pow(this.start.pageX - end.pageX, 2),
                dy = Math.pow(this.start.pageY - end.pageY, 2),
                distance = Math.round(Math.sqrt(dx + dy));

            // if the distance is fairly small, fire
            // a click event. (default is 20 but you can override it through the constructor)
            if (distance <= this.maxDistance) {
                this.elem.click();
            }

            // clear the start position again
            this.start = null;
        }
    }

Тогда вы можете использовать его с любым элементом, например:

// use any element you wish (here I'm using the body)
const elem = document.body;

// initialize the class with the given element
new ScrollToClick(elem);

// listen to a click event on this element.
elem.addEventListener('click', (e) => {
    console.log('Clicked');
})
0 голосов
/ 07 ноября 2019

Мое окончательное решение здесь. Я забыл упомянуть в тексте, что я использую Angular, хотя я но в теге.

Итак, я сделал Angular-директиву, но в предложении AfikDeri, которое было очень близко к стилю директивы.

import { Directive, ElementRef, Input, OnInit } from '@angular/core';

@Directive({
  selector: '[touchClick]'
})
export class TouchClickDirective implements OnInit {
  @Input() maxDistance = 100;
  @Input() maxTime = 2000;

  @Input() touchClick: boolean;
  start: Touch;
  constructor(private elem: ElementRef) {
    this.start = null;
  }
  ngOnInit(): void {
    // Bind the touches event to the element
    this.bindTouchEvents();
  }
  bindTouchEvents() {
    this.elem.nativeElement.addEventListener('touchstart', this.onTouchStart.bind(this), false);
    this.elem.nativeElement.addEventListener('touchend', this.onTouchEnd.bind(this), false);
  }

  onTouchStart(e: TouchEvent) {
    // hold the touch start position
    this.start = e.touches[0];

    // clear the position after 2000 mil (could be set for less).
    setTimeout(() => {
      this.start = null;
    }, this.maxTime);
  }

  onTouchEnd(e: TouchEvent) {
    // if the timeout was called, there will be no start position
    if (!this.start) {
      return;
    }

    // calculate the distance between start and end position
    const end = e.changedTouches[0],
      dx = Math.pow(this.start.pageX - end.pageX, 2),
      dy = Math.pow(this.start.pageY - end.pageY, 2),
      distance = Math.round(Math.sqrt(dx + dy));

    // if the distance is fairly small, fire
    // a click event. (default is 20 but you can override it through the constructor)
    if (distance <= this.maxDistance) {
      this.elem.nativeElement.click();
    }

    // clear the start position again
    this.start = null;
  }
}

А вот как это можно использовать

<button mat-flat-button [touchClick] [maxDistance]="100" [maxTime]="300" (click)="doWarning()">
  Generate Warning
</button>
0 голосов
/ 06 ноября 2019

Это GitHub Issue , похоже, похожий. Я не разработчик JS, поэтому я не уверен, но надеюсь, что это поможет.

...