Wie kann ich in jQuery auf ein Klicken und Halten warten?

116

Ich möchte in der Lage sein, ein Ereignis auszulösen, wenn ein Benutzer auf eine Schaltfläche klickt und diesen Klick dann 1000 bis 1500 ms lang gedrückt hält.

Gibt es eine jQuery-Kernfunktionalität oder ein Plugin, das dies bereits ermöglicht?

Soll ich meine eigenen rollen? Wo soll ich anfangen?

SnickersAreMyFave
quelle
mögliches Duplikat von Long Press in JavaScript?
Der Hochstapler
Wie wäre es mit "Taphold"?
Roshdy

Antworten:

173
var timeoutId = 0;

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

Edit : Korrektur per AndyE ... danke!

Bearbeiten 2 : Verwenden Sie bind jetzt für zwei Ereignisse mit demselben Handler pro Gnarf

Baumgesicht
quelle
4
Das Update ist besser, aber Sie können das Intervall auch in einem mouseleaveHandler löschen.
Andy E
5
Sie könnten die gleiche Funktion für Mouseup / Mouseleave verwenden:.bind('mouseup mouseleave', function() {
Gnarf
@gnarf Guter Punkt! Ich habe es bearbeitet, um Ihren Vorschlag aufzunehmen.
Baumgesicht
Gutes Zeug! Ohne Probleme in jQuery Mobile implementiert.
Anthony
@treeface Slick, aber ich bin verwirrt, wohin die Nutzlast gehen würde. Sollte der implementierungsspezifische Handler im mouseup-Ereignis aufgerufen werden?
Bob Stein
13

Aircoded (aber auf dieser Geige getestet )

(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);
})
Zwerg
quelle
wie man den Text mit einer anderen Farbe auswählt, wenn wir auf das Gerät tippen und es gedrückt halten
Lucky
8

Ich habe ein einfaches JQuery-Plugin dafür erstellt, wenn jemand interessiert ist.

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

Tony Smith
quelle
Schön. Konnte dies ändern, um zu erkennen, dass ein Objekt gezogen wurde, um eine Nachricht zu entfernen, die den Benutzer auffordert, das Objekt zu ziehen.
Starfs
FANTASTISCHES Plugin. Ich bin zu meinem Projekt gekommen und bam, funktioniert.
Andy
Ihr Plugin wurde nicht für Bootstrap geschrieben, funktioniert aber SEHR gut damit! Kein zusätzliches CSS oder Herumspielen. Funktioniert einfach. Ein großes Lob.
Andy
5

Vermutlich könnten Sie einen setTimeoutAnruf mousedowneinleiten und dann abbrechen mouseup(falls mouseupdies vor Ablauf Ihrer Zeitüberschreitung geschieht).

Es sieht jedoch so aus, als gäbe es ein Plugin: longclick .

Jacob Mattison
quelle
1

Hier ist meine aktuelle Implementierung:

$.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
quelle
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
quelle
0

Ich habe Code geschrieben, um es einfach zu machen

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

Siehe auf JSFiddle

Jetzt müssen Sie nur noch die Haltezeit einstellen und clickHoldIhrem Element ein Ereignis hinzufügen

Sergey Semushin
quelle
0

Versuche dies:

var thumbnailHold;

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

         } , 1000);
     return false;
});

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