Comment puis-je écouter un clic et maintenir dans jQuery?

116

Je veux pouvoir déclencher un événement lorsqu'un utilisateur clique sur un bouton, puis maintient ce clic pendant 1000 à 1500 ms.

Existe-t-il une fonctionnalité principale de jQuery ou un plugin qui permet déjà cela?

Dois-je rouler le mien? Où dois-je commencer?

SnickersAreMyFave
la source
duplicata possible de Long Press en JavaScript?
Der Hochstapler
Que diriez-vous de «taphold»?
Roshdy

Réponses:

173
var timeoutId = 0;

$('#myElement').on('mousedown', function() {
    timeoutId = setTimeout(myFunction, 1000);
}).on('mouseup mouseleave', function() {
    clearTimeout(timeoutId);
});

Edit : correction par AndyE ... merci!

Edit 2 : utiliser bind now pour deux événements avec le même gestionnaire par gnarf

face d'arbre
la source
4
La mise à jour est préférable, mais vous pouvez également envisager de supprimer l'intervalle dans un mouseleavegestionnaire.
Andy E
5
Vous pouvez utiliser la même fonction pour mouseup / mouseleave:.bind('mouseup mouseleave', function() {
gnarf
@gnarf Bon point! Je l'ai modifié pour inclure votre suggestion.
treeface
Jolies choses! Implémenté dans jQuery Mobile sans aucun problème.
Anthony
@treeface Slick, mais je ne sais pas où irait la charge utile. Le gestionnaire spécifique à l'implémentation doit-il être appelé dans l'événement mouseup?
Bob Stein
13

Aircoded (mais testé sur ce violon )

(function($) {
    function startTrigger(e) {
        var $elem = $(this);
        $elem.data('mouseheld_timeout', setTimeout(function() {
            $elem.trigger('mouseheld');
        }, e.data));
    }

    function stopTrigger() {
        var $elem = $(this);
        clearTimeout($elem.data('mouseheld_timeout'));
    }


    var mouseheld = $.event.special.mouseheld = {
        setup: function(data) {
            // the first binding of a mouseheld event on an element will trigger this
            // lets bind our event handlers
            var $this = $(this);
            $this.bind('mousedown', +data || mouseheld.time, startTrigger);
            $this.bind('mouseleave mouseup', stopTrigger);
        },
        teardown: function() {
            var $this = $(this);
            $this.unbind('mousedown', startTrigger);
            $this.unbind('mouseleave mouseup', stopTrigger);
        },
        time: 750 // default to 750ms
    };
})(jQuery);

// usage
$("div").bind('mouseheld', function(e) {
    console.log('Held', e);
})
gnarf
la source
comment sélectionner le texte avec une couleur différente lorsque nous maintenons le doigt sur l'appareil
Chanceux
8

J'ai fait un simple plugin JQuery pour cela si quelqu'un est intéressé.

http://plugins.jquery.com/pressAndHold/

Tony Smith
la source
Joli. A pu le modifier pour détecter qu'un objet avait été déplacé afin de supprimer un message demandant à l'utilisateur de faire glisser l'objet.
Starfs
Plugin FANTASTIQUE. Je suis tombé dans mon projet et bam, ça marche.
Andy
Votre plugin n'a pas été écrit pour Bootstrap, mais fonctionne TRÈS bien avec! Pas de CSS supplémentaire ni de déconner. Fonctionne juste. Gloire.
Andy
5

Vous pouvez vraisemblablement lancer un setTimeoutappel mousedown, puis l'annuler mouseup(si mouseupcela se produit avant la fin de votre délai d'expiration).

Cependant, il semble qu'il existe un plugin: longclick .

Jacob Mattison
la source
1

Voici ma mise en œuvre actuelle:

$.liveClickHold = function(selector, fn) {

    $(selector).live("mousedown", function(evt) {

        var $this = $(this).data("mousedown", true);

        setTimeout(function() {
            if ($this.data("mousedown") === true) {
                fn(evt);
            }
        }, 500);

    });

    $(selector).live("mouseup", function(evt) {
        $(this).data("mousedown", false);
    });

}
SnickersAreMyFave
la source
1
    var _timeoutId = 0;

    var _startHoldEvent = function(e) {
      _timeoutId = setInterval(function() {
         myFunction.call(e.target);
      }, 1000);
    };

    var _stopHoldEvent = function() {
      clearInterval(_timeoutId );
    };

    $('#myElement').on('mousedown', _startHoldEvent).on('mouseup mouseleave', _stopHoldEvent);
kayz1
la source
0

J'ai écrit du code pour faciliter les choses

//Add custom event listener
$(':root').on('mousedown', '*', function() {
    var el = $(this),
        events = $._data(this, 'events');
    if (events && events.clickHold) {
        el.data(
            'clickHoldTimer',
            setTimeout(
                function() {
                    el.trigger('clickHold')
                },
                el.data('clickHoldTimeout')
            )
        );
    }
}).on('mouseup mouseleave mousemove', '*', function() {
    clearTimeout($(this).data('clickHoldTimer'));
});

//Attach it to the element
$('#HoldListener').data('clickHoldTimeout', 2000); //Time to hold
$('#HoldListener').on('clickHold', function() {
    console.log('Worked!');
});
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<img src="http://lorempixel.com/400/200/" id="HoldListener">

Voir sur JSFiddle

Il vous suffit maintenant de définir l'heure de maintien et d'ajouter un clickHoldévénement sur votre élément

Sergey Semushin
la source
0

Essaye ça:

var thumbnailHold;

    $(".image_thumb").mousedown(function() {
        thumbnailHold = setTimeout(function(){
             checkboxOn(); // Your action Here

         } , 1000);
     return false;
});

$(".image_thumb").mouseup(function() {
    clearTimeout(thumbnailHold);
});
KR Vineeth
la source