Background:
My site is in magento open source ecommerce solution, and in the top (header) it has a shopping cart icon. On dekstop, when user hovers
this is my hack. It's a small code block and it should work well on mobiles. It sets a timer when you first tap on something and then it checks if the second tap is in the time range (600ms in this example)
// DOUBLE TAP
var timer = 0;
$(document).on("click" , "#target" , function() {
if(timer == 0) {
timer = 1;
timer = setTimeout(function(){ timer = 0; }, 600);
}
else { alert("double tap"); timer = 0; }
});
This is the final working code that did the magic for me :) I have just copied and paste all the code in here but one may use it in accordance to own needs.
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ) {
$('#dropdown_menu').css({ "right":'20%'});
var action;
$('#continue_shopping').show();
$('#continue_shopping').bind('touchstart click', function(event){
setTimeout(function(e){
$('#mini-cart').removeClass('open');
$('#dropdown_menu').hide();
}, 1200, [event]);
});
$('#dropdown-toggle').bind('touchstart', function(event){
var now = new Date().getTime();
var lastTouch = $(this).data('lastTouch') || now + 1 ;
var delta = now - lastTouch;
clearTimeout(action);
if(delta<500 && delta>0){
window.location='<?php echo $this->getUrl('checkout/cart');?>';
}else{
//if(delta == -1){
$('#mini-cart').addClass('open');
$('#dropdown_menu').show();
$(this).data('lastTouch', now);
action = setTimeout(function(e){
clearTimeout(action);
}, 500, [event]);
}
$(this).data('lastTouch', now);
});
if (typeof document.body.ontouchstart == "undefined") {
$('#dropdown-toggle').bind('click', function(event){
var now = new Date().getTime();
var lastTouch = $(this).data('lastTouch') || now + 1 ;
var delta = now - lastTouch;
clearTimeout(action);
if(delta<600 && delta>0){
window.location='<?php echo $this->getUrl('checkout/cart');?>';
}else{
//if(delta == -1){
$('#mini-cart').addClass('open');
$('#dropdown_menu').show();
$(this).data('lastTouch', now);
action = setTimeout(function(e){
clearTimeout(action);
}, 600, [event]);
}
$(this).data('lastTouch', now);
});
}
}
If you want to target mobile then you can use touchstart
which is the touch equivalent of mousedown
. though touch capable desktop browsers can also use this so maybe you still need to do user-agent detection if that doesn't suit you. Last I checked, there wasn't any built in "double tap" event we can hook onto, but we can manually check for a tap or a double tap. The code would look something like
var tapped=false
$("#mini-cart .dropdown-toggle").on("touchstart",function(e){
if(!tapped){ //if tap is not set, set up single tap
tapped=setTimeout(function(){
tapped=null
//insert things you want to do when single tapped
},300); //wait 300ms then run single click code
} else { //tapped within 300ms of last tap. double tap
clearTimeout(tapped); //stop single tap callback
tapped=null
//insert things you want to do when double tapped
}
e.preventDefault()
});
This should work on any touch enabled browser.
An alternative, though a bit heavy for just this, is to use Hammer.js. It's a really nice library for handling touch events. And it also aggregates mouse and touch events into one type of event. For example, for tap and double tap it'll essentially be
Hammer(el).on("tap", function() {
//singletap stuff
});
Hammer(el).on("doubletap", function() {
//doubletap stuff
});
This also works for mouse events too, which might not be what you want. And it is a bit overkill if it's just for this. But if you plan to do more touch related stuff, I would recommend using this library.
This can also be achieved using vanilla javascript =>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<button id="btn">click me</button>
<script>
let exit = false;
document.getElementById('btn').addEventListener('click', async () => {
let open = true;
document.getElementById('btn').addEventListener('click', () => {
if (open) {
exit = true;
}
});
function timeout(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
}).then(() => (open = false));
}
await timeout(1500);
console.log(exit);
});
</script>
</body>
</html>
According to the exit variable value (i.e. either true or false) you can define further action.