Hallo Linuchs,
wenn Du mit dem revealing module Pattern arbeitest, stellst Du im Prinzip ein Objekt bereit, dessen Implementierung auf Interna des Moduls zugreifen kann. Diese Interna sind letztlich in der Closure gespeichert, die zu dem Funktionskontext gehört, der das Objekt erzeugt hat, und damit gut versteckt.
Dieses Objekt kann ein normales Objekt mit Methoden sein. Oder auch eine Funktion - siehe dazu weiter unten.
Wenn Du Methoden dieses Objekts verwenden willst, musst Du natürlich immer obj.method() schreiben. Ist lästig, aber:
Vergiss with
Douglas Crockford teilt JavaScript im Schmetterlingsbuch (JavaScript: The Good Parts) in 3 Teile: Awful, Bad und Good. with
ist bad. Der Grund:
with (obj)
{
a = b;
}
lässt sich je nach Definiertheit von obj, obj.a und obj.b als eins von 4 Statements deuten:
a = b;
a = obj.b;
obj.a = b;
obj.a = obj.b;
JS weiß erst, wenn es an dieser Stelle angekommen ist und getestet hat, ob obj, obj.a oder obj.b undefined
sind, was es zu tun hat. Und das ist die Hölle für jeden Optimizer. Der strict mode verbietet es deshalb. Die Bequemlichkeit und Reduktion in Scriptgröße, die with
mitbringt, rechtfertigt den negativen Einfluss auf die Eindeutigkeit der Ausführung nicht.
var plA = { ... }
Kann man machen, aber innerhalb von playThis solltest Du this
statt plA verwenden. Dann KÖNNTEST Du die playThis-Funktion in einer Variablen ablegen und jedem plA Objekt als playThis zuweisen.
Wieso werden die li-Elemente nicht erkannt?
Weil li kein Klassenname ist und Du getElementsByClassName verwendest.
Aber wie wär's hiermit - revealing module, das eine Funktion bereitstellt:
function getNextSongPlayer(id) {
const playList = document.getElementById(id);
const obj_audio = playList.querySelector("audio");
const songs = playList.querySelector("li");
return function(ndx) {
obj_audio.src = songs[ndx].dataset.url;
arr_li[ndx].style.fontWeight = "bold";
return obj_audio.play();
}
}
playA = getNextSongPlayer("plA");
playB = getNextSongPlayer("plB");
playA(0); // Spiele erstes Lied in Playlist A
playB(0); // Spiele erstes Lied in Playlist B
Die Funktion, die aus getNextSongPlayer herauskommt, gibt das Promise zurück, das von play() geliefert wird. Du kannst also auf den Rückgabewert von playA oder playB mit .then und .catch reagieren, oder - in einer async-Funktion - mit await darauf warten.
Diese Technik setzt auf Closures - wie das funktioniert, steht z.B. hier
Rolf
sumpsi - posui - obstruxi