Cruz: Referenz auf function mit Parameterübergabe

Hallo Leute,

ich stehe hier vor einem kleinem JavaScript Problem, ich hoffe jemand hat eine Idee.

Ich habe ein recht komplexes JS geschrieben für die dynamische Füllung von Dropdowns. Beispiel: Der User wählt im ersten Dropdown die Option "Länder" aus, daraufhin wird der zweite Dropdown mit Ländern gefüllt. Hätte er die Option "Städte" ausgewählt, wäre der zweite Dropdown mit Städten gefüllt worden. Es gibt aber nicht nur 2, sondern eine recht große Baumstruktur von Dropdowns.

Ich habe eine Funktion fillCombos(), die onChange ausgeführt wird, sobald sich bei einem Dropdown etwas tut. Diese fillCombos() Funktion muss wissen welches Dropdown genau angefasst wurde, damit die Funktion die dazu passenden Dropdowns neu füllen kann. Und genau darin liegt mein Problem. Wie weiss meine fillCombos() Methode von welchem Dropdown aus er onChange aufgerufen wurde.

Ich hätte natürlich die Möglichkeit in jedem Dropdown im HTML Code den onChange zu deklarieren und eine Referenz auf den aufrufenden Dropdown zu übergeben:

<select name="Hase" onChange="fillCombos(this)">

Das würde allerdings die Usability von meinem JS einschränken. Ich möchte einem HTML Programmierer, der mein JS einbindet dies abnehmen, damit er nicht überall den onChange deklarieren muss.

Das ist im Grunde auch kein Problem, ich habe es folgendermaßen in JS realisiert:

form.elements[comboName].onchange = fillCombos;

Dies wird an einer passenden Stelle in meinem JS eingebunden und damit deklariere ich den onChange="fillCombos()" für den HTML Programmierer. Wie man sieht belege ich das onchange Attribut mit einer Referenz zur fillCombos() Funktion. Was jetzt fehlt ist die Übergabe einer Referenz zur aufrufenden Dropdown.

Im Firefox ist das kein Problem. Ich deklariere die fillCombos() Funktion so:

function fillCombos(event)
{
   ...
}

und dann stehen im event Parameter Informationen über das aufrufende Form Element und darüber finde ich den Dropdown. Im IE passiert aber nichtsdergleichen und da muss es leider auch funktionieren.

Ich würde ja gerne soetwas machen:

form.elements[comboName].onchange = fillCombos(comboName);

Also eine Referenz zu einem Funktionsaufruf, der auch gleich einen festgelegten Parameter mit übergibt. Aber so funktioniert es leider nicht, denn das wird keine Referenz zur Funktion, sondern der Rückgabewert der Funktion die in diesem Augenblick auch ausgeführt wird.

Also wie kann ich denn soetwas machen? Eine Referenz zu einer Funktion mit festgelegtem Parameter.

Oder hat jemand noch eine andere Idee, wie ich den aufrufenden Dropdown herausfinden kann,ohne dass ich manuell im HTML jedes onChange deklarieren muss?

Es ist dafür gesorgt, dass jedes Dropdown einen eindeutigen Namen hat, also brauche ich nicht unbedingt gleich eine Refernz zum Form Element. Der Name als String würde völlig aussreichen.

Viele Grüße,
Cruz

  1. Hallihallo!

    Eine einfache und direkte Lösung zu Deinem Problem fällt mir leider nicht ein, aber vielleicht hilft Dir ein kleiner Umweg ja weiter:

    Rufe doch einfach über Deinen zentral definierten eventhandler "onChange" eine Funktion auf, die die aktuellen Zustände aller Deiner "Combos" mit den vorherigen vergleicht. Diejenige "Combo", die einen anderen Wert hat als vorher, muss logischerweise die sein, die das event ausgelöst hat.

    Du müsstest also zwei zusätzliche Funktionen bauen:

    1. eine "init()" (ich nenn sie einfach mal so), die die "Startpositionen" aller "Combos" ausliest und einen Array (ich nenne ihn mal "statusvorher") damit füttert.
    2. eine "vergleicheCombos()", die die Statusse [1] aller "Combos" mit den im Array "statusvorher" gespeicherten vergleicht. Diese Funktion wäre dann die, die per onChange aufgerufen würde. Sie findet also durch simplen Vergleich der Statusse [1] den Urheber des onChange- events heraus, ändert schnell das statusvorher- Array, und ruft ihrerseits dann die FillCombos() mit den passenden Parametern auf.

    So, nun hoffe ich drei Dinge:

    1. meine wirren Gedankengänge sind verständlich rübergekommen
    2. meine wirren Gedankengänge funktionieren
    3. meine wirren Gedankengänge konnten Dir resultierend aus 1) und 2) helfen

    Viele liebe Grüße, und weiterhin eine gute Nacht,
    Der Dicki

    [1] Nein, dies ist kein Rechtschreibfehler im Wort "Star- Tusse" oder so... Eher eine Rache an Allen, die mich täglich mit Wörtern wie "Globusse", "Atlasse", "Pizzas" etc. quälen. (Auch, wenn Einige davon tatsächlich erlaubt sind *schauder*)

    1. Hallo Dicki,

      nun es hat sich inzwischen eine einfache und elegante Lösung gefunden. Trotzdem will ich mich für deine Idee bedanken, denn dein Lösungsvorschlag hätte sicherlich funktioniert und außerdem finde ich, dass bei so einer Art "Brainstorming" auch die nicht verwendeten Ideen sinnvolle Beiträge sind.

      Viele Grüße,
      Cruz

  2. hi,

    form.elements[comboName].onchange = fillCombos;

    wenn du jetzt in fillCombos auf this zugreifst, enthält dieses eine referenz auf form.elements[comboName], als das select-element, aus welchem heraus die funktion aufgerufen wurde.

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
    1. Hallo wahsaga,

      ja das ist tatsächlich wahr, vielen Dank! Eine einfache Lösung ist immer die beste. :)

      Ich verstehe zwar nicht warum this innerhalb der Funktion auf das select-Element zeigt und nicht z.B. auf die Funktion selbst, aber ausnutzen tu ich das schon gerne. :)

      Danke,
      Cruz

      hi,

      form.elements[comboName].onchange = fillCombos;

      wenn du jetzt in fillCombos auf this zugreifst, enthält dieses eine referenz auf form.elements[comboName], als das select-element, aus welchem heraus die funktion aufgerufen wurde.

      gruß,
      wahsaga

      1. hi,

        Ich verstehe zwar nicht warum this innerhalb der Funktion auf das select-Element zeigt und nicht z.B. auf die Funktion selbst

        eben _weil_ du dem eventhandler die funktionsreferenz zugewiesen hast.

        bei
        element.on{event xy} = funktionsreferenz;
        referenziert this innerhalb der funktion auf das über den eventhandler aufrufende objekt;

        bei
        <element on{event xy}="funtkionsaufruf();" ...>
        hingegen würde this innerhalb der funktion auf die funktion selber referenzieren.

        gruß,
        wahsaga

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }
      2. Ich verstehe zwar nicht warum this innerhalb der Funktion auf das select-Element zeigt und nicht z.B. auf die Funktion selbst, aber ausnutzen tu ich das schon gerne. :)

        this zeigt immer auf das aktuelle Element.

        funtion test()
        {
        // hier ist this == window
        }

        Da test() im aktuellen Element window aufegrufen wird, also ist

        window.test() == test()

        entspricht also:
        window.test = function()
        {
        }

        Wenn du eine Eventfunktion anlegst:

        objekt.test = function()
        {
        // hier ist this == objekt
        }

        Struppi.