如何在iPad的Safari浏览器中使用jQuery识别触摸事件?这是否可行?

203

是否可以使用jQuery在iPad的Safari浏览器上识别触摸事件?

我在Web应用程序中使用了mouseOver和mouseOut事件。由于没有像mouseOut和mouseMove这样的事件,iPad的Safari浏览器上是否有类似的事件?

8个回答

257

核心jQuery没有为触摸事件提供任何特殊功能,但您可以使用以下事件轻松构建自己的触摸事件:

  • touchstart
  • touchmove
  • touchend
  • touchcancel

例如,touchmove事件

document.addEventListener('touchmove', function(e) {
    e.preventDefault();
    var touch = e.touches[0];
    alert(touch.pageX + " - " + touch.pageY);
}, false);

这在大多数基于WebKit的浏览器中有效(包括Android)。

这里有一些很好的文档


2
非常感谢,David。我认为它会起作用,但是 e.touches[0] 是什么?你能详细描述一下参数“e”吗? - Abhishek B.
7
e是自动传递给处理程序的事件对象。对于Safari浏览器(以及Android),它现在包含用户在屏幕上进行的所有触摸的数组。每个触摸都有自己的属性(例如x,y坐标)。 - David Pean
1
现在该怎么样找出要触发事件的元素呢 -__- - Muhammad Umer
请注意正确答案是由Timothy Perez提供的,这个答案已经过时了。 - EPurpl3

154
如果您使用的是jQuery 1.7+,那么比起其他回答,这甚至更加简单。
$('#whatever').on({ 'touchstart' : function(){ /* do something... */ } });

1
是的,Timothy,在我开始我的项目时我没有使用1.7+版本。现在我正在使用jquery 1.7+。感谢您的好建议和回复。非常感谢。 :) - Abhishek B.
8
这个很有效。我需要点击和触摸开始实现同样的功能,而且我习惯于使用非对象语法,像这样:$('#whatever').on('touchstart click', function(){ /* 做某事... */ }); - goodeye
我使用了Timothy Perez的解决方案,它有效了,但是goodeye的解决方案不行。有没有办法在新添加的元素中也更改Timothy Perez的代码? - edonbajrami
1
当我键入 $('#whatever').on({ 'touchstart' : function(ev){}}); 后,ev 看起来并没有关于触摸信息(touches、targetTouches 或 changedTouches)的任何信息。 - Octopus
8
你可以在 ev.originalEvent 下找到详细的信息。 - Peter Bloomfield
1
@edonbajrami 当然可以。查看文档并寻找“委托事件”。$("#element to monitor for new elements").on("eventX", "#element", function( event ) {/whatever/}); - honk31

32

仅使用touchstart或touchend并不是一个好的解决方案,因为如果您滚动页面,设备也会将其检测为触摸或点击事件。 因此,同时检测轻触和点击事件的最佳方法是仅检测未移动屏幕(滚动)的触摸事件。 要做到这一点,只需将此代码添加到您的应用程序中:

$(document).on('touchstart', function() {
    detectTap = true; // Detects all touch events
});
$(document).on('touchmove', function() {
    detectTap = false; // Excludes the scroll events from touch events
});
$(document).on('click touchend', function(event) {
    if (event.type == "click") detectTap = true; // Detects click events
       if (detectTap){
          // Here you can write the function or codes you want to execute on tap

       }
 });
我测试过它,在我的iPad和iPhone上可以正常运行。它可以检测到轻触,并且可以轻松区分轻触和滑动触摸。

2
这个解决方案似乎是我找到的最直接的,而且在iOS上运行得非常好。 - Joshua Lawrence Austill
我最初使用了jQuery Mobile,但它干扰了其他功能。现在我正在使用这个版本,运行得很完美,到目前为止没有任何问题。 - Anurag Priyadarshi

24

最简单的方法是使用类似 Hammer.js 的多点触控JavaScript库。然后你可以编写如下代码:

canvas
    .hammer({prevent_default: true})
    .bind('doubletap', function(e) { // And double click
        // Zoom-in
    })
    .bind('dragstart', function(e) { // And mousedown
        // Get ready to drag
    })
    .bind('drag', function(e) { // And mousemove when mousedown
        // Pan the image
    })
    .bind('dragend', function(e) { // And mouseup
        // Finish the drag
    });

你可以继续使用它。 它支持轻按、双击、滑动、长按、变换(即捏)和拖动。当发生相应的鼠标操作时,触摸事件也会触发,因此您不需要编写两组事件处理程序。哦,而且如果您想以我所做的jQueryish方式编写代码,您需要使用jQuery插件。


31
最简单的解决方案从来不涉及通过添加库使问题变得更加复杂。 - Octopus
14
使用 hammer.js 是最简单的解决方案,它抽象掉了跨浏览器的困扰。使用 jQuery 扩展,让你感到熟悉。对我来说似乎并不太复杂。 - trusktr
1
所谓的“最简单”的解决方案往往是人们最容易搞砸的...无论你做什么,千万不要忘记确保你的解决方案在支持触摸和鼠标的设备上都能正常工作,比如微软Surface。 - Simon_Weaver
1
@Octopus: "当你只有一把锤子时,每件事都看起来像是钉子" :) - iCollect.it Ltd
是锤子时间了!感谢您分享这个库,它很容易安装在我的应用程序上并运行!由于事件处理程序不同,设置需要一点时间,但简单的console.log(event)会告诉您所需的内容。谢谢! - Andy

21

你可以使用.on()来捕获多个事件,然后在屏幕上测试触摸,例如:

$('#selector')
.on('touchstart mousedown', function(e){
  e.preventDefault();
  var touch = e.touches[0];
  if(touch){
    // Do some stuff
  }
  else {
    // Do some other stuff
  }
});

除了.bind已被弃用外,你应该使用.on - jcuenod

15

jQuery核心没有什么特别之处,但您可以在jQuery Mobile事件页面上阅读有关不同触摸事件的信息。这些事件也适用于除iOS设备以外的其他设备。

它们包括:

  • tap (轻触)
  • taphold(长按)
  • swipe(滑动)
  • swipeleft(向左滑动)
  • swiperight(向右滑动)

值得注意的是,iOS设备在滚动事件(基于移动设备的触摸)期间会冻结DOM操作。


感谢您抽出宝贵的时间回答我的问题。我正在研究Jquery Mobile事件。谢谢。 - Abhishek B.
这些事件并不能真正代表实际的触摸交互。 - trusktr
jQuery Core是一个真正的专有名词吗? - Peter Mortensen

6

我有点担心只使用touchmove来完成我的项目,因为它似乎只在您的触摸从一个位置移动到另一个位置时(而不是在初始触摸时)触发。所以我将其与touchstart结合使用,这对于初始触摸和任何移动都非常有效。

<script>

function doTouch(e) {
    e.preventDefault();
    var touch = e.touches[0];

    document.getElementById("xtext").innerHTML = touch.pageX;
    document.getElementById("ytext").innerHTML = touch.pageY;   
}

document.addEventListener('touchstart', function(e) {doTouch(e);}, false);
document.addEventListener('touchmove', function(e) {doTouch(e);}, false);

</script>

X: <div id="xtext">0</div>
Y: <div id="ytext">0</div>

我还添加了这个来检测自上一个事件以来经过了多长时间。 document.getElementById("ttime").innerHTML = ((new Date()) - touchTime); touchTime = new Date(); - hanamj

3

我刚刚测试了benmajor的GitHub jQuery触摸事件插件,适用于jQuery 1.4和1.7+版本。它很轻量级,可以完美地配合onbind使用,并提供支持一系列触摸事件的全面功能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接