Frage

Das Ziel

Ich möchte Event -Handler dynamisch einigen Divs auf Seiten auf einer Website zuweisen.

Meine Methode

Ich verwende JQuery, um anonyme Funktionen als Handler für ausgewählte Div -Ereignisse zu binden.

Das Problem

Der Code iteriert eine Reihe von Div -Namen und zugehörigen URLs. Der DIV -Name wird verwendet, um das Bindungsziel zu setzen, dh diesen Ereignishandler an dieses DIV -Ereignis angehängt.

Während die Ereignishandler erfolgreich an jedes der DIV -Ereignisse gebunden sind, zielen die von diesen Ereignishandlern ausgelösten Aktionen immer nur auf das letzte Element im Array ab.

Die Idee ist also, dass der Benutzer, wenn er über ein bestimmtes DIV stammt, eine Ausrutschenanimation für diese DIV ausführen sollte. Stattdessen löst das Mäuschen über Div1 (Rangetaball) eine Ausrutschenanimation für Div4 (Rangetabthmus) aus. Gleiches gilt für Divs 2, 3 usw. Die Bestellung ist unwichtig. Ändern Sie die Array -Elemente um und Ereignisse zielen immer auf das letzte Element im Array Div4 ab.

Mein Code - (verwendet jQuery)

var curTab, curDiv;
var inlineRangeNavUrls=[['rangeTabAll','range_all.html'],['rangeTabRem','range_remedial.html'],
                ['rangeTabGym','range_gym.html'],['rangeTabThm','range_thermal.html']];
        for (var i=0;i<inlineRangeNavUrls.length;i++)
        {
            curTab=(inlineRangeNavUrls[i][0]).toString();
            curDiv='#' + curTab;
            if  ($(curDiv).length)
            {
                $(curDiv).bind("mouseover", function(){showHideRangeSlidingTabs(curTab, true);} );
                $(curDiv).bind("mouseout", function(){showHideRangeSlidingTabs(curTab, false);} );
            }
        }

Meine Theorie

Ich sehe entweder keinen blendend offensichtlichen Syntaxfehler oder ist ein PASS -BY -Referenzproblem. Anfangs hatte ich die folgende Aussage, um den Wert von Curtab festzulegen:

curTab=inlineRangeNavUrls[i][0];

Als das Problem auftrat, stellte ich fest, dass ich bei der Veränderung (über die Schleifen -Iteration) den Hinweis auf Curtab tatsächlich war, tatsächlich war ich tatsächlich Ändern Die Referenz für alle früheren anonymen Funktionen Event -Handler auf den neuen Curtab -Wert .... Deshalb zielten Ereignishandler immer die letzte Div.

Ich musste also wirklich den Curtab bestehen Wert zu den anonymen Funktionen Ereignis Handlern nicht der Curtab Objekt Hinweis.

Also dachte ich:

curTab=(inlineRangeNavUrls[i][0]).toString();

Würde das Problem beheben, aber es tut es nicht. Gleicher Deal. Ich vermisse also klar, dass ich einen Schlüssel und wahrscheinlich sehr grundlegendes Wissen über das Problem fehlt. Vielen Dank.

War es hilfreich?

Lösung

Sie müssen auf jedem Durchgang eine neue Variable durch die Schleife erstellen, damit sie in den Schließungen, die Sie für die Event -Handler erstellen, erfasst werden.

Wenn Sie jedoch nur die Variablenerklärung in die Schleife verschieben JavaScript führt keinen neuen Umfang für willkürliche Blöcke ein.

Eine einfache Möglichkeit, die Einführung eines neuen Bereichs zu erzwingen, besteht darin, eine andere anonyme Funktion zu verwenden:

for (var i=0;i<inlineRangeNavUrls.length;i++)
{
  curDiv='#' + inlineRangeNavUrls[i][1];
  if ($(curDiv).length)
  {
    (function(curTab)
    {
      $(curDiv).bind("mouseover", function(){showHideRangeSlidingTabs(curTab, true);} );
      $(curDiv).bind("mouseout", function(){showHideRangeSlidingTabs(curTab, false);} );
    })(inlineRangeNavUrls[i][0]); // pass as argument to anonymous function - this will introduce a new scope
  }
}

Wie Jason vorschlägt, Sie können dies tatsächlich einiges mit JQuery's integriert aufräumen hover() Funktion:

for (var i=0;i<inlineRangeNavUrls.length;i++)
{
  (function(curTab) // introduce a new scope
  {
  $('#' + inlineRangeNavUrls[i][1])
    .hover(
      function(){showHideRangeSlidingTabs(curTab, true);},
      function(){showHideRangeSlidingTabs(curTab, false);} 
    );
  // establish per-loop variable by passsing as argument to anonymous function
  })(inlineRangeNavUrls[i][0]); 
}

Andere Tipps

Was hier vor sich geht, ist, dass Ihre anonmymous Funktionen einen Schluss bilden und ihren äußeren Umfang mit sich nehmen. Das bedeutet, dass, wenn Sie Curtab in Ihrer anomymen Funktion verweisen, wenn der Ereignishandler diese Funktion ausführt, er nachschlagen wird aktuell Wert von Curtab in Ihrem äußeren Bereich. Das wird alles sein, was Sie zuletzt Curtab zugewiesen haben. (Nicht das, was zu dem Zeitpunkt zugewiesen wurde, als Sie die Funktion gebunden haben)

Was Sie tun müssen, ist dies zu ändern:

$(curDiv).bind("mouseover", function(){showHideRangeSlidingTabs(curTab, true);} );

dazu:

$(curDiv).bind("mouseover", 
    (function (mylocalvariable) { 
        return function(){
            showHideRangeSlidingTabs(mylocalvariable, true);
        } 
    })(curTab) 
);

Dies kopiert den Wert von Curtab in den Umfang der äußeren Funktion, die die innere Funktion mit sich bringt. Dieses Kopieren erfolgt gleichzeitig, dass Sie die innere Funktion an den Ereignishandler binden, sodass "myLocalVariable" den Wert von Curtab zu dieser Zeit widerspiegelt. Das nächste Mal in der Schleife wird eine neue äußere Funktion mit einem neuen Bereich erstellt und der nächste Wert von Curtab kopiert in sie.

Shog9s Antwort erreicht im Grunde dasselbe, aber sein Code ist etwas strenger.

Es ist irgendwie kompliziert, aber es macht Sinn, wenn Sie darüber nachdenken. Schließungen sind komisch.

Bearbeiten: oops, vergessen, die innere Funktion zurückzugeben. Fest.

Ich denke, Sie machen das komplizierter, als es sein muss. Wenn Sie nur einen Gleiteffekt auf Mausover/Out zuweisen, versuchen Sie es mit dem schweben Effekt mit JQuery.

$("#mytab").hover(function(){
    $(this).next("div").slideDown("fast");},
  function(){
    $(this).next("div").slideUp("fast");
});

Wenn Sie Ihre volle HTML gepostet haben, könnte ich Ihnen genau sagen, wie es geht :)

Sie können den Wert Ihrer Variablen in ein nicht vorhandenes Tag einfügen und später von dort aus lesen. Dieser Ausschnitt ist Teil eines Schleifenkörpers:

 s = introduction.introductions[page * 6 + i][0]; //The variables content
 $('#intro_img_'+i).attr('tag' , s);              //Store them in a tag named tag
 $('#intro_img_'+i).click( function() {introduction.selectTemplate(this, $(this).attr('tag'));}  );  //retrieve the stored data
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top