Pytanie Zapobieganie kliknięciom z opcją przeciągnij i upuść jQuery


Mam elementy na stronie, które są draggabe z jQuery. Te elementy mają zdarzenie click, które przechodzi do innej strony (zwykłe linki na przykład).

Jaki jest najlepszy sposób, aby zapobiec wystrzeliwaniu kliknięcia przez kliknięcie przy jednoczesnym kliknięciu w stan "przeciągnij i upuść"?

Mam problem z elementami do sortowania, ale myślę, że dobrze jest mieć rozwiązanie dla ogólnego przeciągania i upuszczania.

Rozwiązałem problem sam. Po tym znaleziono to samo rozwiązanie istnieje dla Scriptaculous, ale może ktoś ma lepszy sposób na osiągnięcie tego.


76
2017-11-20 16:25


pochodzenie


Podobne / duplikat: stackoverflow.com/questions/3486760/... - Ryan


Odpowiedzi:


Rozwiązanie, które dobrze się sprawdziło i nie wymaga limitu czasu: (tak, jestem trochę pedantyczny ;-)

Dodaję klasę znaczników do elementu podczas przeciągania, np. "noclick". Po upuszczeniu elementu wywoływane jest zdarzenie kliknięcia - dokładniej, jeśli przeciąganie kończy się, w rzeczywistości nie trzeba go rzucać na prawidłowy cel. W module obsługi kliknięć usuwam klasę znaczników, jeśli jest obecna, w przeciwnym razie kliknięcie jest obsługiwane normalnie.

$('your selector').draggable({
    start: function(event, ui) {
        $(this).addClass('noclick');
    }
});

$('your selector').click(function(event) {
    if ($(this).hasClass('noclick')) {
        $(this).removeClass('noclick');
    }
    else {
        // actual click event code
    }
});

84
2018-03-26 19:16



Przydatny! Nie pracowałem dla mnie za jednym zamachem, prawdopodobnie dlatego, że błądziłem w poprzednich próbach tego samego, a zajęcia skończyły się na innym elemencie niż ten, który kliknąłem ... ale w każdym razie użyłem zmiennej globalnej (która na tym ekstremalnie prosta strona była ok), a to działało całkiem dobrze. - MSpreij
To doprowadziło mnie do mojego rozwiązania, po prostu użyłem funkcji danych jQuery zamiast klasy. Dzięki. - William
ale przeglądarka nie wywoła zdarzenia kliknięcia za każdym razem, gdy upuszczasz element - puchu
Aby zapisać ustawienie klasy lub danych, w procedurze obsługi zdarzenia kliknięcia możesz również użyć: if (! $ (This) .is ('. Ui-przeciąganie-przeciąganie')) {... kliknij akcję} - ChrisV
Uważam, że ta odpowiedź jest znacznie lepsza: stackoverflow.com/a/13973319/336694 - Heliodor


Rozwiązaniem jest dodanie obsługi kliknięcia, która zapobiegnie rozprzestrzenianiu się kliknięcia na początku przeciągania. A następnie usuń ten handler po wykonaniu kropli. Ostatnia akcja powinna zostać nieco opóźniona, aby zapobiegać klikaniu.

Rozwiązanie do sortowania:

...
.sortable({
...
        start: function(event, ui) {
            ui.item.bind("click.prevent",
                function(event) { event.preventDefault(); });
        },
        stop: function(event, ui) {
            setTimeout(function(){ui.item.unbind("click.prevent");}, 300);
        }
...
})

Rozwiązanie do przeciągania:

...
.draggable({
...
        start: function(event, ui) {
            ui.helper.bind("click.prevent",
                function(event) { event.preventDefault(); });
        },
        stop: function(event, ui) {
            setTimeout(function(){ui.helper.unbind("click.prevent");}, 300);
        }
...
})

38
2017-11-20 16:26



Uważam, że ta odpowiedź jest znacznie lepsza: stackoverflow.com/a/13973319/336694 - Heliodor
Wydaje się, że to nie przeszkodziło mi w zdarzeniu kliknięcia, używam jquery 1.9.1 i jquery.ui 1.10.3 - aaron
@Heliodor zgodził się.
dziwne, że odpowiedziałeś na własne pytanie, i to nawet nie działa, Sasha lol.
@Aaron ta odpowiedź poniżej działa: http://stackoverflow.com/a/4572831/119765 - lol


Chciałbym dodać do tego, że wygląda na to, że zapobieganie zdarzeniu kliknięcia działa tylko wtedy, gdy zdarzenie kliknięcia jest zdefiniowane po przeciągnięciu lub sortowaniu zdarzenia. Jeśli kliknięcie zostanie dodane jako pierwsze, zostanie uaktywnione po przeciągnięciu.


11
2018-03-15 13:34



TAK, TO POWODUJE BYĆ NAJBARDZIEJ SKUTECZNĄ I NAJBARDZIEJ EFEKTYWNĄ METODĄ !!! - JxAxMxIxN


Miałem ten sam problem i próbowałem wielu podejść i nikt nie pracował dla mnie.

Rozwiązanie 1

$('.item').click(function(e)
{            
    if ( $(this).is('.ui-draggable-dragging') ) return false;
});  

nic dla mnie nie robi. Element jest klikany po zakończeniu przeciągania.

Rozwiązanie 2 (autor: Tom de Boer)

$('.item').draggable(
{   
    stop: function(event, ui) 
    {
         $( event.originalEvent.target).one('click', function(e){ e.stopImmediatePropagation(); } );
    }
});

Działa to dobrze, ale kończy się niepowodzeniem w jednym przypadku - kiedy chodziłem na fullscreen onclick:

var body = $('body')[0];     
req = body.requestFullScreen || body.webkitRequestFullScreen || body.mozRequestFullScreen;
req.call(body); 

Rozwiązanie 3 (autor: Sasha Yanovets)

 $('.item').draggable({
        start: function(event, ui) {
            ui.helper.bind("click.prevent",
                function(event) { event.preventDefault(); });
        },
        stop: function(event, ui) {
            setTimeout(function(){ui.helper.unbind("click.prevent");}, 300);
        }
})

To nie działa dla mnie.

Rozwiązanie 4 - jedyne, które działało dobrze

$('.item').draggable(
{   
});
$('.item').click(function(e)
{  
});

Tak, to jest to - prawidłowa kolejność działa - najpierw musisz powiązać przeciągane (), a następnie zdarzenie click (). Nawet gdy wstawiam tryb przełączania na pełnym ekranie w zdarzeniu click (), nie przeciąga się do trybu pełnoekranowego podczas przeciągania. Idealne dla mnie!


10
2018-03-28 12:44



Jedynym, który pracował dla mnie (w IE11 / Edge) było rozwiązanie 4. Dzięki! - Simon


Nie lubię używać timerów ani zapobiegać, więc to, co zrobiłem, to:

var el, dragged

el = $( '#some_element' );

el.on( 'mousedown', onMouseDown );
el.on( 'mouseup', onMouseUp );
el.draggable( { start: onStartDrag } );

onMouseDown = function( ) {
  dragged = false;
}

onMouseUp = function( ) {
  if( !dragged ) {
    console.log('no drag, normal click')
  }
}

onStartDrag = function( ) {
  dragged = true;
}

Twardy jak skała..


9
2017-11-15 08:48



Podoba mi się ten! - aaron
To było dla mnie najlepsze rozwiązanie. Miałem problemy z uzyskiwaniem zdarzeń kliknięcia w celu pracy z jquery UI, które można było sortować za pomocą przeglądarki mobilnej za pomocą jquery.ui.touch.punch.js, ale to rozwiązało ją dość elegancko. - Godsmith


Stwierdziłem, że przy użyciu standardowej funkcji kliknięcia jQuery:

$("#element").click(function(mouseEvent){ // click event }); 

działa dobrze w jQuery UI. Zdarzenie kliknięcia nie zostanie wykonane podczas przeciągania i upuszczania. :)


9
2018-01-01 00:44



To działało dla mnie, ale musiałem zdefiniować zdarzenie click po zdarzenie przeciągalne, o którym wspomniał @kasakka. - Aaron
To nie działa w firefox - ccsakuweb
Biorąc pod uwagę, że minęły> dwa lata od momentu, w którym zaproponowano to rozwiązanie i że jQuery zmieniło się dość mocno, że rozważasz możliwość, że poprzednie rozwiązanie przestało działać. "Nie działa w firefoxie" nie uwzględnia kontekstu kiedy go przesłałem .. - Norm


wersja lex82, ale dla .sortable ()

 start: function(event, ui){
 ui.item.find('.ui-widget-header').addClass('noclick');
 },

i możesz potrzebować tylko:

 start: function(event, ui){
 ui.item.addClass('noclick');
 },

i oto, czego używam do przełączania:

$("#datasign-widgets .ui-widget-header").click(function(){
if ($(this).hasClass('noclick')) {
$(this).removeClass('noclick');

}
else {
$(this).next().slideToggle();
$(this).find('.ui-icon').toggleClass("ui-icon-minusthick").toggleClass("ui-icon-plusthick");
}
});

3
2018-01-10 20:24



Wygląda na to, że interfejs użytkownika jquery dołącza klasę "ui-sortable-helper" do sortowanego elementu. Zatem możesz pominąć klasę "noclick" i po prostu zrobić, jeśli ($ (this) .hasClass ("ui-sortable-helper")). Bardziej zwinny w ten sposób - Matt De Leon