Blaubart: Reihenfolge des Event-Bubblings

Tach.

Ich programmiere gerade ein Such-/Logikspiel in Javascript, bei dem der Spieler in einer Sammlung von Truhen bestimmte Gegenstände finden muß. Die Inhalte wechseln in jedem Spielschritt nach einem festen Algorithmus, den es zu erkennen gilt, zwischen den Truhen.

Jede Truhe ist ein eigenständiges Javascript-Objekt, welches auch ein HTMLImageElement enthält, das die Truhe auf dem Bildschirm repräsentiert. Jede Truhe reagiert auf click-Events ihres zugehörigen Bildes. Alle Truhenbilder sind als Elemente einer HTML-Liste zusammengefaßt, die sozusagen das Spielfeld darstellt.

Soviel zur Vorgeschichte ... Mein Problem ist folgendes:

Der Spieler darf immer nur eine begrenzte Anzahl Truhen pro Spielzug öffnen, um sich den Inhalt anzuschauen. Ich hatte mir das so vorgestellt, daß das Spielfeld als eine Art Schiedsrichter überwacht, welche Truhen geöffnet sind und ggf. das Öffnen weiterer Truhen unterbindet. Da die Liste aber das Elternelement der Truhen im Elementbaum darstellt, erreicht der click-Event sie erst, *nachdem* er onclick bei den Truhen getriggert hat. Folgende drei Varianten, dieses Problem in den Griff zu kriegen, habe ich mir überlegt:

1. Jede Truhe überprüft in ihrem onclick-Handler den Zustand eines *globalen* Zählers. D. h. nicht das Spielfeld sondern die einzelnen Truhen fungieren als Schiedsrichter.

2. Nicht die Truhe selber, sondern das Spielfeld reagiert auf die click-Events, die normalerweise die Truhe veranlassen, sich zu öffnen.

3. Den Truhen wird schrittweise die Fähigkeit, auf die Klicks zu reagieren entzogen, indem ihr onclick-Handler überschrieben wird.

Methode 1 wäre die einfachste, die ich aber für ziemlich unsauber halte. Rumgebolze mit globalen Variablen führt auf lange Sicht fast immer zu Problemen. Methode 3 erscheint mir ziemlich umständlich und führt wahrscheinlich auch nicht zu mehr Übersichtlichkeit als Methode 2. Mir wäre es zwar lieber, die Truhen kümmerten sich – wie bisher – *selber* um ihr onclick-Handling, allerdings scheint mir Methode 2 insgesamt das geringste Übel zu sein.

Habt Ihr Alternativen und/oder Anmerkungen zu den obigen 3 Methoden?

--
Once is a mistake, twice is jazz.
  1. Hi

    Da die Liste aber das Elternelement der Truhen im Elementbaum darstellt, erreicht der click-Event sie erst, *nachdem* er onclick bei den Truhen getriggert hat.

    Das ist nur der Fall, wenn die Events "bubbeln", also vom im DOM-Baum tieferen Element zum höheren Element aufsteigen.
    Du kannst die Events auch "capture"n, dass heisst, sie werden zuerst im höheren Element getriggert.
    Am besten erklärt das aber A List apart.

    Vielleicht hilft das weiter.

    Gruss,
    Mathias

    1. Tach.

      Das ist nur der Fall, wenn die Events "bubbeln", also vom im DOM-Baum tieferen Element zum höheren Element aufsteigen.
      Du kannst die Events auch "capture"n, dass heisst, sie werden zuerst im höheren Element getriggert.
      Am besten erklärt das aber A List apart.

      Hmm, das klingt erstmal ganz brauchbar. Allerdings fange ich mir damit bzgl. Browserkompatibilität offenbar mehr Probleme ein als ich löse. Ich werd mich noch ein bißchen damit beschäftigen und schauen, was sich daraus ergibt. Vielen Dank für Deine Hilfe.

      --
      Once is a mistake, twice is jazz.
  2. Hallihallo!

    Habt Ihr Alternativen und/oder Anmerkungen zu den obigen 3 Methoden?

    Methode 4: Jede Truhe fragt den Schiedsrichter, wie sie auf einen Klick reagieren soll.
    Dazu bräuchte man nur eine entsprechende Schiedsrichtermethode, die aufgrund der Anzahl bisher geöffneter Truhen "ok" oder "nein" sagt.

    Viele liebe Grüße,
    Der Dicki

    1. Tach.

      Methode 4: Jede Truhe fragt den Schiedsrichter, wie sie auf einen Klick reagieren soll.
      Dazu bräuchte man nur eine entsprechende Schiedsrichtermethode, die aufgrund der Anzahl bisher geöffneter Truhen "ok" oder "nein" sagt.

      Das ist so etwas, wie ich in Methode 1 beschrieben habe: Die Entscheidung wird nicht gefällt, bevor der Event die Truhe erreicht. Also muß sich die Truhe um die umgebende Spiellogik kümmern, obwohl ich das nach Möglichkeit voneinander trennen möchte.

      --
      Once is a mistake, twice is jazz.
      1. Hallihallo!

        Tach.

        Methode 4: Jede Truhe fragt den Schiedsrichter, wie sie auf einen Klick reagieren soll.
        Dazu bräuchte man nur eine entsprechende Schiedsrichtermethode, die aufgrund der Anzahl bisher geöffneter Truhen "ok" oder "nein" sagt.

        Das ist so etwas, wie ich in Methode 1 beschrieben habe: Die Entscheidung wird nicht gefällt, bevor der Event die Truhe erreicht. Also muß sich die Truhe um die umgebende Spiellogik kümmern, obwohl ich das nach Möglichkeit voneinander trennen möchte.

        Wobei Du hierbei aber keinerlei globale Variablen bräuchtest, die Du ja zu recht vermeiden möchtest.
        Vielleicht reden wir ja auch aneinander vorbei. Was ich meinte, ist Folgendes:

        • Truhe wird geklickt.
        • Truhe: "Verdammt, ich wurde geklickt! Was muss ich´n da machen? Am besten mal nachfragen...
                       He, Spielfeld! Wie sieht´s aus? Darf ich mich öffnen lassen, oder lieber nicht?"
        • Spielfeld: "Hmm, mal überlegen. Also im Moment hab ich hier 3 offene Truhen rumliegen. Warte mal eben...."
        • Spielfeld tut irgendwas hochwichtiges, was die Regeln so vorschreiben (z.B. andere Truhen schliessen, oder was auch immer)
        • Spielfeld an Truhe: "Jupp, jetzt kannste! Aber bau keinen Mist, ich hab Dich gespeichert!" oder eben "Neeeee Du, lass mal. Noch ´ne offene Truhe mehr kann ich echt nicht gebrauchen."
        • Truhe öffnet sich, oder eben nicht. Was die anderen Truhen machen, interessiert sie nicht. Darum kümmert sich das Spielfeld.

        So zumindest würde ich es machen. Globale Variablen bräuchte es dafür nicht...

        Falls das unsauber ist, soll mich bitte Irgendwer zurechtweisen, denn so in der Art gehe ich in anderen Fällen auch vor...

        Viele liebe Grüße,
        Der Dicki

        1. Tach.

          Vielleicht reden wir ja auch aneinander vorbei. Was ich meinte, ist Folgendes:

          Ich habe schon verstanden, was du meinst.

          • Truhe: "Verdammt, ich wurde geklickt! Was muss ich´n da machen? Am besten mal nachfragen...
                         He, Spielfeld! Wie sieht´s aus? Darf ich mich öffnen lassen, oder lieber nicht?"

          Siehst du es nicht selber? Die Initiative geht von der Truhe aus. Sie greift also entweder über eine globale Variable auf das Spielfeld zu oder muß anderweitig von dessen Existenz wissen – den Truhen das Spielfeld als feste Objekteigenschaft bekannt zu machen, um globale Variablen zu vermeiden, läuft für mich auf's gleiche hinaus. Die Truhe soll sich um die Spielregeln aber gar nicht kümmern müssen! Statt dessen soll sie nur dann reagieren, wenn die höhere Instanz tatsächlich Aufgaben an sie weiterleitet – daher ja auch meine Wahl der Überschrift für diesen Thread.

          Der Unterschied ist der gleiche wie bei einem Angestellten, der

          A) *alle* eingehenden Aufträge entgegennimmt und bei jedem seinen Chef fragt, ob er ihn tatsächlich bearbeiten soll

          oder

          B) nur die Aufträge bekommt, die sein Chef aus der Flut aller eingehenden Aufträge für ihn herausgesammelt hat.

          Nams Hinweis auf bubble vs. capture trifft es ja genau. Nun muß ich bloß mal sehen, ob sich das möglichst browserübergreifend umsetzen läßt. Momentan sieht's nicht so aus, also wird es wohl eh ein Kompromiß zwischen "so hätte ich es gerne von der Struktur her" und "so funktioniert es bei möglichst vielen Leuten".

          --
          Once is a mistake, twice is jazz.