Bearbeitung des Wiki: Playlist
bearbeitet von
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:
~~~js
with (obj)
{
a = b;
}
~~~
lässt sich je nach Definiertheit von obj, obj.a und obj.b als eins von 4 Statements deuten:
~~~js
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.
~~~js
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:
~~~js
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.
_Rolf_
--
sumpsi - posui - obstruxi
Bearbeitung des Wiki: Playlist
bearbeitet von
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.
Wenn Du dann 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:
~~~js
with (obj)
{
a = b;
}
~~~
lässt sich je nach Definiertheit von obj, obj.a und obj.b als eins von 4 Statements deuten:
~~~js
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.
~~~js
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:
~~~js
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.
_Rolf_
--
sumpsi - posui - obstruxi