jQuery:将函数绑定到数组中的对象,避免了关闭错误

时间:2012-10-27 17:12:10

标签: jquery arrays object closures

我有点卡在这里。一些提示会非常好。
我必须拥有一个多维的对象数组,这些对象包含我想在鼠标悬停时使用的功能(play,stop,showFrame等)。但它们尚未全部加载,所以我的第一种方法是使用

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

直到遇到闭包问题,这已经在StackOverflow和其他地方讨论了几次。首先,我尝试用另一个SO线程给出的解决方案来解决问题,直到我遇到你可以在.bind()中传递的eventData。我首先注意到的SO-closure解决方案在下面进行了评论,活动代码包含我的方法.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,其中包含相应的深度菜单。
基本上两种解决方案都只适用于从一开始就已经加载到页面上的元素。例如,鼠标悬停部分不会在稍后加载()的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 with closure fix

1 个答案:

答案 0 :(得分:0)

您的代码看起来太复杂 - 这就是问题所在。我认为您应该查看backbone.js或类似的框架来构建数据并将逻辑与视图分开。 Backbone(和下划线)有一个非常有用的方法来处理集合和模型。