Извлечение связанной функции с этим ключевым словом из addEventListener

Я хочу изменить библиотечная функция, который выглядит следующим образом:

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

Помощь очень ценится!

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Здесь:

function onTouchStart(e) { 
    if (e.touches.length > 1) { foo() } else { this.fire.bind(map, 'mousedown') }
};

Проблема в this.fire.bind(map, 'mousedown'). Этот код не имеет побочных эффектов, он просто определяет функцию. См. связывать. Но на самом деле не называет это.

Чтобы вызвать его, вы можете использовать:

this.fire('mousedown');

Спасибо за ваш ответ @eguneys. Дело в том, что я заменил код в первом фрагменте только последним фрагментом в своем вопросе, поэтому я ожидал, что он будет работать без явного вызова? Я не полностью понимаю код, но я думаю, что это уже сделано в какой-то момент в коде. Рассматриваемая библиотека — Вот этот. И я совершенно забыл упомянуть об ошибке, которую я получаю, извините! Обновил вопрос.

Felix 29.07.2019 22:14

Не забывайте о двусмысленности this.

ghybs 30.07.2019 03:37
Ответ принят как подходящий

Это экземпляр проблема XY.

Вам не нужно преобразовывать события касания в события мыши (touchstartmousedown, touchmovemousemove, touchendmouseup) или наоборот: браузер уже делает это за вас.

Я настоятельно рекомендую вам посмотреть Презентация 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. Библиотека (ссылка в комментариях) делает это таким образом, и, похоже, это работает, поэтому я не хотел переделывать все это. Но если у меня будет время, я посмотрю материал, на который вы ссылаетесь. Спасибо за подробное объяснение, очень полезно!

Felix 30.07.2019 10:59

В этом случае я должен предположить, что автор L.Pather не знает, что события касания также автоматически запускают события мыши, но L.Pather не страдает от дублирующей обработки таких событий :-/

IvanSanchez 30.07.2019 11:27

Привет @IvanSanchez, небольшой вопрос: я заметил, что при запуске моего приложения Cordova в браузере полилинии LPather становятся видимыми, когда вы рисуете их во время перемещения мыши, но на моем устройстве Android они становятся видимыми только после наведения мыши. Может ли это быть вызвано тем, как L.Pather обрабатывает события касания?

Felix 31.07.2019 12:05

Другие вопросы по теме