Как определить, чем вызвано событие click — мышью или сенсорным экраном

Настройки отображения темы Показывать по сообщений с сортировкой .
Выводить , отправленные .
Одна страница
Распечатать
К данной теме присоединены сообщения из темы «Почему я берусь за проекты-долгострои?»
10geek
Единомышленник
Нет Всего сообщений: 333
Зарегистрирован: 29 июн. 2018 г., 09:36
Рейтинг пользователя: 40

0
. Редактировалось 1 раз, последний — #2
Да вот буквально вчера столкнулся с очередным примером такой черезжопности. В браузерах нельзя просто так взять и определить, чем было вызвано событие click: мышью или сенсорным экраном. Вообще нет правильного способа это сделать. Лучший способ, который я нашёл — это написание обёртки для обработчиков событий click и touchend, вроде этой. Вот такие идиотские проблемы в чужом софте и затормаживают разработку, вчера полдня с этим угробил.

В новых версиях Chromium у события click есть свойство pointerType, которое как раз и является тем, что мне нужно. Но, например, в Firefox 91 оно не поддерживается, несмотря на информацию в таблице совместимости на MDN. И, судя по всему, это баг, который был в Firefox и Safari.

4X_Pro
Создатель сайта
Всего сообщений: 3526
Зарегистрирован: 9 дек. 2015 г., 19:20
Рейтинг пользователя: 1719

0
#3
Кажется, нашёл решение — свойство mozInputSource: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/mozInputSource
Правда, оно, наоборот, работает только в Firefox, но не в Chrome. Так что проверка по-любому получается костыльной.

Ребята, давайте жить спокойно!

10geek
Единомышленник
Нет Всего сообщений: 333
Зарегистрирован: 29 июн. 2018 г., 09:36
Рейтинг пользователя: 40

0
. Редактировалось 1 раз, последний — #4
В итоге предложенную на StackOverflow функцию я привёл к следующему виду:
function addClickTouchHandler(el, callback) { var touch = move = false; el.addEventListener('touchmove', function() { move = true; }); el.addEventListener('touchend', function() { if(move) touch = move = false; else touch = true; }); el.addEventListener('click', function(ev) { var callbackReal = callback.bind(this); callbackReal(ev, touch ? 'touch' : 'click'); touch = false; }); }
Делает почти всё то же самое, с той лишь разницей, что теперь callbackReal() вызывается только при событии 'click', но не при 'touchend', а значит 1-м аргументом в неё теперь всегда передаётся объект Event события 'click'. Это в свою очередь позволяет использовать методы event.preventDefault() и event.stopImmediatePropagation() событий 'click', а ведь именно при 'click' (а не 'touchend') обычно выполняются действия, в т. ч. стандартные браузерные, при нажатии на кнопки, ссылки и пр. интерактивные элементы.

Одна страница
Распечатать

У вас нет прав для отправки сообщений в эту тему.

Задать вопрос

Здесь можно задать мне вопрос или спросить совета по любой теме, затронутой в блогах или на форуме. После того, как я отвечу, вопрос и ответ появятся в соответствующем разделе. Но не забываем, что я — сторонник slow life, поэтому каких-либо сроков ответов не обещаю. Самые интересные вопросы станут основой для новых тем на форуме или записей в блоге.
Сразу предупреждаю: глупости, провокации, троллинг и тому подобное летит прямо в /dev/null.