最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - jQuery update (1.7) breaks event coords on touch event? - Stack Overflow

programmeradmin0浏览0评论

This jsfiddle reproduces the problem and allows you to quickly switch between 1.6.4 and 1.7.1.

You'll see that LIs stop being detected, because the coords are undefined after switching to 1.7.1

/

How can I fix this problem without downgrading?

body{
    font-family: sans-serif;
}

#other{
position: absolute;
height: 300px;
width: 300px;
background: rgba(0,0,0,0.5);
}

#other ul{
position: absolute;
top: 50px;
right: 50px;
bottom: 50px;
left: 50px;
width: 200px;
height: 200px;
}

#other li{
    display: block;
    margin: 25px;
    height: 50px;
    width: 50px;
    color: white;
    background: rgba(0,0,0,0.5);
    float: left;

<div id="other">
   <ul>
       <li>LI</li>
       <li>LI</li>
       <li>LI</li>
       <li>LI</li>
   </ul>
</div>
<div id="output">
    output
<div>
$(document).bind('touchmove', function(event){
    event.preventDefault();              
});

$('#other').bind('touchstart touchmove', function(event){
    element = document.elementFromPoint(event.pageX, event.pageY);
    console.log(event);
    if(element.nodeName === 'LI'){
       $('#output').html('LI');
   }else{
       $('#output').html('NOT LI');     
   }    
});  

This jsfiddle reproduces the problem and allows you to quickly switch between 1.6.4 and 1.7.1.

You'll see that LIs stop being detected, because the coords are undefined after switching to 1.7.1

http://jsfiddle/eHHgP/2/

How can I fix this problem without downgrading?

body{
    font-family: sans-serif;
}

#other{
position: absolute;
height: 300px;
width: 300px;
background: rgba(0,0,0,0.5);
}

#other ul{
position: absolute;
top: 50px;
right: 50px;
bottom: 50px;
left: 50px;
width: 200px;
height: 200px;
}

#other li{
    display: block;
    margin: 25px;
    height: 50px;
    width: 50px;
    color: white;
    background: rgba(0,0,0,0.5);
    float: left;

<div id="other">
   <ul>
       <li>LI</li>
       <li>LI</li>
       <li>LI</li>
       <li>LI</li>
   </ul>
</div>
<div id="output">
    output
<div>
$(document).bind('touchmove', function(event){
    event.preventDefault();              
});

$('#other').bind('touchstart touchmove', function(event){
    element = document.elementFromPoint(event.pageX, event.pageY);
    console.log(event);
    if(element.nodeName === 'LI'){
       $('#output').html('LI');
   }else{
       $('#output').html('NOT LI');     
   }    
});  
Share Improve this question edited Dec 10, 2011 at 14:16 fancy asked Dec 10, 2011 at 11:01 fancyfancy 51.6k64 gold badges158 silver badges230 bronze badges 14
  • Could you try event.originalEvent.pageX instead? – pimvdb Commented Dec 10, 2011 at 11:07
  • @T.J.Crowder As far as I know the event object is passed from the dom unmodified, right? I didn't think jQuery should have any effect on it. – fancy Commented Dec 10, 2011 at 11:14
  • "I think because the coords are undefined with 1.7.1" Surely you can test that to be sure? – T.J. Crowder Commented Dec 10, 2011 at 11:14
  • @fancy: "As far as I know the event object is passed from the dom unmodified, right?" No, not at all, jQuery does a lot to it: api.jquery./category/events/event-object If you want the raw event object, it's available as event.originalEvent. – T.J. Crowder Commented Dec 10, 2011 at 11:15
  • 1 @T.J. Crowder: In 1.7, only properties which pass the following regexp get a "mouse status" and have their .pageX properties etc. passed through to the jQuery event object: github./jquery/jquery/blob/master/src/event.js#L7. Touch events don't pass this regexp. See also github./jquery/jquery/blob/master/src/event.js#L1041. – pimvdb Commented Dec 10, 2011 at 11:21
 |  Show 9 more ments

2 Answers 2

Reset to default 8

It turns out that in 1.7, only events which pass this regexp have certain "mouse properties" (like .pageX) passed through to the jQuery event object:

/^(?:mouse|contextmenu)|click/

Obviously, touchstart etc. don't pass this regexp. So you'd have to mark these events as being mouse events yourself, as jQuery does here. You can do it this way if you want to go for conciseness:

// add more if necessary, I don't know much about touch events
$.each("touchstart touchmove touchend".split(" "), function(i, name) {
    jQuery.event.fixHooks[name] = jQuery.event.mouseHooks;
});

Also another way to handle this is using the proper e.changedTouches. So it would work like this:

if (typeof e.changedTouches !== 'undefined') {
  pageX = e.changedTouches[0].pageX;
  pageY = e.changedTouches[0].pageY;
} else {
  pageX = e.pageX;
  pageY = e.pageY;
}

Hope this helps.

发布评论

评论列表(0)

  1. 暂无评论