Я хочу изменить библиотечная функция, который выглядит следующим образом:
this.map.getContainer().addEventListener('touchstart', this.fire.bind(map, 'mousedown'));
Прямо сейчас (если я правильно понял) функция прослушивает события касания и, если они происходят, отправляет соответствующие события мыши. Таким образом, он указывает объекту карты обрабатывать события касания так же, как события мыши.
this.map.on('mousedown', this.eventHandlers.mouseDown);
this.eventHandlers = {
mouseDown: this.events.mouseDown.bind(this),
};
Я хочу изменить приведенную выше функцию, чтобы она различала события касания одним пальцем и события мультитач, например:
element.addEventListener('touchstart', onTouchStart);
function onTouchStart(e) {
if (e.touches.length > 1) { foo() } else { this.fire.bind(map, 'mousedown') }
};
Однако это не работает, просто поместив туда указанную выше функцию прослушивателя. Я попытался использовать e.currentTarget, а также создать var otherThis = this, а затем заменить this на otherThis, но это не сработало.
Я получаю следующую ошибку:
Uncaught TypeError: Cannot read property 'bind' of undefined at HTMLDivElement.onTouchStart
Помощь очень ценится!
Здесь:
function onTouchStart(e) {
if (e.touches.length > 1) { foo() } else { this.fire.bind(map, 'mousedown') }
};
Проблема в this.fire.bind(map, 'mousedown')
. Этот код не имеет побочных эффектов, он просто определяет функцию. См. связывать. Но на самом деле не называет это.
Чтобы вызвать его, вы можете использовать:
this.fire('mousedown');
Не забывайте о двусмысленности this
.
Это экземпляр проблема XY.
Вам не нужно преобразовывать события касания в события мыши (touchstart
→mousedown
, touchmove
→mousemove
, touchend
→mouseup
) или наоборот: браузер уже делает это за вас.
Я настоятельно рекомендую вам посмотреть Презентация Getting Touchy, 2015 г., а также прочитать соответствующая колода слайдов. В нем подробно объясняется, как разные браузеры отправляют события мыши (и указателя) наряду с событиями касания.
Даже если вы отправляете mousedown
/up
/move
только при некоторых условиях для событий касания, вы будете получать события дубликатmousedown
/up
/move
для одного касания.
С другой стороны: чистый способ привязки обработчиков событий здесь...
element.addEventListener('touchstart', onTouchStart);
function onTouchStart(e) {
if (e.touches.length > 1) { foo() } else { this.fire.bind(map, 'mousedown') }
};
...было бы...
element.addEventListener('touchstart', onTouchStart.bind(this));
function onTouchStart(e) {
if (e.touches.length > 1) { foo() } else { this.fire('mousedown') }
};
Обратите внимание, как вызов bind()
применяется к функции обработчика событий, а нет — к вызовам функций внутри обработчика событий. Это делает значение this
внутри обработчика события параметром bind()
.
"Путь листовки" был бы...
L.DomEvent.on(element, 'touchstart', onTouchStart, this)
... это пара оберток над bind
и addEventListener
. L.DomEvent
также обрабатывает особенности браузера (dblclick
на сенсорных экранах при некоторых обстоятельствах) и переводит нестандартные MSPointerDown
IE10 (и др.), так что touch*
события на машине Win7 с IE10 и сенсорным экраном будут работать.
Большое спасибо, @IvanSanchez. Библиотека (ссылка в комментариях) делает это таким образом, и, похоже, это работает, поэтому я не хотел переделывать все это. Но если у меня будет время, я посмотрю материал, на который вы ссылаетесь. Спасибо за подробное объяснение, очень полезно!
В этом случае я должен предположить, что автор L.Pather
не знает, что события касания также автоматически запускают события мыши, но L.Pather
не страдает от дублирующей обработки таких событий :-/
Привет @IvanSanchez, небольшой вопрос: я заметил, что при запуске моего приложения Cordova в браузере полилинии LPather становятся видимыми, когда вы рисуете их во время перемещения мыши, но на моем устройстве Android они становятся видимыми только после наведения мыши. Может ли это быть вызвано тем, как L.Pather обрабатывает события касания?
Спасибо за ваш ответ @eguneys. Дело в том, что я заменил код в первом фрагменте только последним фрагментом в своем вопросе, поэтому я ожидал, что он будет работать без явного вызова? Я не полностью понимаю код, но я думаю, что это уже сделано в какой-то момент в коде. Рассматриваемая библиотека — Вот этот. И я совершенно забыл упомянуть об ошибке, которую я получаю, извините! Обновил вопрос.