2010-08-12 21 views
23

Sto tentando di impedire più clic su collegamenti e voci, che causano problemi.jQuery previene altri eventi dopo un clic

Sto utilizzando jQuery per associare eventi di clic ai pulsanti (interfaccia utente di jQuery) e collegamenti alle immagini (<a><img /></a>).

C'è un modo per evitare una volta per tutte gli altri eventi di attivazione dopo un clic?

Oppure è necessario mantenere una variabile globale denominata _isProcessing e impostarla su true per ogni gestore di eventi?

Grazie

Edit: (chiarimento) Grazie per le vostre risposte, il mio problema non impedisca il gorgogliare della manifestazione, ma evitando gli scatti multipli simultanei.

+1

Cosa intendi con * "altri eventi" *? Altri gestori di eventi sullo stesso elemento? O sui suoi elementi antenati? O sull'intera pagina? Potresti per favore chiarire la tua specifica esigenza? – user113716

+0

Quindi, se ho un collegamento immagine chiamato "Aggiungi servizio", che aggiunge una riga a una tabella sulla mia pagina. Se clicco più di una volta ne aggiunge due. Non è necessario aggiungere altre righe dopo l'esecuzione del clic e prima che la riga sia stata creata. – Russell

+0

@Russell - Sì, ho aggiunto una risposta qui sotto per risolverlo. – user113716

risposta

29

Esistono vari modi per impedire ai clic di eseguire il codice in concomitanza.

Un modo è quello di unbind('click') sull'elemento, quindi .bind() di nuovo quando sei pronto.

Preferisco usare una sorta di bandiera. Potrebbe essere una variabile, ma preferirei assegnare una classe all'elemento, come .processing, e rimuoverlo quando è fatto. Quindi si dovrebbe controllare il gestore dell'esistenza di quella classe per determinare che il codice debba essere eseguito.

$('someElement').click(function() { 
    var $th = $(this); 
    if($th.hasClass('processing')) 
      return; 
    $th.addClass('processing'); 
    // normal code to run 
    // then when done remove the class 
    $th.removeClass('processing'); 
}); 

Un'altra opzione è quella di utilizzare gli elementi .data() per impostare una bandiera simile, come $(this).data('processing', true); quindi impostarla su false quando fatto.

+0

@ elo80ka - Grazie. Vorrei che jQuery avesse qualcosa come '.disableHandler ('click')' e '.enableHandler ('click')' in alternativa a '.bind()/unbind()' e soluzioni un po 'ingombranti/hackish come l'uso di classi o variabili come bandiere. : o) – user113716

+0

È necessario utilizzare la funzione .data() anziché aggiungere una classe che potrebbe avere un impatto accidentale sulla visualizzazione dell'elemento. – bcherry

+0

@bcherry - La cosa bella dell'uso di una classe è che è (sono abbastanza sicuro) un'operazione più leggera rispetto all'utilizzo di '.data()'. Se fai attenzione a nominare la tua classe, non ci dovrebbero essere ramificazioni di visualizzazione. – user113716

7

hai verificato preventDefault?

$("a").click(function(e) { 
    e.preventDefault(); 
} 

si potrebbe anche provare stopImmediatePropagation() o stopPropagation()


Si potrebbe anche prendere in considerazione l'evento one().

Collegare un gestore a un evento per gli elementi . Il gestore viene eseguito a più una volta per elemento.

+0

Il metodo 'e.preventDefault()' in realtà non ferma i gestori. Impedisce il comportamento predefinito di un elemento di attivarsi (come un '' che ti porta alla sua posizione 'href'). – user113716

+1

utilizzato e.stopImmediatePropagation(); lavorato. Grazie! Inoltre, usato unbind. – techdude

+0

uno() ha aiutato il mio caso in cui l'evento è stato attivato per ogni clic. Grazie! – planetregin

3

Restituire false dai gestori di eventi o chiamare ev.stopPropagation() in ogni gestore.

+0

Usa .stopPropagation() – Mark

+0

@Mark - Rileggi la domanda. * "il mio problema non impedisce il gorgoglio dell'evento" * – user113716

+0

Ho chiarito la domanda dopo aver postato la sua risposta. – Russell

19

C'è event.preventDefault, event.stopPropagation e restituisce falso come già dichiarato.

$("a").click(function(e) { 
    e.preventDefault(); 
    e.stopPropagation(); 
    return false; 
} 
+0

:-) per buona misura ... (anche se la domanda è diversa, immagino ...) –

+0

sì, quando ho risposto alla domanda non era stato ancora chiarito. – TehOne

+0

Sì scusa @TehOne, non ho espresso correttamente la mia domanda prima volta. – Russell

2

hai un paio di opzioni:

  1. Se i pulsanti/link vi ricaricare pagina, si può semplicemente separare il gestore di eventi click:

    $('input:submit').click(fumction() { 
        $(this).unbind('click'); 
        // Handle event here 
    }) 
    
  2. È puoi disabilitare i pulsanti e riattivarli una volta terminato (penso che funzioni anche con <input type="image">):

    $('input:submit').click(function() { 
        $(this).attr('disabled', 'disabled'); 
        // It also helps to let the user know what's going on: 
        $(this).val('Processing...'); 
        // Handle event here 
        $(this).removeAttr('disabled'); 
    }) 
    

    Non penso che questo funziona sui collegamenti però.

+0

Sapete se esiste un modo per disabilitare gli eventi (non rilasciarli, basta disabilitare)? – Russell

+0

@Russell: è possibile disabilitare gli elementi di input. Per quanto ne so, gli elementi disabilitati non generano eventi. – elo80ka

+0

Sì, ma un collegamento immagine (ancora), ad esempio, potrebbe generare un evento click ma non è un campo di input (come hai detto, disabilitare gli elementi di ancoraggio non funziona). – Russell

2

Un altro modo sarebbe usare event.stopPropagation() e event.isPropagationStopped() di segnalazione:

Esempio:

$(button).click(function(e){ 
    if(e.isPropagationStopped()) 
     return; // propagation was stopped, so stop further execution 

    // if you got this far - this event handler was called first 
    // custom logic goes here 

    // stop event propagation to signal other handlers 
    e.stopPropagation(); 

    // if you need, call e.preventDefault() to prevent default behaviour 
}); 

Ripetere stessa logica per altri gestori di eventi.

Problemi correlati