Событие touchhend не работает на Android
Я только начал изучать базовую мобильную веб-разработку на андроиде и написать тест script для исследования событий касания. Я запустил следующий код в эмуляторе Android, и событие touchhend никогда не запускается. Может ли кто-нибудь сказать мне, почему?
Я пробовал в трех версиях эмулятора (1.6, 2.1 и 2.2), и все три ведут себя одинаково.
Заранее благодарим за любую помощь, которую вы можете мне дать.
Cheers,
Колм
EDIT. Я также пробовал это с использованием инфраструктуры XUI и имею ту же проблему, поэтому я предполагаю, что у меня есть фундаментальное непонимание того, как это работает...
Проверка карты
<meta name="description" content="" />
<meta name="keywords" content="" />
<meta name="language" content="english" />
<meta name="viewport" content="minimum-scale=1.0,
width=device-width,
height=device-height,
user-scalable=no">
<script type="text/javascript">
window.onload = function(){
document.body.appendChild(
document.createTextNode("w: " + screen.width + " x " + "h : " +screen.height)
);
attachTouchEvents();
}
function attachTouchEvents() {
console = document.getElementById("console");
var map = document.getElementById("map");
map.addEventListener ('touchstart', function (event) {
event.preventDefault();
var touch = event.touches[0];
document.getElementById("touchCoord").innerHTML = "S : " + touch.pageX + " " + touch.pageY;
document.getElementById("touchEvent").innerHTML = "Touch Start";
}, false);
map.addEventListener ('touchmove', function (event) {
event.preventDefault();
var touch = event.touches[0];
document.getElementById("touchCoord").innerHTML = "M : " + touch.pageX + " " + touch.pageY;
document.getElementById("touchEvent").innerHTML = "Touch Move";
}, false);
map.addEventListener ('touchend', function (event) {
var touch = event.touches[0];
document.getElementById("touchCoord").innerHTML = "E : " + touch.pageX + " " + touch.pageY;
document.getElementById("touchEvent").innerHTML = "Touch End";
event.preventDefault();
}, false);
console.innerHTML = "event attached";
}
</script>
<style type="text/css">
html, body {
height:100%;
width:100%;
margin: 0;
background-color:red;
}
#map {
height: 300px;
width: 300px;
background-color:yellow;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="touchCoord">Touch Coords</div>
<div id="touchEvent">Touch Evnt</div>
<div id="console">Console</div>
</body>
Ответы
Ответ 1
Для тех, кто пытается понять, почему в Android версии v3 и v4 отсутствуют события (возможно, v2.3), существует длинная выдающаяся ошибка, которая только что была исправлена в v4.1 (по-видимому):
http://code.google.com/p/android/issues/detail?id=4549
http://code.google.com/p/android/issues/detail?id=19827
Чтобы обойти эту ошибку, вы должны называть preventDefault()
на сенсорном экране или в первом событии touchmove. Конечно, это предотвращает естественную прокрутку, поэтому вам нужно будет повторно реализовать это самостоятельно.
Ответ 2
Вот как вам нужно правильно его использовать. Вы фиксируете начальный x, y, когда палец идет на экран. Когда палец перемещается, событие touchmove обновляет окончание x, y. Когда закончите, коснется огонь, но да, у него нет массива касаний и, следовательно, ошибка JavaScript. Вот почему мы используем его только для того, чтобы зафиксировать, что это конечная задача (пальцы покинули экран), а затем реагируют на нее. (В этом случае я посылаю информационное предупреждение.)
var gnStartX = 0;
var gnStartY = 0;
var gnEndX = 0;
var gnEndY = 0;
window.addEventListener('touchstart',function(event) {
gnStartX = event.touches[0].pageX;
gnStartY = event.touches[0].pageY;
},false);
window.addEventListener('touchmove',function(event) {
gnEndX = event.touches[0].pageX;
gnEndY = event.touches[0].pageY;
},false);
window.addEventListener('touchend',function(event) {
alert('START (' + gnStartX + ', ' + gnStartY + ') END (' + gnEndX + ', ' + gnEndY + ')');
},false);
Ответ 3
Это веб-разработка, поэтому я создаю веб-страницу, которая может использовать события касания.
Я понял, в чем проблема.
Когда событие touchend
запущено, массив event.touches[]
пуст, поэтому возникает ошибка Javascript. Событие запускалось, но ничего не выдавало, потому что я пытался получить доступ к данным undefined. У браузера эмулятора, похоже, нет каких-либо инструментов отладки Javascript, которые я нашел, и даже не сказал мне, когда произошла ошибка Javascript, поэтому мне потребовалось некоторое время, чтобы понять это.
Ответ 4
TouchList всегда пуст при запуске события, потому что вы удалили все пальцы с экрана:).
http://www.sitepen.com/blog/2008/07/10/touching-and-gesturing-on-the-iphone/
Ответ 5
map.addEventListener ('touchend', function (event) {
var touch = event.changeTouches[0];
...
}
Ответ 6
У меня была та же проблема, и дополнительно связать событие "touchcancel" решила его. Было ли какое-то тестирование и когда "touchhend" не был уволен, тогда вместо этого произошло событие "touchcancel".
var onTouchEnd = function(){
console.log("touch end");
}
document.addEventListener("touchend", onTouchEnd);
document.addEventListener("touchcancel", onTouchEnd);
Ответ 7
Это происходит на KitKat и решается путем обработки touchcancel в соответствии с android dev http://developer.android.com/guide/webapps/migrating.html#TouchCancel
Для старых версий для Android проблема связана с тем, что андроид не передает события касания к веб-просмотру, если preventdefault не применяется к событию touchstart. Это жестко закодировано в миллионы устройств Android. https://github.com/TNT-RoX/android-swipe-shim
Ответ 8
Я смог устранить проблему, вызвав событие touchend
вручную в событии motion ACTION_UP
из активности, которая содержит WebView, как это:
//onCreate method
webView.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View view, MotionEvent motionEvent)
{
if(motionEvent.getAction() == MotionEvent.ACTION_UP)
{
webView.loadUrl("javascript:document.dispatchEvent(new CustomEvent('touchend'))");
}
return false;
}
});
Ответ 9
Здесь разрешено поддерживать прокрутку:
Добавьте preventDefault()
в обработчик touchMove, но оберните его в условное выражение, которое проверяет движение боковой прокрутки:
onTouchStart = function (e) { // Save start position
startX = e.originalEvent.touches[0].pageX;
startY = e.originalEvent.touches[0].pageY;
}
onTouchMove = function (e) {
currentX = e.originalEvent.touches[0].pageX;
currentY = e.originalEvent.touches[0].pageY;
translateY = Math.abs(currentY - startY);
if (translateY < 10) { // If we are not (yet) scrolling vertically:
e.preventDefault()
}
}