4

ここでちょっと立ち往生しています。いくつかのヒントは本当にいいでしょう。
オブジェクトの多次元配列が必要であると仮定します。オブジェクトには、マウスオーバーで使用したい関数 (再生、停止、showFrame など) が含まれています。しかし、それらはまだすべてロードされていないので、私の最初のアプローチは

.on("mouseover", function () { ... }

閉鎖の問題に遭遇するまで、それはここStackOverflowや他の場所ですでに数回議論されていました. 最初に、.bind() 内で渡すことができる eventData に遭遇するまで、別の SO スレッドで与えられた解決策で問題に遭遇しようとしました。私が最初に持っていた SO クロージャー ソリューションは、次のようにコメントされています。アクティブなコードには、.bind eventData を使用した私のアプローチが含まれています。

$(function(){
    for (var r=0, firDep=menu[0][0].length; r<firDep; r+=1){
        objects[0][0][r].init();
}
for(var f=0, livLen=menu.length; f<livLen; f++){
    for(var g=0, livWid=menu[f].length; g<livWid; g++){
        for(var h=0, livDep=menu[f][g].length; h<livDep; h++){
            if(menu[f][g][h]){
//                  (function( ) {
//                        var fr = f;
//                        var gr = g;
//                        var hr = h;
// to apply this prior solution, i would simply replace all occurences of e.data.** with ** again and all .bind's with .on's
                    $('#'+menu[f][g][h]).bind("mouseover", { fr: f, gr: g, hr: h}, function(e) {
                        if(objects[e.data.fr][e.data.gr][e.data.hr].status==0){
                            objects[e.data.fr][e.data.gr][e.data.hr].showFrame(1);
                        }
                    });
                    $('#'+menu[f][g][h]).bind("mouseout", { fr: f, gr: g, hr: h}, function(e) {
                        if(objects[e.data.fr][e.data.gr][e.data.hr].status==0){
                            objects[e.data.fr][e.data.gr][e.data.hr].showFrame(0);
                        }
                    });
                    $('#'+menu[f][g][h]).bind("click", {fr: f, gr: g, hr: h}, function(e) {
                        e.preventDefault();
                        if(objects[e.data.fr][e.data.gr][e.data.hr].status!=1 || objects[e.data.fr][e.data.gr][e.data.hr].status!=2){
                            for(var t=0, tstLen=menu[e.data.fr][e.data.gr].length; t<tstLen; t++){
                                if(objects[e.data.fr][e.data.gr][t].status==1 || objects[e.data.fr][e.data.gr][t].status==2){
                                    objects[e.data.fr][e.data.gr][t].stop();
                                    objects[e.data.fr][e.data.gr][t].playReverse();
                                }
                            }
                            objects[e.data.fr][e.data.gr][e.data.hr].stop();
                            objects[e.data.fr][e.data.gr][e.data.hr].play();
                            finc = e.data.fr+1;
                            if(menu[finc][e.data.hr] && menu[finc][e.data.hr].length > 0){
                                $('#menu'+finc).load('menu'+finc+e.data.hr+'.php', function () {
                                    for(var b=0, ldLen=menu[finc][e.data.hr].length; b<ldLen; b++){
                                        objects[finc][e.data.hr][b].init();
                                    }
                                    $('#menu'+finc).slideDown('slow');
                                });
                            } else {
                                if ($('#menu2').is(':visible')) {
                                    $('#menu2').slideUp('slow', function () {
                                        $('#menu1').slideUp('slow', function () {
                                            $('#menu1').empty();
                                            $('#menu2').empty();
                                        });
                                    }); 
                                } else if ($('#menu1').is(':visible')){
                                    $('#menu1').slideUp('slow', function () {
                                        $('#menu1').empty();
                                    });
                                }
                            }
                            loadContent(menu[e.data.fr][e.data.gr][e.data.hr]+".php");
                        }
                    });
                //})(); //function execution for prior closure-defeating attempt
            }
        }
    }
  }
});

だから私は3D配列メニュー[] [] []を持っていて、構造を定義し、オブジェクトの3D配列[] [] []とそれらのplay()、stop()などの関数を、私が持っているHTMLページに持っています適切な深さのメニューを含む 3 つのメニュー div、#menu0、#menu1、#menu2。
基本的に、両方のソリューションは機能しますが、最初からページに既に読み込まれている要素に対してのみ機能します。たとえば、mouseover-part は、後で load() される div ではトリガーされませんが、セレクターに非常によく一致します

$('#'+menu[f][g][h]).

ここSOで見つけた別の解決策については、最初にコメントを削除してその匿名関数を取得し、e.data.**のすべての出現を適切な**のみに置き換え、すべての.bindsを.onに置き換えますそしてもちろん { fr:f, gr:g, hr: h} eventData 部分を削除します。ああ、関数が直接実行されている最後のコメントを削除します })();

お時間をいただきありがとうございます。

- - 編集 - -

受け入れられました、これは完全な混乱です。私は別の道を行くつもりです、助けてくれてありがとう。しかし、論理的な問題は、より単純な形式であっても依然として存在し、その背後にある基本的な論理的な問題が何であるかを理解するために、その答えに本当に興味があります. クロージャーの修正または on() について、私が理解できない何かがあるに違いありません。そこで、jQuery でのはるかに単純な例で質問を再質問しました : click function bind in for-loop withclosure fix

4

1 に答える 1

0

コードが複雑すぎるように見えます-それは問題です。データを構造化し、ロジックをビューから分離するには、 backbone.jsまたは同様のフレームワークを検討する必要があると思います。バックボーン(およびアンダースコア)には、コレクションおよびモデルを操作するための非常に便利なメソッドがあります。

于 2012-10-27T17:54:26.937 に答える