1. 程式人生 > >初學筆記之:Java_Script的for迴圈事件繫結

初學筆記之:Java_Script的for迴圈事件繫結

學了好幾天JS,一直糾結於for迴圈事件繫結,我一直不理解,想找到一些解釋,以下是個人研究一個下午後的一些見解,有不對的還望大神們指正,輕噴。在這裡謝過啦。

首先,目的是做一個滑動切換圖片的效果,上JS程式碼:

// 拿物件
// 獲取所有的按鈕div,返回一個數組
var barArr=document.getElementsByClassName("up_stript_div_bar")
//定義一個圖片的陣列
var imgSrcArr=new Array("images/視訊.jpg","images/秒拍.jpg","images/綜藝.jpg")



往後,一開始我是這樣寫的:“勤快寫法”
barArr[0].onmouseover=function overIt() {
document.getElementById("imgBig").src=imgSrcArr[0];

}
barArr[1].onmouseover=function overIt() {
document.getElementById("imgBig").src=imgSrcArr[1];
}
barArr[2].onmouseover=function overIt() {
document.getElementById("imgBig").src=imgSrcArr[2];
}
發現是可以的;

然後,就想試一下for迴圈繫結,程式碼如下:
for(var i=0;i<barArr.length;i++){
barArr[i].onmouseover=function overIt() {
document.getElementById("imgBig").src=imgSrcArr[i];
}

}
結果顯示:undefined:1 Failed to load resource: the server responded with a status of 404 (Not Found)
當時我就好奇了,什麼情況??
for迴圈理論上,是一種迭代偷懶的計數器,你給他設定範圍,設定步長,他就做事。難道結果不是跟第一種如下一開始的一樣麼?
barArr[0].onmouseover=function overIt() {
document.getElementById("imgBig").src=imgSrcArr[0];

}
barArr[1].onmouseover=function overIt() {
document.getElementById("imgBig").src=imgSrcArr[1];
}
barArr[2].onmouseover=function overIt() {
document.getElementById("imgBig").src=imgSrcArr[2];
}
經過我的思考我發現了這點:
最上面這種全部列出來的“勤快寫法”;大致可以看成是這樣
[0]------[0]
[1]------[1]
[2]------[2]
而上面那個for迴圈的結果是什麼呢?
我原以為也是這樣,因為通過列印,發現,他是執行完0,1,2的過程的,難道不是左右都有,然後等待滑鼠事件?
但其實應該只有一半!:

他是分兩步來完成的:
第一:
[0]----
[1]---
[2]---
for迴圈結束,一切定格,它能做的就這麼多啊

第二:

滑鼠事件發生
[0或1或2] ------i
因為後一半要通過滑鼠事件才可以顯現,它是被好好的保護著的,一旦滑鼠事件發生,好傢伙,function部分醒過來了,手上拿著i,問i是多少,好的,i是3,於是,你到哪找3給它。於是就報錯了。
它根本沒有完成開頭的“勤快寫法的全部”,(for迴圈就是為了減少程式碼量的)

所以,問題在於,怎麼把“勤快寫法”給表現出來。做的事情不能少。


問題知道了,下面看怎麼解決:

解決一:用另外一個跟隨被點選物件的自定義屬性來複制一份[0][1][2]
簡單說,就是
被點的物件,都手持一個牌子,被點的時候,就告訴後面一個數組,牌子的標號。看程式碼:
for(var i=0;i<barArr.length;i++){
// console.log(i)
barArr[i].n=i;
barArr[i].onmouseover=function () {
console.log(i)
document.getElementById("imgBig").src=imgSrcArr[this.n];

}
}
變成了這樣:
n
[0]--[0]---
[1]--[1]---
[2]--[2]---
滑鼠點選時,i=3,但是要什麼緊。又不根據i找,你點哪個,我把對應的n給你,因為複製好一份對應的n的一列。這個完成了操作,就跟對映列表一樣,都對應好了。


解決二:
閉包:
這個是我自學的。
大概意思就是,函式包函式,這個在java裡面是不允許的,一般是函式包一個函式的呼叫。
但有一條一樣:就是如果一個函式的內在成員如果是被另一個函式引用的話,那他就不會被垃圾回收機制幹掉(java和js都有垃圾回收機制)
一開始我是這樣寫的:想著閉包,乾脆別那麼麻煩,少些那個註釋的兩行:看程式碼:

for(var i=0;i<barArr.length;i++){
barArr[i].onmouseover=(function (i) {
// return function () {
document.getElementById("imgBig").src=imgSrcArr[i]
}

//})(i)

}
思考:那兩條雙斜槓的,少了會怎麼樣?

那是一個自執行函式,簡單來說,這樣(function(i){巴拉巴拉})(i),就是他可以自己自動執行,可以傳參。
問題是,它到底是個什麼過程?如下?
[0]--[0]
[1]--[1]
[2]--[2]

滑鼠事 i=3
這個更有意思,我覺得,它是執行完,但都隨後直接彈棧了。。。。。因為,它執行完了,根本不需要滑鼠事件了。。。。

於是,閉包就來了
首先:它內部函式吊著外面的變數,他不會被回收
具體,我覺得是這樣,它是真的完成了操作,也沒借助額外的屬性設定:
[0]--[0]
[1]--[1]
[2]--[2]
for迴圈結束,
i=3
滑鼠事件,就跟一開頭的“勤快寫法一樣”

所以,關鍵點在於閉包,它沒彈棧。


總結:最先前的,直接寫i的那種,滑鼠事件之前,它完成了左邊的賦值,右面沒有,滑鼠事件一發生,i的值是4
閉包:用的是它內部函式吊著外面的一個變數,它不彈棧。

今天研究了一個下午的成果,如上。


多謝學習給我帶來快樂!

加油!