2016-03-14 59 views
6

我一直在嘗試通過將一本書中的一些jquery示例重構爲javascript來學習javascript。在以下代碼中,我將一個點擊偵聽器添加到一個選項卡,並在用戶單擊該選項卡時將其更改爲活動狀態。試圖讓我的JavaScript代碼中的「this」有意義(一件事情有效,另一件事不行)

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(); 
 
    }); 
 
}

當我運行它這將返回undefined error。但是,我試圖用this.classList.add("active")替換tabs[tabNumber].classList.add("active"),它工作。

爲什麼前面的代碼不工作?據我所見,他們指的是同樣的事情,並且tabs[tabNumber]應該工作,因爲在該代碼中它是tabs[0]

+3

如果你在你的事件處理程序中使用console.log(tabNumber),你會發現它是3,不管你點擊了哪個項目。 – nnnnnn

+0

儘可能地使用'let'作for循環,但這個問題可以通過關閉或你在JS代碼中引用它的地方來解決。 – Gary

回答

3

我想其他答案告訴你爲什麼tabs[tabNumber]不起作用(因爲它來自for循環的分數,所以,總是等於tabNumber的更大值)。

這就是爲什麼我會建議使用.forEach循環。小心,但因爲它沒有對document.querySelectorAll()產生的DOM節點陣列工作,但你可以使用:反正

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

,我做你的代碼的簡化working demo。 請注意,我將當前活動的選項卡保存在一個變量中,以防止另一個for循環。你也可以這樣做:

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

但我喜歡減少DOM閱讀量。

祝你好運,將一些jQuery代碼重新寫入Vanilla JS似乎是一個好方法,並且你可能獲得更好的JavaScript理解。

4

如果使用this,我認爲這是更好的和更精細的解決方案。如果您仍然想使用tabNumber,則可能在每次點擊回叫時評估爲3,因爲這是最後一次迭代後的數字,並且您沒有tabs[3]的位置。

所以,你只需要關閉tabNumber變量。

相關問題