Для прослушивания двойного щелчка требуется три нажатия на iOS 13 - PullRequest
0 голосов
/ 21 апреля 2020

Я пытаюсь прослушать двойной щелчок на полном экране в iOS.

Минимальный пример без рамки работает, когда двойное нажатие на простой div: https://fluoridated-nebulous-zebu.glitch.me/

Но при подключении к canvas блока aframe требуется три нажатия на iOS для запуска: https://classic-infrequent-pram.glitch.me/

<script>
    function doubleClick(fn, timeout = 500) {
        let last = Date.now();

        return function(e) {
            const now = Date.now();
            const diff = now - last;

            console.log('single');

            if (diff < timeout) {
                fn(e);

                console.log('double');
            }

            last = now;
        }
    };

    AFRAME.registerComponent('double-click', {

        init: function() {
            this.el.sceneEl.canvas.addEventListener('click', doubleClick(this.onDoubleClick.bind(this)));
        },

        onDoubleClick: function() {
            this.el.setAttribute('color', '#ff0000');
        }
    });
</script>

<a-scene background="color: #FAFAFA">
    <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9" shadow double-click></a-box>
    <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E" shadow></a-sphere>
    <a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D" shadow></a-cylinder>
    <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4" shadow></a-plane>
</a-scene>

Кажется, второй щелчок душится, но я не уверен, кем. Я не смог найти ни одного кода, который бы делал это в настройках холста aframe, и даже ручное удаление любых слушателей, не принадлежащих мне, в инспекторе Safari не имело значения.

Редактировать: Это также работает, если вы нажимаете достаточно медленно, чтобы избежать удушения, и достаточно быстро, чтобы оно истекло.

Редактировать 2: Также похоже, что оно работает на iOS 12, но не на 13.

1 Ответ

0 голосов
/ 23 апреля 2020

Нашел решение из потока Github: https://github.com/Leaflet/Leaflet/issues/6817#issuecomment -535919797

натолкнулся на эту тему при поиске аналогичной проблемы. Я обнаружил, что вызов метода warnDefault на сенсорном старте позволит вам получать сенсорные события как обычно и, таким образом, проверять наличие двойного касания.

Я считаю, что это сводится к тому, что мобильный Safari изменил способ имитации событий при наведении (чтобы веб-сайты работали, полагаясь исключительно на события при наведении, чтобы открыть меню и тому подобное)

Вместо этого я сейчас слушаю touchstart и вызываю e.preventDefault() для первого события:

function doubleClick (fn, timeout = 500) {
  let last = Date.now();

  return function (e) {
    const now = Date.now();
    const diff = now - last;

    console.log('single');

    if (diff < timeout) {
      fn(e);

      console.log('double');
    } else {
      e.preventDefault();
    }

    last = now;
  }
};

AFRAME.registerComponent('double-click', {

  init: function () {
    this.el.sceneEl.canvas.addEventListener('touchstart', doubleClick(this.onDoubleClick.bind(this)));
  },

  onDoubleClick: function () {
    this.el.setAttribute('color', '#ff0000');
  }
});

Конечно, предотвращение дефолта может вызвать проблемы в вашей ситуации, поэтому YMMV. Также все еще должен обрабатывать щелчок как запасной вариант для нормально работающих устройств.

...