web-dev-qa-db-fra.com

Longue pression en JavaScript?

Est-il possible d'implémenter "long press" en JavaScript (ou jQuery)? Comment?

alt text http://androinica.com/wp-content/uploads/2009/11/longpress_options.png

HTML

<a href="" title="">Long press</a>

JavaScript

$("a").mouseup(function(){
  // Clear timeout
  return false;
}).mousedown(function(){
  // Set timeout
  return false; 
});
99
Randy Mayer

Il n'y a pas de magie 'jQuery', juste des minuteries JavaScript.

var pressTimer;

$("a").mouseup(function(){
  clearTimeout(pressTimer);
  // Clear timeout
  return false;
}).mousedown(function(){
  // Set timeout
  pressTimer = window.setTimeout(function() { ... Your Code ...},1000);
  return false; 
});

Basé sur la réponse de Maycow Moura, j'ai écrit ceci. Cela garantit également que l'utilisateur ne fait pas un clic droit, ce qui déclencherait une pression longue et fonctionnerait sur les appareils mobiles. DEMO

var node = document.getElementsByTagName("p")[0];
var longpress = false;
var presstimer = null;
var longtarget = null;

var cancel = function(e) {
    if (presstimer !== null) {
        clearTimeout(presstimer);
        presstimer = null;
    }

    this.classList.remove("longpress");
};

var click = function(e) {
    if (presstimer !== null) {
        clearTimeout(presstimer);
        presstimer = null;
    }

    this.classList.remove("longpress");

    if (longpress) {
        return false;
    }

    alert("press");
};

var start = function(e) {
    console.log(e);

    if (e.type === "click" && e.button !== 0) {
        return;
    }

    longpress = false;

    this.classList.add("longpress");

    if (presstimer === null) {
        presstimer = setTimeout(function() {
            alert("long click");
            longpress = true;
        }, 1000);
    }

    return false;
};

node.addEventListener("mousedown", start);
node.addEventListener("touchstart", start);
node.addEventListener("click", click);
node.addEventListener("mouseout", cancel);
node.addEventListener("touchend", cancel);
node.addEventListener("touchleave", cancel);
node.addEventListener("touchcancel", cancel);

Vous devez également inclure des indicateurs utilisant des animations CSS:

p {
    background: red;
    padding: 100px;
}

.longpress {
    -webkit-animation: 1s longpress;
            animation: 1s longpress;
}

@-webkit-keyframes longpress {
    0%, 20% { background: red; }
    100% { background: yellow; }
}

@keyframes longpress {
    0%, 20% { background: red; }
    100% { background: yellow; }
}
28
kelunik

Vous pouvez utiliser l'événement taphold de l'API mobile jQuery.

jQuery("a").on("taphold", function( event ) { ... } )
25
doganak

Même si cela semble assez simple à implémenter vous-même avec un délai d’expiration et quelques gestionnaires d’événements de souris, cela devient un peu plus compliqué lorsque vous considérez des cas comme clic-glisser-relâcher, prenant en charge à la fois l’appui et la pression longue sur le même élément et travailler avec des appareils tactiles comme l'iPad. J'ai fini par utiliser le plugin longclick jQuery ( Github ), qui s'occupe de ce travail pour moi. Si vous devez uniquement prendre en charge des périphériques à écran tactile tels que les téléphones mobiles, vous pouvez également essayer l’événement taphold jQuery Mobile .

15
ʇsәɹoɈ

plugin jQuery. Il suffit de mettre $(expression).longClick(function() { <your code here> });. Le deuxième paramètre est la durée de maintien; le délai d'attente par défaut est de 500 ms.

(function($) {
    $.fn.longClick = function(callback, timeout) {
        var timer;
        timeout = timeout || 500;
        $(this).mousedown(function() {
            timer = setTimeout(function() { callback(); }, timeout);
            return false;
        });
        $(document).mouseup(function() {
            clearTimeout(timer);
            return false;
        });
    };

})(jQuery);
10
piwko28

J'ai créé long-press-event(0.5k JavaScript pur)} pour résoudre ce problème, il ajoute un événement long-press au DOM.

Écoutez l'élément long-press sur any:

// the event bubbles, so you can listen at the root level
document.addEventListener('long-press', function(e) {
  console.log(e.target);
});

Écoutez un long-press sur un élément spécifique:

// get the element
var el = document.getElementById('idOfElement');

// add a long-press event listener
el.addEventListener('long-press', function(e) {

    // stop the event from bubbling up
    e.preventDefault()

    console.log(e.target);
});

Fonctionne dans les applications mobiles IE9 +, Chrome, Firefox, Safari et hybrides (Cordova et Ionic sur iOS/Android))

Démo

7
John Doherty
$(document).ready(function () {
    var longpress = false;

    $("button").on('click', function () {
        (longpress) ? alert("Long Press") : alert("Short Press");
    });

    var startTime, endTime;
    $("button").on('mousedown', function () {
        startTime = new Date().getTime();
    });

    $("button").on('mouseup', function () {
        endTime = new Date().getTime();
        longpress = (endTime - startTime < 500) ? false : true;
    });
});

DEMO

5
razzak

La réponse de Diodeus est géniale, mais cela vous empêche d'ajouter une fonction onClick, elle ne fonctionnera jamais si vous mettez un onclick. Et la réponse du Razzak est presque parfaite, mais elle ne fonctionne que sur la souris et généralement, la fonction est exécutée même si l’utilisateur continue de tenir.

Donc, j'ai rejoint les deux, et fait ceci:

$(element).on('click', function () {
    if(longpress) { // if detect hold, stop onclick function
        return false;
    };
});

$(element).on('mousedown', function () {
    longpress = false; //longpress is false initially
    pressTimer = window.setTimeout(function(){
    // your code here

    longpress = true; //if run hold function, longpress is true
    },1000)
});

$(element).on('mouseup', function () {
    clearTimeout(pressTimer); //clear time on mouseup
});
4
Maycow Moura

Pour les développeurs multiplateformes (Remarque Toutes les réponses données jusqu'à présent ne fonctionneront pas sur iOS) :

Mouseup/down semblait fonctionner correctement sur Android - mais pas sur tous les appareils, par exemple (Samsung Tab4). Ne fonctionnait pas du tout sur iOS .

Des recherches plus poussées semblent indiquer que cela est dû au fait que l'élément est sélectionné et que le grossissement natif interrompt l'auditeur.

Cet écouteur d'événements permet d'ouvrir une image miniature dans un mode de démarrage, si l'utilisateur détient l'image pendant 500 ms. 

Il utilise une classe d'image réactive affichant donc une version plus grande de l'image ..__ Ce code a été entièrement testé sur (iPad/Tab4/TabA/Galaxy4):

var pressTimer;  
$(".thumbnail").on('touchend', function (e) {
   clearTimeout(pressTimer);
}).on('touchstart', function (e) {
   var target = $(e.currentTarget);
   var imagePath = target.find('img').attr('src');
   var title = target.find('.myCaption:visible').first().text();
   $('#dds-modal-title').text(title);
   $('#dds-modal-img').attr('src', imagePath);
   // Set timeout
   pressTimer = window.setTimeout(function () {
      $('#dds-modal').modal('show');
   }, 500)
});
4
tyler_mitchell

Pour les navigateurs mobiles modernes:

document.addEventListener('contextmenu', callback);

https://developer.mozilla.org/en-US/docs/Web/Events/contextmenu

2
Kory Nunn

Vous pouvez définir le délai d'expiration de cet élément lorsque la souris est enfoncée et l'effacer lorsque cette dernière est activée:

$("a").mousedown(function() {
    // set timeout for this element
    var timeout = window.setTimeout(function() { /* … */ }, 1234);
    $(this).mouseup(function() {
        // clear timeout for this element
        window.clearTimeout(timeout);
        // reset mouse up event handler
        $(this).unbind("mouseup");
        return false;
    });
    return false;
});

Avec cela, chaque élément obtient son propre délai d'attente.

2
Gumbo

Le plus élégant et le plus propre est un plugin jQuery: https://github.com/untill/jquery.longclick/ , Également disponible en packacke: https: // www. npmjs.com/package/jquery.longclick .

En bref, vous l'utilisez comme ceci:

$( 'button').mayTriggerLongClicks().on( 'longClick', function() { your code here } );

L'avantage de ce plugin est que, contrairement à certaines des autres réponses ici, les événements de clic sont toujours possibles. Notez également qu'un clic long se produit, tout comme un clic long sur un périphérique, avant mouseup. Donc, c'est une fonctionnalité.

1
untill

Vous pouvez utiliser le taphold de jquery-mobile. Incluez le fichier jquery-mobile.js et le code suivant fonctionnera correctement

$(document).on("pagecreate","#pagename",function(){
  $("p").on("taphold",function(){
   $(this).hide(); //your code
  });    
});
1
Prashant_M

Vous pouvez vérifier le temps d'identifier Click ou appuyez longuement sur [jQuery]

function AddButtonEventListener() {
try {
    var mousedowntime;
    var presstime;
    $("button[id$='" + buttonID + "']").mousedown(function() {
        var d = new Date();
        mousedowntime = d.getTime();
    });
    $("button[id$='" + buttonID + "']").mouseup(function() {
        var d = new Date();
        presstime = d.getTime() - mousedowntime;
        if (presstime > 999/*You can decide the time*/) {
            //Do_Action_Long_Press_Event();
        }
        else {
            //Do_Action_Click_Event();
        }
    });
}
catch (err) {
    alert(err.message);
}
} 
0
Derin

Vous pouvez utiliser les événements jquery Touch. ( vois ici )

  let holdBtn = $('#holdBtn')
  let holdDuration = 1000
  let holdTimer

  holdBtn.on('touchend', function () {
    // finish hold
  });
  holdBtn.on('touchstart', function () {
    // start hold
    holdTimer = setTimeout(function() {
      //action after certain time of hold
    }, holdDuration );
  });
0
Irteza Asad

Pour moi, c'est travailler avec ce code (avec jQuery):

var int       = null,
    fired     = false;

var longclickFilm = function($t) {
        $body.css('background', 'red');
    },
    clickFilm = function($t) {
        $t  = $t.clone(false, false);
        var $to = $('footer > div:first');
        $to.find('.empty').remove();
        $t.appendTo($to);
    },
    touchStartFilm = function(event) {
        event.preventDefault();
        fired     = false;
        int       = setTimeout(function($t) {
            longclickFilm($t);
            fired = true;
        }, 2000, $(this)); // 2 sec for long click ?
        return false;
    },
    touchEndFilm = function(event) {
        event.preventDefault();
        clearTimeout(int);
        if (fired) return false;
        else  clickFilm($(this));
        return false;
    };

$('ul#thelist .thumbBox')
    .live('mousedown touchstart', touchStartFilm)
    .live('mouseup touchend touchcancel', touchEndFilm);
0
molokoloco

J'avais besoin de quelque chose pour les événements de clavier longue presse, alors j'ai écrit ceci.

var longpressKeys = [13];
var longpressTimeout = 1500;
var longpressActive = false;
var longpressFunc = null;

document.addEventListener('keydown', function(e) {
    if (longpressFunc == null && longpressKeys.indexOf(e.keyCode) > -1) {
        longpressFunc = setTimeout(function() {
            console.log('longpress triggered');
            longpressActive = true;
        }, longpressTimeout);

    // any key not defined as a longpress
    } else if (longpressKeys.indexOf(e.keyCode) == -1) {
        console.log('shortpress triggered');
    }
});

document.addEventListener('keyup', function(e) {
    clearTimeout(longpressFunc);
    longpressFunc = null;

    // longpress key triggered as a shortpress
    if (!longpressActive && longpressKeys.indexOf(e.keyCode) > -1) {
        console.log('shortpress triggered');
    }
    longpressActive = false;
});
0
Brad.Smith

comme ça?

doc.addEeventListener("touchstart", function(){
    // your code ...
}, false);    
0
翁沈顺