Jquery function that prevents freezing when touched

I have a freeze function, if it is a touch device, I would like the hover event NOT to happen. The problem is that when you click on a link with a touch device, it makes a hang event before doing a click event, so you need to double-click it to make it work.

this is a hover function:

$("#close").hover( function () { $("#close_2").css({ display: "none" }); $("#close_1").css({ display: "block" }); }, function () { $("#close_1").css({ display: "none" }); $("#close_2").css({ display: "block" });; } ); 

and then I configured it as a click function:

 $('#close').click(function() { var id = $(this).attr('id'); $('#full_image').animate({ height: 0 }, 300, function() { $('#full_image img').attr('src','#'); }); $("#close_1").css({ display: "none" }); $("#close_2").css({ display: "none" }); $("#close").css({ display: "none" }); }); 
+8
jquery click jquery-hover
source share
5 answers

ended with touch detection:

 var deviceAgent = navigator.userAgent.toLowerCase(); var agentID = deviceAgent.match(/(iphone|ipod|ipad)/); if(agentID) { $('#close').click(function() { var id = $(this).attr('id'); $('#full_image').animate({ height: 0 }, 300, function() { $('#full_image img').attr('src','#'); }); $("#close_1").css({ display: "none" }); $("#close_2").css({ display: "none" }); $("#close").css({ display: "none" }); }); } else { $('#close').hover( function() { $("#close_2").css({ display: "none" }); $("#close_1").css({ display: "block" }); }, function() { $("#close_1").css({ display: "none" }); $("#close_2").css({ display: "block" }); } ); $('#close').click(function() { var id = $(this).attr('id'); $('#full_image').animate({ height: 0 }, 300, function() { $('#full_image img').attr('src','#'); }); $("#close_1").css({ display: "none" }); $("#close_2").css({ display: "none" }); $("#close").css({ display: "none" }); }); } 
-5
source share

Make the .hover () method more explicit and combine it with .on ():

 var $close1 = $('#close_1'), $close2 = $('#close_2'); $('#close').on({ mouseenter: function(){ $close2.css({display:'none'}); $close1.css({display:'block'}); }, mouseleave: function(){ $close1.css({display:'none'}); $close2.css({display:'block'}); } }); 

Then combine this with .off ().

 $('#close').on('touchstart',function(){ $(this).off('mouseenter,mouseleave'); }); 

If you want the event to fire when you click on touch devices, but when hovering on desktop devices, then place the functions as a separate function that you call in these actions accordingly.

EDIT

Some time has passed since I made this answer, here is the best way:

 $(function(){ var isTouchDevice = ('ontouchstart' in window || 'onmsgesturechange' in window), $close = $('#close'), $close1 = $('#close_1'), $close2 = $('#close_2'); if(!isTouchDevice){ $close.on({ mouseenter: function(){ $close2.hide(); $close1.show(); }, mouseleave: function(){ $close1.hide(); $close2.show(); } }); } $close.on('click',function(){ $('#full_image').animate({height:0},300,function(){ $(this).find('img').attr('src','#'); }); $close.hide(); $close1.hide(); $close2.hide(); }); }); 

This does not require every event to fire with a β€œfreeze” warning, it basically sets up page loading capabilities without affecting the click event.

+11
source share

I think a clear approach would be this:

  • Detect if browser supports touch events
  • Add a hover event handler.

If you are already using something like Modernizr:

 if(!Modernizr.touch){ // only if the browser doesn't support touch events, // add the hover handler here. } //add the click handler here, as you want it bound no matter what 

See What is the best way to detect a touchscreen device using JavaScript? and What is the best way to detect a touchscreen device using JavaScript? for other options for detecting touch capabilities.

+5
source share

On a mobile phone, calling preventDefault in a touchstart event prevents mouse manipulation, mouseenter, mousedown, and related events. Detail: https://patrickhlauke.imtqy.com/touch/tests/results/

  $('#close').on('touchstart',function(e){ console.log('touchstart'); e.preventDefault(); //Do touch stuff }); 
+2
source share

Because of Windows 8 and Ultrabooks, I expect to see a lot of devices that support both touch events and pointers. As a result, I avoid automatically turning off the hover event, since it can potentially disrupt the site for a user with touch control using the mouse.

To solve this problem, I ended up using two different classes to display the .hover and .touch , as well as separate events for pointing and clicking.

I use jquery.finger to capture click events, although any plugin should work, it was the smallest.

HTML There will be something like:

 <li> <a>Some Link</a> <div>Some Content</div> </li> 

CSS will look something like this:

 li div {display:none;} li.hover div, li.touch div {display:block;} 

And Javascript using jQuery:

 // Caching whatever elements I'm using for the navigation a = $("a"); li = $("li"); // Set hover events li.hover( // Both hover in and out fire whenever the user taps, aggravating! function(e) { // Close unused menus li.not(this).removeClass("hover").removeClass("touch"); // Show this menu $(this).addClass( "hover" ); }, function(e) { // Only closes if the menu doesn't have .touch, hell yeah! li.removeClass("hover"); } ); // Set the tap event a.on('tap',function(e,data){ e.stopPropagation(); var thisParent = $(this.parentNode); // Close unused menus li.not(thisParent).removeClass("touch"); // Toggle the current menu thisParent.toggleClass("touch"); // The menu is open, so we don't need this class anymore li.removeClass("hover"); }); // Prevent the list items when being tapped from closing the drop down li.on('tap',function(e){e.stopPropagation();}); // Close drop downs when tapping outside the menus $(document).on('tap',function(e){ li.removeClass("touch"); }); 

An important departure here is how I add a separate .hover or .touch class depending on the event, as well as deleting unused classes. The order is very important, so the menu does not blink.

+1
source share

All Articles