2013-04-30 95 views
0

用RaphaelJS庫繪製一組圓。onclick函數的參數

對於每個圓圈,我想創建一個傳遞變量的onclick函數,但在此函數中,我的變量未定義。

什麼問題?

這是我的代碼:

//children is an array such as [1,2,4[5,6,7]] 
for (var i = 0; i < children.length; i++) { 
    var array = children; 
    alert("ARRAY[0]===" + array[0]) 

    var st = space2Draw.set(); 
    st.push(space2Draw.circle(xChildren, yChildren, 20).click(function (array) { 
     //array[i] is undefined 
     alert("ARRAY[i]===" + array[i]); 
     //retrive(array[i]); 
    }), 
    LineRoot(xRadice, yRadice, xChildren, yChildren, space2Draw)); 
    space2Draw.text(xChildren, yChildren, children[i]).attr({ 
     fill: "white" 
    }); 
    st.attr({ 
     fill: "red" 
    }); 

    xChildren += 50; 
} 

回答

1

你應該這樣做:

... 
st.push(space2Draw.circle(xChildren, yChildren, 20).click((function (array, i) { 
    return function() { 
     //array[i] is undefined 
     alert("ARRAY[i]===" + array[i]); 
     //retrive(array[i]); 
    } 
}(array, i))); 
... 

之所以這樣,工作原理是,在JavaScript中,範圍是指由函數,而不是塊。

你的回調獲得訪問(通過關閉)到arrayi(其它變量),但是當回調被執行,i等於children.length,因爲循環完成迭代。

通過使用IIFE(立即調用函數表達式),我們創建一個新的範圍,回調能存取的arrayi當前值。


此外,click功能通過傳遞一個event對象作爲第一個參數調用回調,所以我們IIFE應該回到這個

return function (event) { 
    // access array and i by closure 
    // event is the event representing the click 
    // event, provided by Raphael 

    // do something 
} 
2

你不應該有一個「陣列」參數到點擊的回調,它覆蓋從父範圍「陣列」變種。你可以刪除參數,它應該沒問題。

我想你會遇到另一個問題,我總是在你的點擊回調中使用children.length(因爲函數的作用域實際上會在循環結束時關閉)更多信息here)。你應該創建一個輔助函數來爲你創建回調。

你可以嘗試這樣的事:

//children is an array such as [1,2,4[5,6,7]] 
for (var i = 0; i < children.length; i++) { 
    var array = children; 
    alert("ARRAY[0]===" + array[0]) 

    var st = space2Draw.set(); 
    st.push(space2Draw.circle(xChildren, yChildren, 20).click(getCallback(array , i)), 
    LineRoot(xRadice, yRadice, xChildren, yChildren, space2Draw)); 
    space2Draw.text(xChildren, yChildren, children[i]).attr({ 
     fill: "white" 
    }); 
    st.attr({ 
     fill: "red" 
    }); 

    xChildren += 50; 
} 

function getCallback(array , i){ 
    return function() { 
     alert("ARRAY[i]===" + array[i]); 
    } 
}