Событие мобильного события jQuery запускается дважды
Я тестировал событие jquery mobile 'tap' и обнаружил, что он запускал два раза, каждый раз, когда он запускается. Код, как показано ниже для страницы html:
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.js"></script>
<style>
#box{
background-color:red;
width:200px;
height:200px;
}
</style>
</head>
<body>
<div id="box">
tapped me
</div>
<script type="text/javascript">
$(document).ready(function() {
$('#box').bind('tap',function(event) {
alert('why');
});
});
</script>
</body>
</html>
Больше иронии, когда я проверяю это на jsfiddle, он только запускал событие для один раз.
Здесь ссылка.
http://jsfiddle.net/mochatony/tzQ6D/6/
После дальнейшего тестирования я узнал, что ошибка ушла с размещением javascript в разделе заголовка.
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js">
</script>
<script type="text/javascript" src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.js">
</script>
<style type="text/css">
#box{ background-color:red; width:200px; height:200px; }
</style>
<script type="text/javascript">
$(document).ready(function() {
$('#box').bind('tap', function(event) {
alert('halo');
});
});
</script>
</head>
<body>
<div id="box">
tapped me
</div>
</body>
</html>
Я не мог объяснить, почему размещение в разделе body и header делает это другим.
Ответы
Ответ 1
Я забыл, где я это видел, но проблема в том, что jQuery Mobile привязан к событиям касания и мыши, чтобы имитировать "кран", и в некоторых случаях Android будет запускать оба.
Трюк, который работал у меня, - это вызвать preventDefault
в событии в обработчике событий. Это предотвратит срабатывание дублирующего события.
Насколько это возможно, иногда я знаю, что мобильные браузеры будут пытаться только запустить версию мыши, если кто-то не слушает сенсорную версию. Там может быть проблема с обнаружением или делегированием jQuery, что сбивает с толку эвристику.
Ответ 2
У вас возникает проблема с призрачным щелчком... Это известная "ошибка" и трудно решить.
Дополнительная информация:
http://forum.jquery.com/topic/tap-fires-twice-with-live-tap
https://developers.google.com/mobile/articles/fast_buttons
http://philosopherdeveloper.wordpress.com/2011/11/01/ghost-clicks-in-jquery-mobile/
В первой ссылке вы найдете хак, который делает трюк. Насколько я знаю, нет простого решения: (
Кстати: даже если это не решит вашу проблему, @Sagiv прав. JQuery mobile часто использует ajax для изменения страницы и поэтому не запускает событие document.ready.
Ответ 3
на странице jQuery Mobile:
Важно: используйте $(document).bind('pageinit'), а не $(document).ready()
Первое, что вы узнали в jQuery, - это вызвать код внутри $(document).ready(), поэтому все будет выполняться, как только Загружается DOM. Однако в jQuery Mobile Ajax используется для загрузки содержимое каждой страницы в DOM при навигации и готовность DOM обработчик выполняется только для первой страницы. Выполнять код всякий раз, когда новая страница загружается и создается, вы можете привязываться к событию pageinit. Это событие подробно описано в нижней части этой страницы.
поэтому пропустите $(document).ready()
. подробнее здесь.
Ответ 4
связанный с этим вопросом, я получал два события 'tap' и 'click' один сразу после другого. Все идеи здесь вдохновляли, но я нашел другое решение. Я добавил следующий код к моему контроллеру JavaScript, чтобы различать последовательные дублированные события на основе временной метки, которая, к счастью, точно такая же для двух повторяющихся событий. В основном, я делаю это, чтобы сохранить последнюю использованную метку времени, если я решаю использовать это событие. Во второй раз, когда событие с той же меткой времени я просто отбросил.
var _lastEventTimestamp;
var checkAndPreventDuplicatedEvent = function (e) {
if (e.timeStamp === _lastEventTimestamp) return true;
else _lastEventTimestamp = e.timeStamp;
return false;
}
Ответ 5
$("#buttonID").tap(function(event){
if(localStorage.JQMGostClick == 0 || localStorage.JQMGostClick == "" || typeof(localStorage.JQMGostClick) === "undefined")
localStorage.JQMGostClick = 1;
else if(localStorage.JQMGostClick == 1){
localStorage.JQMGostClick = 0;
return false;
}
.....
});
Он работает для меня, поскольку, если вы используете мобильную среду, то, вероятно, вы используете своего рода хранилище
Ответ 6
Я узнал, что в моем случае добавление data-role="page"
к моему контейнеру страницы предотвращало дважды срабатывание событий крана.
Ответ 7
Я испытал нечто подобное раньше, и это произошло из-за того, что моя форма не была внутри data-role="page"
То, что я хотел бы предложить, - это обернуть свой код с помощью html-структуры jQuery Mobile, чтобы ваш вариант мог выглядеть так:
<div data-role="page" class="ui-page ui-page-theme-a ui-page-active">
<div class="ui-content">
<div id="box">
tapped me
</div>
<script type="text/javascript">
$(document).ready(function() {
$('#box').bind('tap',function(event) {
alert('why');
});
});
</script>
</div>
</div>
Ответ 8
Это может быть не лучшее решение и будет работать только в некоторых случаях, но то, что сработало для меня, было сразу же после того, как началось событие click, чтобы установить "указатель-события" CSS для этого элемента в "none". Затем с помощью JS setTimeout reset "указатели-события" будут автоматически после 500 мс.
Для меня достаточно 300 мкс для устройств Android, но для iPhone требуется 500 мс, чтобы предотвратить двойной щелчок.
function yourEvent(evt){
$(el).css('pointer-events', 'none');
setTimeout(function(){
$(el).css('pointer-events', 'auto');
}, 500);
//do you stuff
}