JQuery (Swipe vs. Touch) pageX и страницаY продолжают возвращаться 0
Я играю с touchstart и touchhend на моем iPhone. Я построил образец страницы с div, который, если вы коснетесь его и прокрутите страницу, он должен вернуть y координаты начальной и конечной позиции.
ссылка: http://jsbin.com/ibemom/2
jQuery:
var touchStartPos;
$('.theDiv')
.bind('touchstart', function(e){
touchStartPos = e.pageY;
})
.bind('touchend', function(e){
alert(touchStartPos + ' | ' + e.pageY)
})
Однако, когда я загружаю эту страницу на свой iPhone, предупреждение сообщает о том, что оба значения равны нулю. Кто-нибудь видит что-то не так с тем, что у меня есть?
UPDATE:
Я наткнулся на этот бит кода в проекте jQuery Mobile: https://github.com/jquery/jquery-mobile/issues/734
Комментарий от него:
// (in iOS event.pageX and event.pageY are always 0 )
Это не говорит, почему это дело, но по крайней мере я нашел кого-то другого, который видит то же самое. Прокопайте код примера на этой странице, чтобы узнать, есть ли решение.
ОБНОВЛЕНИЕ II:
Хорошо, посмотрев пример кода в приведенной выше ссылке, похоже, что это вернет фактическое значение:
e.originalEvent.touches[0].pageY
Уловка, я теперь понимаю, что не совсем мне нужно. Он возвращает смещение Y области, к которой я коснулся объекта, который я привязал событие к IN RELATION TO HTML DOCUMENT... а не к окну браузера.
Моя цель - выяснить, где на экране началось касание, и где оно закончилось... и затем сравните значения. Если они немного разные, то мы представляем, что салфетки были выполнены... а не прикосновение.
ОБНОВЛЕНИЕ III:
Я также нахожу ссылки на эти примеры:
e.originalEvent.touches[0].pageX
event.targetTouches[0].pageY
Хотя я не могу заставить их работать. Оба возвращают ошибки undefined.
ОБНОВЛЕНИЕ IV:
Похоже, что одним из решений является отслеживание offset() для самого документа. Я могу применить событие touchhend к документу, а затем проверить его смещение.
Проблема с этим в том, что мое событие touchhend будет сначала запускаться на элементе на моей странице, а затем он загорится над документом (пузырь). Поэтому я не могу определить, было ли это прикосновение или проведите пальцем. Прежде чем мне нужно выяснить, что делать с объектами touchhend.
Еще обдумывая этот...
Ответы
Ответ 1
Хорошо быстрый ответ: вы не можете обнаружить прикосновение, когда палец покидает экран (touchend
).
Мой первый пример доказывает, что: http://jsfiddle.net/Y4fHD/
Теперь обходной путь. Или называй это тем, что хочешь. Возможно, в событии touchend
не имеет смысла обнаружение, потому что нажатие закончилось.
Привяжите обработчик к событию touchmove
: http://jsfiddle.net/Y4fHD/1/
var endCoords = {};
$(document.body).bind("touchmove", function(event) {
endCoords = event.originalEvent.targetTouches[0];
});
И затем используйте переменную endCoords
для определения последнего касания
$(document.body).bind("touchend", function(event) {
$('p').text("Your end coords is: x: " + endCoords.pageX + ", y: " + endCoords.pageY);
});
Хорошо, просто нажмите на свое устройство! Тогда ошибка все равно будет выглядеть: Почему? Потому что вы не тронули ваше прикосновение.
Если все мы готовы в touchstart
, мы определяем переменную endCoords
: http://jsfiddle.net/Y4fHD/2/
var endCoords = {};
$(document.body).bind("touchstart touchmove", function(event) {
endCoords = event.originalEvent.targetTouches[0];
});
И затем используйте переменную endCoords
для определения последнего касания
$(document.body).bind("touchend", function(event) {
$('p').text("Your end coords is: x: " + endCoords.pageX + ", y: " + endCoords.pageY);
});
Теперь попробуйте нажать на свое устройство!
Некоторые заключительные примечания будут следующими: Сделайте для переменных: startCoords
и endCoords
, затем используйте их в событии touchend
: http://jsfiddle.net/Y4fHD/3/
var startCoords = {}, endCoords = {};
$(document.body).bind("touchstart", function(event) {
startCoords = endCoords = event.originalEvent.targetTouches[0];
});
$(document.body).bind("touchmove", function(event) {
endCoords = event.originalEvent.targetTouches[0];
});
$(document.body).bind("touchend", function(event) {
$('p').text("Your touch on the axis: " + Math.abs(startCoords.pageX-endCoords.pageX) + "x, " + Math.abs(startCoords.pageY-endCoords.pageY) + "y");
});
Примечание:
Ни один из вышеприведенных примеров не проверен, надеется, что это сработает!
Math.abs
дает мне абсолютное значение числа, например: -5 становится 5
Ответ 2
Существует упрощенный фрагмент кода, который я использую для обнаружения жестов для прокрутки .myelement, в оригинале это галерея слайдера
$(function() {
var diff, tchs, del = 150,
clk = function(el){
if ( typeof(tchs) !== 'object' ) return; //we have nothing to do
if ( (diff - tchs[tchs.length - 1].pageX) < 0 ) { //swipe right
}
else if ( (diff - tchs[tchs.length - 1].pageX) > 0 ) { //swipe left
}
};
$('.myelement').bind('touchstart touchmove', function(ev){
var oev = ev.originalEvent, el = $(this);
switch( ev.type.charAt(5) ){
case 's': //touch start
diff = oev.pageX;
window.setTimeout(clk, del, el);
break;
case 'm': //touch move
tchs = oev.touches;
break;
}
});
});
UPD: кстати, когда я использовал программное обеспечение MobiOne версии 2.0.0M2 Testing Center, оно поместило значение touchhend pageX, как и ожидалось, так что это звучит плохой вариант, который может смутить, если у вас нет быстрого доступа к реальное устройство.
UPD2: хорошо, вдохновленный положительной обратной связью:) реализована бит сложная версия, которая позволяет обнаруживать правильные, левые, вверх и вниз щелчки, но еще нужно очистить, но вы получили эту идею.
$(function () {
var ftch, // first touch cache
lck = Math.sin(Math.PI / 4); //lock value, sine of 45 deg configurable
var defSwipeDir = function (el, tchs) { // need define swaping direction, for better UX
if (typeof (tchs) !== 'object') return 0; // check if there was any movements since first touch, if no return 0
var ltch = tchs[tchs.length - 1], // last touch object
dx = ltch.pageX - ftch.pageX,
dy = ltch.pageY - ftch.pageY,
hyp = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)),
sin = dy / hyp,
cos = dx / hyp,
dir;
if (Math.abs(cos) >= lck) { // left or right swape
dir = cos > 0 ? 'r' : 'l';
} else { // up or down
dir = sin < 0 ? 'u' : 'd';
}
el.trigger('swipe', dir); // trigger custom swipe event
return dir; // and return direction too
}
$('.myelementTouchDetection').on('touchstart touchmove swipe', function (ev, d) {
var oev = ev.originalEvent,
myelementTouchDetection = $(this),
dir; // you may know swipes on move event too
switch (ev.type) {
case 'touchstart':
ftch = oev;
break;
case 'touchmove':
dir = defSwipeDir(myelementTouchDetection, oev.touches);
return false // cancel default behaiviour
break;
case 'swipe':
switch (d) {
case 'r': // swipe right
console.log('swipe right');
break;
case 'l': // swipe left
console.log('swipe left');
break;
case 'u': // swipe up
console.log('swipe up');
break;
case 'd': // swipe down
console.log('swipe down');
break;
}
break;
}
})
});
Ответ 3
Ответ NULL, выше, отлично работал у меня, за исключением того, что вы не можете назначать startCoords для endCoords в функции, связанной с touchstart. Затем они указывают на один и тот же объект, так что, когда endCoords обновляется, также начинается startCoords. Когда происходит событие touchhend, startCoords всегда будет равно endCoords.
Обновлен код ниже. Это работало для меня на iPad 3 с использованием Safari на iOS 6.0. Отредактировано также, чтобы исправить ошибку математики и отображения и удалить Math.abs() внутри функции, связанной с touchhend. Также добавлен вызов event.preventDefault() внутри функции, связанной с touchmove, так что они будут работать и с Google Chrome на iOS.
var startCoords = {}, endCoords = {};
$(document.body).bind("touchstart", function(event) {
endCoords = event.originalEvent.targetTouches[0];
startCoords.pageX = event.originalEvent.targetTouches[0].pageX;
startCoords.pageY = event.originalEvent.targetTouches[0].pageY;
});
$(document.body).bind("touchmove", function(event) {
event.preventDefault();
endCoords = event.originalEvent.targetTouches[0];
});
$(document.body).bind("touchend", function(event) {
$('p').text("Your touch on the axis: " + (endCoords.pageX-startCoords.pageX) + "x, " + (endCoords.pageY-startCoords.pageY) + "y");
});
Ответ 4
Вот что работает для меня....
$('.someClass').bind('touchmove',function(e){
e.preventDefault();
var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
var elm = $(this).offset();
var x = touch.pageX - elm.left;
var y = touch.pageY - elm.top;
if(x < $(this).width() && x > 0){
if(y < $(this).height() && y > 0){
//your code here
}
}
});