2016-03-14 9 views
6

Ho cercato di imparare javascript rifattorizzando alcuni esempi di Jquery in un libro in javascript. Nel seguente codice aggiungo un listener di clic a una scheda e lo trasformo in attivo quando l'utente fa clic sulla scheda.Cercando di dare un senso a "questo" nel mio codice javascript (una cosa funziona, l'altra no)

var tabs = document.querySelectorAll(".tabs a span"); 
 
var content = document.querySelectorAll("main .content li"); 
 

 
for (var tabNumber = 0; tabNumber <= 2; tabNumber++) { 
 
    tabs[tabNumber].addEventListener("click", function (event) { 
 
    
 
    for (var i = 0; i < tabs.length; i++) { 
 
     tabs[i].classList.remove("active"); 
 
    } 
 
    tabs[tabNumber].classList.add("active"); 
 
    for (var i = 0; i < content.length; i++) { 
 
     content[i].innerHTML = ""; 
 
    } 
 
    event.preventDefault(); 
 
    }); 
 
}

Ciò restituisce un undefined error quando l'eseguo. Tuttavia, ho provato a sostituire tabs[tabNumber].classList.add("active") con this.classList.add("active") e ha funzionato.

Perché il codice precedente non funziona? Per quanto posso vedere si riferiscono alla stessa cosa, e tabs[tabNumber] dovrebbe funzionare poiché a quel punto nel codice è tabs[0].

+3

Se console.log (tabNumber) all'interno del gestore di eventi, troverai che è 3, indipendentemente dall'elemento su cui hai fatto clic. – nnnnnn

+0

usa 'let' per i cicli il più possibile, ma il problema può essere risolto chiudendo o nel punto in cui lo fai riferimento nel tuo codice JS. – Gary

risposta

3

Suppongo che altre risposte ti abbiano spiegato perché il tabs[tabNumber] non funziona (perché proviene dal punteggio del ciclo for e quindi è sempre uguale al valore maggiore di tabNumber).

Ecco perché suggerirei di utilizzare un ciclo .forEach. Attenzione però, perché non funziona su array di nodi DOM prodotte da document.querySelectorAll(), ma è possibile utilizzare:

// ES6 
Array.from(document.querySelectorAll('...')) 
// ES5 
[].slice.call(document.querySelectorAll('...')) 

In ogni caso, ho fatto una semplificata working demo del codice. Si noti che salvi la scheda attualmente attiva in una variabile, per evitare un altro ciclo for. Si potrebbe anche fare:

document.querySelector('.active').classList.remove('active') 

Ma mi piace ridurre la quantità di lettura DOM.

Buona fortuna per il tuo apprendista, la riscrittura di un codice jQuery in Vanilla JS sembra un buon metodo e potresti acquisire una comprensione molto migliore di JavaScript.

4

Se si utilizza this, penso che sia meglio e una soluzione più lucida. Se si desidera utilizzare ancora tabNumber, è probabilmente in corso la valutazione su 3 in ogni richiamo di clic, poiché è il numero dopo l'ultima iterazione e non si dispone di una posizione tabs[3].

Quindi, è sufficiente chiudere la variabile tabNumber.

Problemi correlati