Я пытаюсь использовать JavaScript и jQuery для захвата сенсорных событий.Но я наблюдаю очень странное поведение в веб-браузере на Android 2.3.2: всякий раз, когда я касаюсь экрана, а затем быстро нажимаю где-нибудь еще на экране, браузер:
- на мгновение показываеторанжевая рамка и выделение по всему экрану, и
- посылает мне неправильные события.
Оранжевая граница, кажется, является просто связанным симптомом того жеосновная проблема, так что я не слишком беспокоюсь об этом - на самом деле удобно знать, когда браузер все испортил.Что я действительно хочу знать, так это: как я могу последовательно получать правильные события касания для двух быстрых нажатий? Я считаю, что когда эта проблема будет решена, оранжевая граница также исчезнет.
Ниже приведены все болезненные детали, которые я до сих пор проработал.
Вот страница, которая показывает проблему и отображает множество диагностической информации о деталях и времени каждого событияэто получено.Вы обязательно получите оранжевые вспышки / плохие события, если вы нажмете внутри синего прямоугольника, а затем быстро нажмете внутри черного прямоугольника.
Мой код jQuery довольно стандартный.Реализация функции log
не важна;проблема в том, что браузер не вызывает его, когда должен.
el = $('#battle');
el.on('touchstart', function(event) {
log(event);
return event.preventDefault();
});
el.on('touchend', function(event) {
return log(event);
});
el.on('touchcancel', function(event) {
return log(event);
});
el.mousedown(function(event) {
log(event);
return event.preventDefault();
});
return el.mouseup(function(event) {
return log(event);
});
Подробнее о явлениях, которые я описал изначально:
Оранжевая рамка и выделение: Это та же оранжевая рамка и выделение, которое браузер рисует вокруг гиперссылки при нажатии на нее.Но на странице нет гиперссылок, и браузер рисует эту оранжевую рамку вокруг всего экрана - или, более конкретно, вокруг внешнего <div id="battle">
, к которому я подключаю события через jQuery.
Неправильные события: В моем touchstart
обработчике событий я звоню event.preventDefault()
, чтобы сообщить браузеру не прокручивать, не синтезировать события мыши и т. Д. Поэтому я ожидаю получить только touchstart
иtouchend
событий.И я делаю, для первого крана.Но вместо touchstart
/ touchend
для второго касания я получаю все количество комбинаций событий касания, синтезированных событий мыши и случайных touchcancel
для второго касания или даже повторяющихся событий для первого касания.Подробности ниже.
Такое поведение также имеет место только в очень особых обстоятельствах:
- Первый сигнал должен быть коротким (менее ~ 200 мс).
- Второй сигналдолжно произойти быстро после этого (менее чем ~ 450 мс после первого касания
touchstart
). - Второй отвод должен находиться на расстоянии не менее 150 пикселей от первого касания (измеряется по диагонали от координат первого касания).
touchstart
). - Если я удаляю код, перехватывающий
mousedown
и mouseup
, оранжевые прямоугольники больше не появляются.Тем не менее, сенсорные события иногда все еще искажены.
Что я имею в виду под искаженными событиями, вот что я вижу.Когда я пишу «1:», это означает, что события предназначены для координат первого касания;«2:» означает координаты второго касания.Я видел следующие схемы событий (проценты показывают, сколько раз каждый из них появлялся после 100 испытаний):
- (50%) 1: touchstart 1: touchend 1: mousedown 1: mouseup (короткая задержка)) 2: mousedown 2: mouseup
- (35%) 1: touchstart 1: касание 2: touchstart 1: mousedown 1: mouseup 2: touchend
- (10%) 1: touchstart 1:touchend 2: touchstart 1: mousedown 1: mouseup 2: touchcancel (короткая задержка) 2: mousedown 2: mouseup
- (3%) 1: touchstart 1: touchend 2: touchstart 2: touchend (короткая задержка) 1: mousedown 1: mouseup
- (2%) 1: touchstart 1: touchend 1: mousedown 1: mouseup (и вообще ничего для второго нажатия)
Некоторые комбинации событий появляются чаще всего в зависимости от того, насколько быстро я нажимаю, но я не совсем прибил схему.(По второму пункту выше, скорее всего, появятся два быстрых, четких удара, в то время как более быстрый подход с меньшим акцентом на четкость кажется более вероятным первым пунктом. Но я не определил конкретные временные числа, которые приводят ккаждому.) Точно так же «короткие задержки», указанные выше, могут составлять от ~ 150 мс до ~ 400 мс;Я также не перепроектировал весь шаблон там.
Если я не подключу mousedown
и mouseup
, распределение будет примерно таким:
- (40%) 1: сенсорный запуск 1: касание 2: сенсорный запуск 2: касание
- (35%) 1: сенсорный запуск 1: касание 2: касание 2: касание (фактическое желаемое поведение)
- (25%) 1: запуск прикосновения 1: прикосновение (и вообще ничего для второго касания)
Так что, если я не перехватываю события мыши,это работает треть времени;и если бы я хотел сделать вид, что touchcancel
означало то же самое, что и touchend
, я мог бы получить это до 75% времени.Но это все еще довольно отстойно.
Альтернативы, которые я уже пробовал:
- Я пытался использовать jQuery Mobile
vmousedown
иvmouseup
события , но они не всегда запускаются при втором касании, я подозреваю, из-за этой же странности лежащего в основе события. - Я мог бы просто полностью забыть о событиях касания и использовать только синтезированную мышьсобытий, но обычно между задержкой физического нажатия и доставкой события синтезированной мыши обычно есть задержка примерно в полсекунды, тогда как события касания происходят немедленно, поэтому я могу быть более отзывчивым.Я также хочу предотвратить прокрутку - это для полноэкранной игры, и я бы предпочел, чтобы пользователь случайно не прокручивал адресную строку назад и не блокировал часть игры - и делал
preventDefault
на touchstart
обычно это достигается (хотя иногда второй тап действительно способен прокручивать экран, несмотря на мою preventDefault
... еще одну причину, по которой я хочу решить весь этот беспорядок событий). - Я пробовал стороннюю версиюВеб-браузер ( Dolphin ), но у него те же проблемы с событиями.Поэтому я предполагаю, что это, вероятно, проблема с тем, как базовый WebView доставляет события в сценарии.
Может кто-нибудь предложить способ изменить мой HTML, мои обработчики событий или что-то еще, чтобы надежнополучать события касания для двух быстрых нажатий подряд?