jQuery og lukking

stemmer
1

Jeg har en multippel-menyen er på min side som alle bruker samme mouse og klikk hendelser, så jeg bestemte meg for å få det inn i en funksjon. Men vars synes å alltid bli tildelt den siste av argumentene for hover (funksjon, funksjon) -funksjonen.

$(document).ready( function() {
menuMouseOver = function() {
    for(i=0, u=arguments.length; i<u; i++){
        var parent = arguments[i].parent;
        var active = arguments[i].active;
        var childSelect = arguments[i].childSelect;
        console.log(active); //logs the correct active
            $(parent).children(childSelect)
                .not('.'+active).each( function(i, e) {console.log(active);})
 //The above console.log logs the correct active 
                    .hover( function() {
                            console.log(active); //this one always logs menu2_active
                            $(this).addClass(active);
                        }, function() {
                            $(this).removeClass(active);
                        });
    }
}
menuMouseOver( { parent: '#menu1',
                active: 'menu1_active',
                childSelect: ':gt(0)'},
            { parent: '#menu2',
                active: 'menu2_active',
                childSelect: ':gt(0)'});
});

Hvorfor er er at den siste console.log vil alltid logger den siste aktive i stedet for en som tilhører argumenter [i] .active. (I dette eksempelet det alltid logger aktive argumenter [1] .active) Hva gjør jeg galt?

Dessuten er den virkelige funksjon mer komplisert, men problemet er også til stede i denne varianten.

Publisert på 29/01/2009 klokken 17:23
kilden bruker
På andre språk...                            


3 svar

stemmer
1

Ditt problem er at hover hendelsen skjer utenfor rammen av å utføre metoden. Så da hover utfører din aktive variabel har allerede gått gjennom hele settet og hviler på den aktive tilstanden til siste element. Så du ser dette problemet, fordi det siste loggen er en hendelse, som er ute av omfang, og de to andre er i-omfang i løkkene.

Prøv dette:

        $(parent).children(childSelect)
            .not('.'+active).each( function(i, e) {
                console.log(active);
                $(this).data("active", active);
            })
            .hover( function() {
                $(this).addClass($(this).data("active"));
            }, function() {
                $(this).removeClass($(this).data("active")));
            });

Dette vil faktisk lagrer den 'aktive' verdi på innsiden av DOM-elementet, slik at det kan nås i omfang.

Svarte 29/01/2009 kl. 17:40
kilden bruker

stemmer
0

Jeg reoler min hjerne fordi det er en merkelig sak, men jeg refactored funksjonen litt, kan være nyttig (oh, noen mye flinkere svarte i mellomtiden):

$("#menu1,#menu2").each(function(){
    var id = $(this).attr("id");
    $(">li",this).not("."+id+"_active,:eq(0)").hover(function(){
        $(this).addClass(id+"_active");
    },function(){
        $(this).removeClass(id+"_active");
    });
});
Svarte 29/01/2009 kl. 18:04
kilden bruker

stemmer
4

Javascript har ikke blokken omfang, slik at disse variablene du erklærer i for loop har sine verdier endres hver iterasjon, og alle disse funksjonene referere de samme variablene. Trikset er å opprette en ny funksjon omfang innen for loop, slik at de variablene du erklærer er bundet i denne iterasjon.

Du kan oppnå dette ved å utføre en anonym funksjon inne i bue:

menuMouseOver = function() {
    for(i=0, u=arguments.length; i<u; i++){
      (function(){ // anonymous function to create new scope
        var parent = arguments[i].parent;
        var active = arguments[i].active;
        var childSelect = arguments[i].childSelect;
        console.log(active); //logs the correct active
            $(parent).children(childSelect)
                .not('.'+active).each( function(i, e) {console.log(active);})
 //The above console.log logs the correct active 
                    .hover( function() {
                            console.log(active); //this one always logs menu2_active
                            $(this).addClass(active);
                        }, function() {
                            $(this).removeClass(active);
                        });
       })(); // execute the anonymous function
    }
}

Måten du hatt det før, alle dere funksjoner stengt over de samme variable referanser, og så vant hva noensinne den siste verdien var, ikke verdien av når funksjonen ble opprettet. Ved hjelp av funksjonen omfanget vil ha det oppføre seg som du hadde tenkt.

Svarte 29/01/2009 kl. 18:05
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more