我有点卡在这里了。一些提示真的很好。
假设我必须有一个多维对象数组,这些对象包含我想在鼠标悬停时使用的函数(播放、停止、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/