0

RaphaelJS ライブラリを使用して円のセットを描画します。

円ごとに、変数を渡す関数を作成したいのです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;
}
4

2 に答える 2

2

クリック コールバックに「配列」パラメーターを指定しないでください。親スコープの「配列」変数をオーバーライドしています。引数を削除するだけで問題ありません。

クリックコールバックで i が常に children.length であるという別の問題があると思います(ループの最後で関数スコープが実際に閉じられるためです。詳細はこちらをご覧ください)。コールバックを作成するには、補助関数を作成する必要があります。

次のようなことを試すことができます:

//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]);
    }
}
于 2013-04-30T13:01:07.220 に答える
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 ではスコープがブロックではなく関数によって定義されるためです。

コールバックは (クロージャによって) arrayand i(他の変数の中でも) にアクセスしますが、ループが反復を終了したため、コールバックが実行されると、iは に等しくなります。children.length

IIFE (即時呼び出し関数式) を使用して新しいスコープを作成し、コールバックが と の現在の値にアクセスarrayしますi


また、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
}
于 2013-04-30T13:02:26.293 に答える