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

标签 jquery arrays object closures

我有点卡在这里了。一些提示真的很好。
假设我必须有一个多维对象数组,这些对象包含我想在鼠标悬停时使用的函数(播放、停止、showFrame 等)。但它们还没有全部加载,所以我的第一个方法是使用

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

直到我遇到了闭包问题,这个问题已经在 StackOverflow 和其他地方讨论过几次了。首先,我尝试使用另一个 SO 线程上给出的解决方案来遇到问题,直到我遇到可以在 .bind() 中传递的 eventData。我首先拥有的 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,其中包含适当深度的菜单。
基本上,这两种解决方案都有效,但仅适用于从一开始就已加载到页面上的元素。例如,鼠标悬停部分不会在稍后加载()的 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 .

最佳答案

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

关于jQuery:将函数绑定(bind)到数组中的对象,避免关闭错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13102318/

相关文章:

javascript - 我可以在创建对象时在该对象内部保留该对象的副本吗

javascript - jQuery:鼠标交互 + 简单动画 [img]

javascript - 在表的开头添加/附加列

arrays - Bash Looping 2 Arrays with whitespaces in variables

ios - 将 byte[] 转换为 NSData 后数据损坏

javascript - 将数组转换为对象,其中数组值为对象键,对象值为空

javascript - 如何在 JQuery 中使用动态值填充 <select> 元素?

javascript - 为什么使用鼠标悬停会产生滞后体验? jQuery

java - 合并排序代码抛出 NullPointerException

jQuery 将元素传递给 dataTransfer 属性