2013-05-06 23 views
0

我有以下代碼爲什麼在Javascript中使用閉包時mouseover事件不起作用?

<ul> 
    <li>one</li> 
    <li>two</li>   
    <li>three</li> 
    <li>four</li> 
</ul> 

var lists = document.getElementsByTagName("li"); 

for(var i=0, len = lists.length; i< len; i++){ 
    lists[i].onmouseover = function(){ 
     console.log(i); 
    }(i); 
} 

預期結果:當鼠標在每個li,我在控制檯得到0或1或2或3,但刷新頁面時不mouseover我只得到的那些數目,有人知道爲什麼嗎?

回答

3

的「呼叫括號」 (i)函數表達式後功能立即執行並分配它的返回值作爲事件處理程序(它是undefined)。這裏是一個函數聲明,這使得它更容易看到(希望)一個例子:

function foo(i) { 
    console.log(i); 
} 

// in the loop 
lists[i].onmouseover = foo(i); 

查看如何foo被調用,返回值被分配到lists[i].onmouseover

你必須從立即調用函數表達式返回一個函數:

lists[i].onmouseover = (function(i){ 
    return function() { 
     console.log(i); 
    }; 
}(i)); 

或函數聲明:

function createHandler(i) { 
    return function() { 
     console.log(i); 
    }; 
} 

// in the loop 
lists[i].onmouseover = createHandler(i); 

更多信息:JavaScript closure inside loops – simple practical example

+0

是必要的return語句? (i);'code'對不起,可能是這樣的: } }(i);'code'對不起, ,我不知道如何在評論中格式化代碼。 – user2301368 2013-05-06 07:06:46

+0

是的,您也可以這樣做,您必須將立即執行的功能「上一級」。它雖然沒有改變,但它仍然以相同的方式工作。 – 2013-05-06 07:08:26

+0

非常感謝Felix Kling,你的回覆非常詳細,我想我明白了你的觀點。 – user2301368 2013-05-06 07:13:04

相關問題