touchend event in ios webkit not firing?

Craig picture Craig · Oct 7, 2011 · Viewed 19.7k times · Source

I'm trying to implement a menu for a ios webkit based app in which the user touches/clicks and holds a menu button ('.menu_item'), after 500ms the sub menu opens (div.slide_up_sub_menu), and a user should be able to slide their finger/mouse up to a submenu li item and release.

    <li class="menu_item">
       ASSET MANAGEMENT
       <div class="slide_up_sub_menu hidden_menu">
         <ul class="submenu">
           <li>Unified Naming Convention</li>
           <li>Version Control</li>
         </ul>
       </div>
    </li>

The application should then be able to detect which submenu item the touchend/mouseup event happened on. I'm binding a touchstart event to the menu item, waiting for 500ms, and afterwards telling the submenu to show. When a user releases their finger a touchend event should fire closing the submenu. If the user has stopped their touch on a submenu item it should be detected. Currently detection of which submenu item a mouseup event happened on works in Safari on the desktop:

$('ul.submenu li').live('mouseup', function(e){
   console.log($(e.currentTarget)); //works on the desktop
});

but if I do the same using a touchend handler it doesn't work on an ipad:

$('ul.submenu li').live('touchend', function(e){
   console.log($(e.currentTarget)); //never fires
});

if I look for every touchend event I can get a reference to the parent sub menu item when I end the touch on a submenu item:

$(document.body).bind('touchend', function(e) {
    console.log($(e.target).html()); //logs ASSET MANAGEMENT
 });

but no reference to the submenu item.

Does anyone have any idea why a touchend event is not being fired on the submenu items?

Thanks

Answer

Stefan picture Stefan · Jun 11, 2012

touchend does not fire because touchcancel has fired earlier. If you want full touch evens handling you need to call

e.preventDefault()

in the callback of "touchmove" event, otherwise when a touchmove event occurs if the browser decides that this is a scroll event it will fire touchcancel and never fire touchend.