document .click function for touch device

JqueryCss

Jquery Problem Overview


I've got a sub-nav that works using jquery - A user clicks on the top level list item, for instance 'services' which triggers the dropdown. The dropdown toggles via clicking the 'service' link. I've made it so a user can click anywhere on the screen to toggle the dropdown to a closed state. But as the site is responsive i want the user to be able to click (touch) anywhere on the screen to close the dropdown but my problem is that it's not working on the touch devices.

My code ive setup for the document click is:

$(document).click(function(event) { 

  if ( $(".children").is(":visible")) {
    $("ul.children").slideUp('slow');
  }
  
});

I'm assuming document.click might not work on touch devices, and if not, what work-around is there to achieve the same effect?

Thanks

Jquery Solutions


Solution 1 - Jquery

Update! In modern browsers, the click event will be fired for a tap, so you don't need to add extra touchstart or touchend events as click should suffice.

This previous answer worked for a time with browsers that thought a tap was special. It originally included a "touch" event that actually was never standardised.

Unless you have a problem with:

$(document).on('click', function () { ... });

There is no need to change anything!

Previous information, updated to remove touch...

To trigger the function with click or touch, you could change this:

$(document).click( function () {

To this:

$(document).on('click touchstart', function () {

The touchstart event fires as soon as an element is touched, so it may be more appropriate to use touchend depending on your circumstances.

Solution 2 - Jquery

touchstart or touchend are not good, because if you scroll the page, the device do stuff. So, if I want close a window with tap or click outside the element, and scroll the window, I've done:

$(document).on('touchstart', function() {
	documentClick = true;
});
$(document).on('touchmove', function() {
	documentClick = false;
});
$(document).on('click touchend', function(event) {
	if (event.type == "click") documentClick = true;
    if (documentClick){
        doStuff();
    }
 });

Solution 3 - Jquery

Solution 4 - Jquery

To apply it everywhere, you could do something like

$('body').on('click', function() {
if($('.children').is(':visible')) {
$('ul.children').slideUp('slow');
}
});

Solution 5 - Jquery

As stated above, using 'click touchstart' will get the desired result. If you console.log(e) your clicks though, you may find that when jquery recognizes touch as a click - you will get 2 actions from click and touchstart. The solution bellow worked for me.

//if its a mobile device use 'touchstart'
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
 	deviceEventType = 'touchstart'
} else {
//If its not a mobile device use 'click'
	deviceEventType = 'click'
}

$(document).on(specialEventType, function(e){
    //code here
});

Solution 6 - Jquery

the approved answer does not include the essential return false to prevent touchstart from calling click if click is implemented which will result in running the handler twoce.

do:

$(btn).on('click touchstart', e => { 
   your code ...
   return false; 
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDoidgeyView Question on Stackoverflow
Solution 1 - JqueryFentonView Answer on Stackoverflow
Solution 2 - JqueryaleView Answer on Stackoverflow
Solution 3 - JquerySSAView Answer on Stackoverflow
Solution 4 - JqueryayypView Answer on Stackoverflow
Solution 5 - JqueryAaron ShierView Answer on Stackoverflow
Solution 6 - JquerykofifusView Answer on Stackoverflow