La commutazione fare clic gestori di Javascript

Ho un pulsante HTML a cui attribuisco un evento, utilizzando jQuery bind(), in questo modo:

$('#mybutton').bind('click', myFirstHandlerFunction);

In myFirstHandlerFunction, vorrei che il gestore di sostituire con un nuovo gestore, mySecondHandlerFunction, come questo:

function myFirstHandlerFunction(e) {
    $(this).unbind('click', myFirstHandlerFunction).bind('click', mySecondHandlerFunction);
}

Nella seconda fare clic su gestore, mySecondHandlerFunction, mi piacerebbe impostare il pulsante torna al suo stato originale: separare il mySecondHandlerFunction gestore e ricollegare il gestore originale, myFirstHandlerFunction, in questo modo:

function mySecondHandlerFunction(e) {
    $(this).unbind('click', mySecondHandlerFunction).bind('click', myFirstHandlerFunction);
}

Questo funziona alla grande, tranne che per un piccolo dettaglio: perché l’evento click non è ancora propagato attraverso ogni clic del pulsante gestori, l’evento click viene passato il pulsante clic gestore, che succede ad essere il gestore che era solo legato al precedente gestore. Il risultato finale è mySecondHandlerFunction essere eseguito immediatamente dopo myFirstHandlerFunction viene eseguito.

Questo problema può essere facilmente risolto chiamando il e.stopPropagation() in ogni gestore, ma questo è il lato negativo effetto di annullamento di qualsiasi altro click gestori che potrebbe essere stato attaccato in modo indipendente.

C’è un modo sicuro e in modo coerente alternare tra i due gestori, senza dover interrompere la propagazione dell’evento click?

Perché non utilizzare un flag per controllare che il gestore di richiamare e fissare sempre un maestro del gestore.

OriginaleL’autore Nathan Friend | 2013-01-03

5 risposte

  1. 8

    Aggiornamento: in Quanto questa forma di toggle() è stato rimosso in jQuery 1.9, la soluzione sotto non funziona più. Vedere questa domanda per
    alternative.

    Sembra toggle() avrebbe risolto il problema:

    $("#mybutton").toggle(myFirstHandlerFunction, mySecondHandlerFunction);

    Il codice di cui sopra saranno registrati myFirstHandlerFunction e mySecondHandlerFunction chiamato in alternativa click.

    Non avevo capito che questo non esisteva! Molto cool.
    L’ .toggle(eventHandlers) è stato ammortizzato in jQuery 1.8, e rimosso 1.9+. Questa non è più un’opzione praticabile. –Fonte
    fatto, grazie per il testa a testa.

    OriginaleL’autore Frédéric Hamidi

  2. 6

    Basta usare un booleano per attivare la funzionalità del gestore, non c’è bisogno di destreggiarsi tra cui gestore è in ascolto:

    $('#mybutton').bind('click', myHandlerFunction);
    var first = true;
    
    function myHandlerFunction(e) {
        if(first){
            //Code from the first handler here;
        }else{
            //Code from the second handler here;
        }
        first = !first; //Invert `first`
    }
    Dal momento che si sta utilizzando jQuery, .toggle è probabilmente meglio, ma +1 per la visualizzazione di logica su come fare questo senza l’uso di .toggle
    Come commentato in precedenza, toggle è sconsigliata a 1.9 e rimosso in 1.10. Non la uso.
    Mi piace questo meglio utilizzando i dati di attributo anziché globale : stackoverflow.com/a/2459225/781695

    OriginaleL’autore Cerbrus

  3. 0

    Stavo guardando questo oggi, e si rese conto che c’era ancora un modo per fare questo senza una variabile globale elencati. Mi è venuta un’idea per aggiungere posizioni di ESRI mappa di base, ma sarebbe un lavoro generalmente troppo:

    function addLocationClickHandler() {
        var addLocationClick = overviewMap.on('click', function (event) {
            addLocationClick.remove();
        })
        $('#locationAddButton').one('click', function (cancelEvent) {
            addLocationClick.remove();
            $('#locationAddButton').on('click', addLocationClickHandler)
        });
    }
    
    $('#locationAddButton').on('click', addLocationClickHandler)

    Questo dovrebbe consentire di mettere qualcos’altro nella sezione in cui è possibile sovrascrivere il gestore click e non necessitano di una variabile globale.

    OriginaleL’autore BBQ Singular

  4. -1

    Ciò consentirebbe di aggiungere dati su stato attributo il tasto

    $(document).ready(function(){
    
    $('#mybutton').on('click',function(){
    
    if($(this).attr('data-click-state') == 1) {  
    $(this).attr('data-click-state', 0)
    myFirstHandlerFunction();
    
    } else {
    $(this).attr('data-click-state', 1)
    mySecondHandlerFunction();
    }
    
    });
    
    });
    Mi piace questo approccio!

    OriginaleL’autore Mike Tavish

  5. -2

    Come questo:

    $(this).bind('click', myMasterHandler);
    
    handler = 0;
    
    function myMasterHandler(e) {
        if(handler == 0) {
            myFirstHandler(e);
            handler = 1;
        } else {
            mySecondHandler(e);
            handler = 0;
        }
    }
    Perché il downvote?
    Il downvote non è mia, ma potrebbe essere correlato a handler essere globali che locali, o per l’uso di 0 e 1 invece di un boolean, o per il fatto che il valore corrente di this non è correttamente propagate ai gestori.
    Grazie uomo…

    OriginaleL’autore ATOzTOA

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *