atif atif - 3 months ago 26
jQuery Question

Touch device, Single and Double Tap Events handler jQuery/Javascript?

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 mouse over that icon, it shows the content (items) in shopping cart. But on click of that icon, it takes the user to shopping cart page.

I want:

I want to have the ability, only for touch devices, that when a user single tap on icon, it should display the content only, but when double tap the icon, it should take them to the cart page.

HTML CODE:

<div id="mini-cart" class="dropdown is-not-empty">

<!-- This below div is always visible and on tap of this or either of it's any elements, required behaviour is expected -->
<div class="dropdown-toggle cover" title="View Bag">
<div class="feature-icon-hover">

<a href="example.com/checkout/cart/" title="Shopping Bag">
<span class="first close-to-text icon i-cart-wb force-no-bg-color">&nbsp;</span>
<div class="hide-below-960">My Bag</div>
</a>

<div class="label amount">
<a href="example.com/checkout/cart/" title="Shopping Bag">(1)</a>
</div>

<a class="summary" href="example.com/checkout/cart/" title="Shopping Bag">
<span class="subtotal">
<span class="price">$28</span>
</span>
</a>
<span class="caret">&nbsp;</span>

</div> <!-- end: dropdown-toggle > div -->
</div> <!-- end: dropdown-toggle -->

<!-- This one is invisible by default, and needs to be shown on single tap -->
<div class="dropdown-menu left-hand" style="display: none;">
<!-- All THE CONTENT GOES HERE -->
</div>
</div>


What I already tried:

jQuery(function($){
/* Code to detect the user agent, if mobile device then execute the code*/
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ) {

// on single touch
$("#mini-cart .dropdown-toggle").on('click', 'a', function(e){
e.preventDefault();
$("#mini-cart .dropdown-menu").show();
});

// on double touch
$("#mini-cart .feature-icon-hover").find('a').dblclick(function(e){
location.href = '/checkout/cart';
//alert('dblclick');
});
}
});


This code does prevent from default behaviour on single tap but does not show content div, also does not do anything on double tap. By the way, I am testing it on samsung galaxy, not sure whether it is a correct device for testing, and using JQUERY PLUGIN (not jquery mobile).

Answer

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);
                 });
            }
        }