Jak mogę nasłuchiwać kliknięcia i przytrzymania w jQuery?

116

Chcę mieć możliwość wywołania zdarzenia, gdy użytkownik kliknie przycisk, a następnie przytrzyma to kliknięcie przez 1000 do 1500 ms.

Czy istnieje podstawowa funkcjonalność jQuery lub wtyczka, która już to umożliwia?

Czy powinienem zrobić własny? Gdzie mam zacząć?

SnickersAreMyFave
źródło
możliwy duplikat długiego naciśnięcia w JavaScript?
Der Hochstapler
Co powiesz na „taphold” ??
Roshdy

Odpowiedzi:

173
var timeoutId = 0;

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

Edycja : korekta według AndyE ... dzięki!

Edycja 2 : używanie bind teraz dla dwóch zdarzeń z tym samym handlerem na gnarf

treeface
źródło
4
Aktualizacja jest lepsza, ale możesz rozważyć wyczyszczenie interwału w mouseleavemodule obsługi.
Andy E
5
Możesz użyć tej samej funkcji dla mouseup / mouseleave:.bind('mouseup mouseleave', function() {
gnarf
@gnarf Słuszna uwaga! Zmodyfikowałem go, aby uwzględnić twoją sugestię.
treeface
Niezłe rzeczy! Wdrożony w jQuery Mobile bez żadnych problemów.
Anthony
@treeface Slick, ale nie wiem, dokąd pójdzie ładunek. Czy w przypadku zdarzenia mouseup należy wywołać procedurę obsługi specyficzną dla implementacji?
Bob Stein
13

Kodowane powietrzem (ale przetestowane na tym skrzypcach )

(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
źródło
jak zaznaczyć tekst w innym kolorze, gdy dotykamy i przytrzymujemy urządzenie
Lucky
8

Zrobiłem prostą wtyczkę JQuery do tego, jeśli ktoś jest zainteresowany.

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

Tony Smith
źródło
Niezłe. Był w stanie to zmodyfikować, aby wykryć, że obiekt został przeciągnięty, aby usunąć komunikat nakazujący użytkownikowi przeciągnięcie obiektu.
Starfs
FANTASTYCZNA wtyczka. Wpadłem do mojego projektu i bum, działa.
Andy
Twoja wtyczka nie została napisana dla Bootstrap, ale BARDZO ładnie z nią współpracuje! Bez dodatkowego CSS i bez majstrowania. Po prostu działa. Sława.
Andy
5

Prawdopodobnie możesz rozpocząć setTimeoutpołączenie mousedown, a następnie anulować je mouseup(jeśli mouseupzdarzy się to przed upływem limitu czasu).

Wygląda jednak na to, że istnieje wtyczka: longclick .

Jacob Mattison
źródło
1

Oto moja obecna realizacja:

$.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
źródło
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
źródło
0

Napisałem kod, żeby to ułatwić

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

Zobacz na JSFiddle

Teraz wystarczy ustawić czas wstrzymania i dodać clickHoldzdarzenie na swoim elemencie

Sergey Semushin
źródło
0

Spróbuj tego:

var thumbnailHold;

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

         } , 1000);
     return false;
});

$(".image_thumb").mouseup(function() {
    clearTimeout(thumbnailHold);
});
KR Vineeth
źródło