2013-10-06 84 views
0

在此代碼中,我應該將傾斜效果綁定到<map>元素中的每個<area>標記。爲什麼這個javascript綁定事件的正確參數?

function initLinks(webrt) { 
    var areas = document.querySelectorAll("map#streetmap > area"); 
    var links = new Array(areas.length); 
    for (var i=0; i<links.length; i++) { 
    links[i] = new Image(786,272); 
    links[i].src = webrt+"templates/default/sketches/links"+(i+1)+".png"; 
    areas[i].onmouseover=function(){switchLinkImg(webrt+"templates/default/sketches/links"+(i+1)+".png");}; 
    areas[i].onmouseout=function(){switchLinkImg(webrt+"templates/default/sketches/links.png");}; 
    } 
} 

奇怪的是,每個<area> onmouseover事件試圖加載不存在的圖像:/templates/default/sketches/links6.png。爲什麼它保持這個變量i,它已經增加到6作爲一個全局變量,而不是把我傳遞給函數的字符串?

我該如何解決這個問題?

注意:沒有jQuery!

+0

因爲只有一個*變量,稱爲'i'和'webrt'。搜索「JavaScript循環關閉」。 – user2246674

+0

請參閱http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example - 使用「雙閉合」或「Function.bind」。 – user2246674

+0

@ user2246674我遇到的困惑是當我傳遞字符串'webrt +「templates/default/sketches/links」+(i + 1)+「。」png「''不應該將函數綁定到結果字符串? – user1094607

回答

1

嘗試使用下面的代碼:

function initLinks(webrt) { 
    var areas = document.querySelectorAll("map#streetmap > area"); 
    var links = new Array(areas.length); 
    for (var i=0; i<links.length; i++) { 
     (function(index) { 
      links[index] = new Image(786,272); 
      links[index].src = webrt+"templates/default/sketches/links"+(index+1)+".png"; 
      areas[index].onmouseover=function(){switchLinkImg(webrt+"templates/default/sketches/links"+(index+1)+".png");}; 
      areas[index].onmouseout=function(){switchLinkImg(webrt+"templates/default/sketches/links.png");}; 
     })(i); 
    } 
} 

你應該換行變量爲關閉。否則它會增加。

+0

關於解釋:'i' *已經被綁定在一個閉包中,這就是問題所在。解決方案不是創建一個新的閉包 - 它是*引入一個新的變量範圍*(然後每個循環都是不同的)。 – user2246674

+0

謝謝,我仍然覺得這種行爲很奇怪,但至少現在我知道如何避免它。 – user1094607

+1

是的,我的解釋是不正確的。我的意思是你應該把* i *放在一個新的範圍內。否則它在for循環的範圍內,* i *的值實際上在那裏變化。 – Krasimir

2

我常常發現,清潔劑使用索引的時候,因爲你並不需要額外的包裝採用陣列的方法,一切都讀一點清潔劑(恕我直言):

function initLinks(webrt) { 
    [].forEach.call(document.querySelectorAll("map#streetmap > area"), 
     function(elm, index){ 
      var img = new Image(786,272); 
      img.src = webrt+"templates/default/sketches/links"+(index+1)+".png"; 
      elm.onmouseover=function(){switchLinkImg(webrt+"templates/default/sketches/links"+(index+1)+".png");}; 
      elm.onmouseout=function(){switchLinkImg(webrt+"templates/default/sketches/links.png");}; 
    }); 
} 

變量count一路下滑,並我們通過在「循環」的每次迭代中不創建額外的新函數來避免額外的內存佔用關閉。

可以肯定的是,這兩種方法都可以工作,但是新的數組方法也可以通過將它從forEach()調用中剝離出來並給它起個名字來允許該過程被回收。

相關問題