0

Raphael JSを発見しましたが、forループで生成された要素に適用されるマウスイベントについて質問があります。

5つの長方形を出力するサンプルコードは次のとおりです。

var paper = Raphael("canvasTest",200,200);
for(var i = 0 ; i < 5 ; i++){
    var rect = paper.rect((i*15)+5,10,10,10);
    rect.attr("fill","blue");
    rect.hover(
        function(){
            rect.attr("fill","red");
            document.getElementById("info").innerHTML="Hovered: "+i;
        }, 
        function(){
           rect.attr("fill","blue");
        }
    );
}

これにより、次の出力が生成されます。

出力

問題は、5番目の長方形だけが赤くなり(別の長方形がホバーされている場合でも)、infodivは常に5番目の長方形がホバーされていることを出力することです。

5番目の長方形のみが赤で表示されます。

this内部関数内で使用でき、問題を部分的に解決できることがわかりました。上記のコードは正しい長方形を赤で色付けしますが、情報コンテナは5番目の長方形がホバーされていることを出力します。

rect.hover(
    function(){
        this.attr("color","red");
        ...
    },
    ...
);

これを解決するための最もクリーンな方法は何ですか?rectなどのカスタムフィールドを設定rect.someVariable=iし、それを内部関数で参照することを考えています。しかし、おそらくもっときれいなものがありますか?

よろしくお願いします。

4

2 に答える 2

3

ほとんどの状況でChrisWilsonの手法のいずれかを使用することをお勧めしますが、ユーティリティ関数のデブリフィールドで現在の名前空間を汚染することなく同じ目的を達成するバリエーションがあります。簡単に言えば、正式に定義された関数でクロージャーを作成する代わりに、ループ内で無名関数を使用してクロージャーを作成するだけです。

for(var i = 0 ; i < 5 ; i++) {
    var rect = paper.rect((i*15)+5,10,10,10);
    rect.attr("fill","blue");
    ( function( rect, i ) {
        rect.hover(
            function() {
                rect.attr("fill","red");
                document.getElementById("info").innerHTML="Hovered: "+i;
            }, 
            function() {
                rect.attr("fill","blue");
            }
        ); } )( rect, i );
} 

iこのような構成は、ループ変数の特定のインスタンスを、forループの制約内で作成されたクロージャに埋め込むだけです。簡単、簡単。

于 2013-02-21T18:40:32.663 に答える
3

「ループ内で関数を作成しない」は、野球の「1番目または3番目を3番目に作成しない」に相当するJavascriptです。違反する可能性がありますが、正当な理由がある場合に限ります。あなたはそうしない。したがって、閉鎖する必要があります。

var paper = Raphael("canvasTest",200,200);

var mybox = function(i) {
    var rect = paper.rect((i*15)+5,10,10,10);
    rect.attr("fill","blue");
    rect.hover(
        function(){
            this.attr("fill","red");
            document.getElementById("info").innerHTML="Hovered: "+i;
        }, 
        function(){
           this.attr("fill","blue");
        } 
    );
    return {
        get_rect: function() { return rect; }
    };
};

for(var i = 0 ; i < 5 ; i++){
    mybox(i);
}

jsFiddle

Doug Crockfordの「Javascript:The Good Parts」は、その理由を理解するのに最適な場所です。何らかの理由でこれを本当に実行したくない場合は、Raphaelの.data()メソッドを使用してオブジェクトのiaプロパティを作成することもできます。

var paper = Raphael("canvasTest",200,200);
for(var i = 0 ; i < 5 ; i++){
    var rect = paper.rect((i*15)+5,10,10,10);
    rect.data("myindex", i + 1);
    rect.attr("fill","blue");
    rect.hover(
        function(){
            this.attr("fill","red");
            document.getElementById("info").innerHTML="Hovered: " + this.data("myindex");
        }, 
        function(){
           this.attr("fill","blue");
        }
    );
}

私は最初の方法を強くお勧めします。

于 2013-02-20T15:17:04.993 に答える