2011-09-23 10 views
7

Il meccanismo jQuery ".triggerHandler()", diversamente da ".trigger()", opera solo sul primo elemento a cui fa riferimento il oggetto jQuery per il quale è stato chiamato. In altre parole,jQuery ".triggerHandler()" vs. ".trigger()" quando sono selezionati più elementi

$('.all-over-the-page').triggerHandler("readjust"); 

chiamerà solo il gestore di "riaggiustare" per il primo elemento con classe "all-over-the-page", anche se ci sono molti elementi della pagina con quella classe. Il metodo ".trigger()", d'altra parte, avrebbe effetto su tutti loro.

mi rendo conto che posso usare ".each()" per aggirare il problema (o semplicemente scrivere il mio sostituto che lo fa per me), ma c'è un po 'di logica per il motivo per cui i due sono diversi in questo senso? Non ha senso per me. (Capisco, naturalmente, che quasi certamente non può essere cambiato ora.)

modifica per chiarire:

E 'probabilmente più facile da capire perché sto graffiare la mia testa su questo se fornisco un contesto nello stile del codice che ho effettivamente ottenuto. Quando metto insieme il codice per varie funzioni di "widget" su una pagina, che spesso coinvolge gestori di eventi. Un buon esempio è una forma di qualche tipo che ha alcuni campi la cui rilevanza è controllata da una casella di controllo, un pulsante di scelta o un selettore. Un'istanza comune è la casella di controllo "Indirizzo di spedizione" che compare su un sito di e-commerce di zillion: se la casella è selezionata, l'indirizzo di spedizione è disabilitato e viene utilizzato l'indirizzo di fatturazione.

Ora ritengono che qualche altro codice può, per le proprie ragioni che sono totalmente indipendenti dal widget di casella di controllo, in realtà fare le cose per la forma che può includere le impostazioni casella di controllo di aggiornamento a livello di codice. In tal caso, l'altro codice del widget potrebbe voler utilizzare "triggerHandler()" per indicare qualsiasi widget, "hey ho aggiornato alcune cose, quindi potresti voler ricontrollare lo stato corrente e correggerlo se necessario."

Quindi, se ".triggerHandler()" dovrebbe operare su tutti gli elementi selezionati, ho potuto utilizzare:

$theForm.find('input, select, textarea').triggerHandler('change'); 

e tutti quei gestori potuto correre e fare tutto ciò di cui hanno bisogno. Come ho detto, è abbastanza facile da scrivere: "... c'è una certa logica per il motivo per cui i due sono diversi in questo senso"

$theForm.find('input, select, textarea').each(function() { 
    $(this).triggerHandler('change'); 
}); 
+0

+1 buona domanda A punta –

+0

Non sono sicuro di cosa si stia tentando di fare. Puoi dare un piccolo contesto in più a ciò che stai tentando di risolvere? –

+0

Aggiornato con un po 'più di materiale esplicativo. – Pointy

risposta

11

Penso che l'idea è che triggerHandler() è destinato a essere un modo di invocare la funzione come un gestore come se fosse qualsiasi altra funzione.

Come tali, hanno fatto triggerHandler() modo che la funzione viene richiamata solo una volta, restituisce il valore di ritorno effettivo della funzione, e non influenza il DOM con i comportamenti bolle o di default.

Ovviamente la funzione potrebbe interrompersi se hanno cambiato il valore this in qualcosa di diverso da un elemento DOM, quindi utilizzano solo il primo elemento corrispondente.

Se hai intenzione di usare semplicemente la funzione, allora probabilmente sarei appena mantenere un riferimento ad esso e invoco direttamente, o come argomento di .each().

$('.element').each(handler_func); 

... finché non è necessario l'oggetto event.


EDIT: O se si desidera che i valori restituiti dalla chiamata, utilizzare .map() invece:

var return_values = $('.element').map(handler_func); 

EDIT: Per quanto riguarda l'esempio fornito nella domanda aggiornato , una buona soluzione potrebbe essere quella di sfruttare la capacità extraParametri del metodo trigger()[docs] così che puoi dire al gestore di preventDefault() e stopPropagation().

$('.elememts').bind('click', function(e, was_code_triggered) { 

    if(was_code_triggered) { 
     e.preventDefault(); 
     e.stopPropagation(); 
    } 
    // your code 
}); 


// ... 


$('.elememts').trigger('click', true); // pass "true" to let handler know 
             // it wasn't a DOM event 

Dalle .trigger() documentazione:.

"notare la differenza tra i parametri extra stiamo passando qui e il parametro EventData al metodo .bind() Entrambi sono meccanismi per passare informazioni ad un gestore di eventi, ma l'argomento extraParameters su .trigger() consente di determinare le informazioni al momento dell'attivazione dell'evento, mentre l'argomento eventData su .bind() richiede le informazioni essere già calcolati nel momento in cui il conduttore è vincolato. "

+0

Bene, OK, ma mi sembra strano di scrivere gestori di eventi che si aspettano di poter restituire un valore. E sto bene a non fare i comportamenti di default; questo è davvero problematico con "clic" sulle caselle di controllo (ad esempio). – Pointy

+0

@Pointy: Sì, è strano, a meno che non si disponga di una funzione utile come funzione autonoma, nonché di un gestore. Penserei che il caso sarebbe raro. E 'stato il bubbling disabilitato che stavi cercando in "triggerHandler"? EDIT: appena notato l'aggiornamento alla tua domanda. Leggendo ... – user113716

+2

@Pointy: Vedo cosa stai cercando. Sì, se non vuoi '.each()' (se passi una funzione direttamente o usi 'triggerHandler()'), potresti prendere in considerazione l'uso della funzione * extraParameters * di '.trigger()' per passare un flag che indicherà al gestore che dovrebbe 'preventDefault()' e 'stopPropagation()'. – user113716

Problemi correlati