2012-06-05 22 views
58

Sto utilizzando twitter bootstrap per creare un sito e stavo tentando di inizializzare i suggerimenti. Oltre all'aggiunta di qualcosa come:

 $("[rel=tooltip]").tooltip()
in application.js, a meno che non manchi, il seguente pezzo di codice usato nei documenti di bootstrap, i miei tooltip non vengono inizializzati.

 
!function ($) { 

    $(function(){ 

    }) 

}(window.jQuery) 

Cosa fa il codice sopra riportato?

risposta

157

Lets spiegare rompendo il codice

function() { 
}() 

O spesso scritto come

(function() { 
})() 

è una funzione self-invoking anonymous, noto anche come espressioni di funzione Immediatamente-invocata (IIFEs). Che esegue immediatamente la funzione anonima in linea.

Maggiori informazioni al riguardo a Explain the encapsulated anonymous function syntax.

Le funzioni anonime sono una funzionalità potente e presentano vantaggi come l'ambito ("spaziatura del nome variabile"), vedere What is the purpose of a self executing function in javascript?.


Ora stanno usando

function ($) { 

}(window.jQuery) 

Saltiamo la ! per ora.

Quindi stanno passando, window.jQuery in quella funzione come argomento e accettando come $.

Quello che fa sta facendo $ un alias window.jQuery (Object originale jQuery) e quindi garantire che il $ sarà sempre riferimento al jQuery object interno che closure, non importa se altra libreria che ha preso ($) all'esterno.

Quindi il codice che scrivi all'interno di quella chiusura utilizzando $ funzionerà sempre.

Un altro vantaggio è che $ si presenta come un argomento della funzione anonima, che lo porta più vicino nel scope chain e, quindi, ci vuole meno tempo per l'interprete di JS per trovare l'oggetto $ all'interno della chiusura di quanto sarebbe altrimenti preso se noi usato il globale $.


$(function(){ 

}) 

E 'il documento blocco pronto jQuery come si potrebbe già sapere, che assicura che il codice all'interno di questa funzione verrà eseguito quando dom is ready, e quindi tutti event binding's funzionerà correttamente.

saperne di più su http://api.jquery.com/ready/

E che cosa ! fa è stato ben spiegato here o What does the exclamation mark do before the function?

In breve:

per dimostrare i benefici di !, Lets prendere in considerazione un caso,

(function() { 
    alert('first'); 
}()) 


(function() { 
    alert('second'); 
}()) 

Se si incolla il codice di cui sopra in console, si otterrà due avvisi, ma poi si otterrà questo errore

TypeError: undefined is not a function 

Perché questo accade? Simuliamo come i motori JS eseguono il blocco di codice sopra. Esegue questa funzione anonima function() {alert('first');}() mostra l'avviso e non restituisce nulla undefined viene restituito all'interno dello (). Lo stesso succede anche per la seconda funzione. Così, dopo l'esecuzione di questo blocco, si finisce per avere qualcosa di simile

(undefined)(undefined) 

e come è la sintassi è come una funzione self-invoking anonymous, si cerca di chiamare tale funzione, ma la prima, (undefined) non è una funzione. Quindi ottieni l'errore undefined is not a function. ! corregge questo tipo o errori. Cosa succede con !. Sto citando le righe dal link di risposta sopra.

Quando si utilizza!, La funzione diventa il singolo operando di unario (logico) operatore NOT.

In questo modo la funzione deve essere valutata come espressione, che consente a di richiamarsi immediatamente in linea.

e questo risolve il problema di cui sopra, possiamo riscrivere il blocco sopra utilizzando ! come

!(function() { 
    alert('first'); 
}()) 


!(function() { 
    alert('second'); 
}()) 

Per il vostro caso si può semplicemente inserire il codice tooltip all'interno di un blocco pronto documento come questo

$(function(){ 
    $("[rel=tooltip]").tooltip(); 
}); 

e funzionerà correttamente.

E se si utilizza semplicemente $("[rel=tooltip]").tooltip() senza alcun doc ready block, è possibile che questo codice venga eseguito, non ci sono ancora elementi con rel=tooltip in DOM. Quindi $("[rel=tooltip]") restituirà un set vuoto e tooltip non funzionerà.

Un esempio tag quando non funzionerà senza doc ready block,

. 
. 
. 
<script type="text/javascript"> 
    $("[rel=tooltip]").tooltip(); 
</script> 
. 
. 
. 
. 
<a href="#" rel="tooltip">Something</a> 
<a href="#" rel="tooltip">Something</a> 
<a href="#" rel="tooltip">Something</a> 

Siccome i browser, interpreta il codice sequenziale, viene eseguito il codice js appena faccia come. E quando esegue qui il blocco JS, non ha ancora analizzato i tag a rel="tooltip", come appare dopo il blocco JS, quindi non sono in DOM in quel momento.

Quindi per il caso di cui sopra il $("[rel=tooltip]") è vuoto e quindi il suggerimento non funzionerà. Quindi è sempre sicuro di mettere tutto il codice JS all'interno document ready blocco come

$(function){ 
    // put all your JS code here 
}); 

Spero tutto questo ha un senso a voi adesso.

+5

Grazie per l'ottima risposta! – powtac

+0

@powtac, Grazie, sono anche un principiante che impara cose nuove su JS ogni giorno da SO. –

+4

+1 Great write up, ho imparato un bel po 'qui. Penso che questo sia noto come * Risposta canonica * :) – brasofilo