Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

im a bit stuck here. Some hints would be really nice.
Asume i have to have a multi-dimensional array of objects, the objects contain functions i want to use on mouseover (play, stop, showFrame, etc.). But they are not all loaded yet, so my first approach was using

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

until i ran into a closure problem, that was already discussed a couple of times here on StackOverflow and on other places. First i tried to encounter the problem with a solution given on another SO-thread, until i ran into the eventData that you could pass within .bind(). The SO-closure solution i had first is commented in the following, active code contains my approach with .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
            }
        }
    }
  }
});

So i have a 3d-array menu[][][], defining the structure, the 3d-array of objects[][][] with their play(), stop() etc functions, on the html-page i have 3 menu divs, #menu0, #menu1, #menu2 which would contain the appropriate depths' menu.
Basically both solutions work BUT only for elements that are already loaded on the page from the beginning. The mouseover-part for example is not triggered on div's that are load()ed later on, but very well match the selector

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

For the alternative solution that i found here on SO, you would remove the comments in the beginning to get that anonymous function, replace all occurences of e.data.** with the appropriate ** only, replace all the .binds with .on and of course remove the { fr:f, gr:g, hr: h} eventData parts. Oh, and remove the comment in the end where the function is directly beeing executed })();

Any hint would be great, thanks in advance for your time.

----edit----

Accepted, this is a total mess. Im going to go a different way, thanks for the help. Yet the logical problem still exists, even in simpler forms, and im really interested in the answer, just to understand what the basic logical problem behind it is. There must be something either about the closure fix or on() that i dont understand. So i re-asked the question with a much simpler example at jQuery: click function bind in for-loop with closure fix .

share|improve this question
1  
Hi Karl. In all honesty I don't think the code is salvageable. If by some chance you get it working it will be unmaintainable in the future. You can probably achieve what you are trying to do with 5-10 lines of code, no loops, no 3-dimensional arrays, and no duplication. You could post a new question with your problem statement distilled into its simplest form and proceed from there. –  david Oct 27 '12 at 18:03

1 Answer 1

up vote 0 down vote accepted

Your code looks too complicated - thats a problem. I think you should look on backbone.js or similar frameworks to structure your data and separate logic from views. Backbone(and underscore) have a very useful methods to work with collections and models.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.