web-dev-qa-db-fra.com

Appareil tactile, gestionnaire d'événements simple et double pression jQuery / Javascript?

Contexte:

Mon site est en solution de commerce électronique open source magento, et en haut (en-tête), il a une icône de panier d'achat. Sur dekstop, lorsque l'utilisateur passe la souris sur cette icône, il affiche le contenu (articles) dans le panier. Mais au clic de cette icône, il amène l'utilisateur à la page du panier.

je veux:

Je veux avoir la possibilité, uniquement pour les appareils tactiles, que lorsqu'un utilisateur tape une seule fois sur l'icône, il ne doive afficher que le contenu, mais lorsque vous appuyez deux fois sur l'icône, il doit les amener à la page du panier.

CODE HTML:

<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>

Ce que j'ai déjà essayé:

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

Ce code n'empêche pas le comportement par défaut au simple toucher, mais n'affiche pas la div du contenu, ne fait rien non plus au double toucher. Soit dit en passant, je le teste sur Samsung Galaxy, je ne sais pas si c'est un appareil correct pour les tests et j'utilise JQUERY PLUGIN (pas jquery mobile).

15
atif

Si vous souhaitez cibler le mobile, vous pouvez utiliser touchstart qui est l'équivalent tactile de mousedown. bien que les navigateurs de bureau tactiles puissent également l'utiliser, vous devrez peut-être toujours faire une détection d'agent utilisateur si cela ne vous convient pas. La dernière fois que j'ai vérifié, il n'y avait pas d'événement "double tap" intégré auquel nous pouvons nous connecter, mais nous pouvons vérifier manuellement un tap ou un tap double. Le code ressemblerait à quelque chose

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

Démo

Cela devrait fonctionner sur n'importe quel navigateur tactile.

Une alternative, bien qu'un peu lourde pour cela, consiste à utiliser Hammer.js . C'est une bibliothèque vraiment agréable pour gérer les événements tactiles. Et il regroupe également les événements de souris et tactiles en un seul type d'événement. Par exemple, pour le tapotement et le tapotement double, ce sera essentiellement

Hammer(el).on("tap", function() {
    //singletap stuff
});
Hammer(el).on("doubletap", function() {
    //doubletap stuff
});

Cela fonctionne également pour les événements de souris, ce qui n'est peut-être pas ce que vous voulez. Et c'est un peu exagéré si c'est juste pour ça. Mais si vous prévoyez de faire plus de choses liées au toucher, je recommanderais d'utiliser cette bibliothèque.

40
mfirdaus

C'est le code de travail final qui a fait la magie pour moi :) Je viens de copier et coller tout le code ici mais on peut l'utiliser en fonction de ses propres besoins.

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

c'est mon hack. C'est un petit bloc de code et cela devrait bien fonctionner sur les mobiles. Il définit une minuterie lorsque vous appuyez pour la première fois sur quelque chose, puis il vérifie si le deuxième tap est dans la plage de temps (600 ms dans cet exemple)

    // 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; }
    });
4
Maxwell09

Ceci peut également être réalisé en utilisant 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>

Selon la valeur de la variable de sortie (c'est-à-dire vrai ou faux), vous pouvez définir une action supplémentaire.

0
Sanmati Kumar Jain