Rolf B: Variablen angeblich in function nicht bekannt

Beitrag lesen

Hallo Linuchs,

Was mache ich falsch?

Eine Menge. Zunächst ein Tipp, der nicht direkt in Bezug zur Meldung steht.

arr_li[nr].getAttribute("data-gruppe")
arr_li[nr].getAttribute("data-src")
arr_li[nr].dataset.gruppe
arr_li[nr].dataset.src

Data-Attribute spricht man über die dataset Eigenschaft an. Der einzige Browser, der dataset nicht kennt, ist der Internet Explorer vor Version 11, und das ist komplett irrelevant.

Zur eigentlichen Frage. Dies ist definitiv falsch:

obj_audio.addEventListener('ended', playTitel( lfd_nr +1 ) );

So, wie ich das sehe, ist playTitel der Eventhandler, und nicht eine Funktion, die einen Eventhandler zurückgibt. Deswegen darfst Du an der Stelle, wo der Eventhandler erwartet wird, nicht einfach die Funktion aufrufen. Das würde nur einmal passieren, bei der Registrierung. Aber du möchtest, dass es beim Auslösen des Events passiert.

Ich nehme an, du möchtest bei Eintreten eines ended Events die lfd_nr um 1 erhöhen und sie, wenn sie zu groß wird, auf den Anfang zurücksetzen. Und dann soll der Audiotrack mit der aktuellen lfd_nr gestartet werden.

Problem 1: Array-Indexe sind 0-basierend, aber deine lfd_nr ist 1-basierend. Korrekt wäre, lfd_nr auf 0 zu initialisieren, bei Überlauf auf 0 zurückzusetzen und zur Abfrage des Überlaufs lfd_nr >= arr_li.length zu testen.

Da lfd_nr ohnehin eine globale Variable ist, brauchst Du die auch nicht als Parameter für playTitel. Mach's einfach global.

Zum Start des ersten Liedes wirst Du playTitel eigenständig aufrufen müssen, nicht als Eventhandler, deswegen ist es sinnvoll, wenn playTitel einfach nur das Lied mit der Nummer N startet und sich nicht um die Umlaufsteuerung kümmert. Dafür mach eine zweite Funktion, und lass die den Eventhandler sein.

Das Audio-Element ermittelst Du eleganter über querySelector. Dumme Frage: Ist das Element mit der id player und das audio-Element identisch? Dementsprechend die Frage unten im Code.

Das ganze hab ich noch in eine Funktion gesteckt, damit die globalen Variablen nicht zu global sein müssen. Die darfst Du allerdings nur genau einmal aufrufen, sonst hast Du zwei Eventhandler. Wenn Du sowas wie stopAudioLoop oder resetAudioLoop willst, musst Du das anders strukturieren (z.B. mit Hilfe des revealing module pattern.

function startAudioLoop()
{
  // das Audio-Element
  const obj_audio = document.querySelector("audio");
  // Array der li Elemente (Titel)
  const arr_li = document.querySelectorAll("li");
  // Ausgabeelement für Liedtitel
  const lied_titel = document.getElementById( "lied_titel" );
  // nr des ausgewaehlten li - Elements
  let   lfd_nr = 0;
  
  function playTitel(nr) {
    // Titel und Kuenstler anzeigen
    lied_titel.innerHTML = arr_li[nr].innerHTML +
                           "   " +
                           arr_li[nr].dataset.gruppe;
    // source in den Player
    obj_audio.src        = arr_li[nr].dataset.src
    document.getElementById( "player" ).play();
    // Frage: warum nicht
    obj_audio.play();
  }

  obj_audio.addEventListener("ended", function() {
     lfd_nr = lfd_nr + 1;
     if (lfd_nr >= arr_li.length)
        lfd_nr = 0;
     playTitel(lfd_nr);
  });

  playAudio(0);
}

Das ist jetzt ungetestet ins Forum gecoded und geht möglicherweise irgendwo kaputt. Good Luck.

Rolf

--
sumpsi - posui - obstruxi