Orlok: Quiz - Event-Handler dynamisch anbinden

Beitrag lesen

problematische Seite

Hallo Matthias

ich dilettiere so vor mich hin und stoße bei der Umstrukturierung meiner unorganisierten Scripte auf immer mehr Fragen:

beispiel.html

Z.20: Ist das quiz-Object so logisch?

var quiz = new Object();
    quiz.question   = 'Was ist die Hauptstadt von Deutschland?';
    quiz.solution   = 'Berlin';
    quiz.options    = ['Berlin', 'Hamburg', 'München', 'Hannover'];

Ich kann hier keinen logischen Widerspruch erkennen, aber …

  • … warum rückst du hier die Anweisungen unterhalb der Variablendeklaration ein?

  • Wenn du eine Funktion mittels new als Konstruktor aufrufst, ohne dabei Argumente zu übergeben, dann kannst du dir die runden Klammern nach deren Bezeichner sparen, denn der Aufruf ist bereits Teil der Semantik des Operators new.

  • Andererseits wäre es wohl ohnehin besser, das Objekt in Literalschreibweise zu erstellen, so wie du es mit dem Array für die options ja auch gemacht hast, und nicht durch Aufruf des Konstruktors.

z.52: Ich würde gerne den neu erzeugten Elementen eine Klasse oder einen Event-Handler geben. Wie geht das?

	for (index = 0; index < quiz.options.length; index++) {
	    text = quiz.options[index];
		newElement = addAChild('a', text);
		//newElement.className = "foo";
	}

Ich hatte dafür das a-Element gewählt, da ich dachte, dass man es dann auch durchtabben kann. Dafür benötigt es aber wohl noch ein href="#", oder?

Wie kann ich hier eine Klickfunktionalität erreichen? Wenn ich die Variable newElement noch einmal verwende, bricht die Schleife ab.

Zunächst einmal bin ich mir ziemlich sicher, dass du hier keine Links willst, sondern Buttons vom Typ button. Die sich übrigens auch prima durchtabben lassen.

Der Grund, warum dein Programm an dieser Stelle abschmiert, ist in der Funktion addAChild zu suchen, deren Rückgabewert du der Variable newElement zuweist. Da du für diese Funktion keinen Rückgabewert bestimmt hast, wird standardmäßig undefined zurückgegeben, und der Versuch, diesem primitiven Wert eine Eigenschaft zuzuweisen, ergibt dann zwangsläufig einen Type Error.

Auch der Versuch, die Funktion an den #quiz-Container anzuhängen und dann mit Event.target das geklickte Element zu identifizieren geht so nicht:

  //...
  var element = document.getElementById('quiz');
  element.addEventListener('click',function(){clickHandler(event);});
}

function clickHandler(event) {
  var target = event.target;
  console.log(target);   
}

Um den Event mit target zu identifizieren, benötige ich doch das Event, oder? Wie kann ich das übergeben?

Du hast als Event-Handler eine anonyme Funktion registriert, für die du keinen Parameter bestimmt hast. Innerhalb des Handlers rufst du dann eine Funktion mit dem Argument event auf, aber wo soll das herkommen? Das ergibt natürlich einen Reference Error, da event nicht definiert ist.

Du solltest also für die als Handler registrierte Funktion einen Parameter deklarieren:

element.addEventListener('click', function (event) {
  clickHandler(event);
});

Wobei ein solches Konstrukt ohnehin recht wenig sinnhaft ist. Warum registrierst du clickHandler nicht gleich als Event-Listener? – Oder verwendest die registrierte anonyme Funktion?

Viele Grüße,

Orlok