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

Настройки отображения темы Показывать по сообщений с сортировкой .
Выводить , отправленные .
Одна страница
Распечатать

К данной теме присоединены сообщения из темы «Почему я берусь за проекты-долгострои?»

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

0
. Редактировалось 1 раз, последний — #2

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

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


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

0
#3

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


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


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

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') обычно выполняются действия, в т. ч. стандартные браузерные, при нажатии на кнопки, ссылки и пр. интерактивные элементы.


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

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

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