In welcher Reihenfolge werden DOMContentLoaded abgearbeitet?
Linuchs
- html
- javascript
Moin,
für Liedtexte mit Audio- und Videospuren lade ich mehrere .js Dateien
<script src="../css/formatiert_a3_a5_a6.js"></script><!-- *.htm?a6 -->
<script src="../css/setze_seitenzahlen.js"></script><!-- *.htm?a6Nr.04 -->
<script src="../css/lied_mehrspurig.js"></script>
<script src="../css/tempo_handler.js"></script>
<script src="../css/setze_akkorde.js"></script>
und jede enthält
window.addEventListener('DOMContentLoaded', function () {
...
}
Wenn die Akkorde gesetzt werden, wird in lied_mehrspurig die Lautstärke NICHT verringert.
Da ich keine Idee habe, ob diese Funktionen nacheinander oder zeitgleich abgearbeitet werden, weiß ich nicht, nach welcher Art Fehler ich suchen muss.
Javascript meldet keine Fehler, aber macht es einfach nicht
// alle Audios auf halbe Lautstaerke
for ( let i=0; i<document.querySelectorAll( "audio" ).length; i++ ) document.querySelectorAll( "audio" )[i].volume = 0.2;
Habe den Dateien-Mix auf den Server geladen, damit ihr inspizieren könnt.
Vom Server geholt, wird jetzt (bei mir) die Tonart (C ist Standard) nicht gesetzt, das Ergebnis sieht so aus:
To|nika Do|minante Su|bdominante sollte so aussehen:
Gruß, Linuchs
Moin Linuchs,
window.addEventListener('DOMContentLoaded', function () { ... }
funktioniert das denn überhaupt oder muss es eher
document.addEventListener('DOMContentLoaded', function () {
…
}
sein?
Viele Grüße
Robert
Hallo Robert,
habe window. ersetzt durch document. beim DOMContentLoaded.
Jetzt ist es umgekehrt, die Akkorde werden gesetzt, aber volume nicht verringert.
Ist das ZUfall? Je nachdem, welche js-Datei zuerst fertig geladen ist?
Gruß, Linuchs
P.S. Ist window bei selfHTML auf dieser Seite richtig?
Hallo Linuchs,
ja, das Window-Objekt feuert ein load-Event und das Dokument ein DOMContentLoaded Event. Doof, aber wahr.
Ist (die Reihenfolge) Zufall? Je nachdem, welche js-Datei zuerst fertig geladen ist?
Jein. Falls Du deine Scripte asynchron laden würdest, dann ja.
Ein script-Element, dass weder async noch defer noch type="module" hat, hält die DOM-Erzeugung an (ggf. sogar den HTML Parser, meine ich). Der Browser lädt das Script, führt es aus und DANN geht die DOM-Erzeugung weiter.
D.h. 5 Scripte bewirken:
Heißt: Die DOMContentLoaded-Handler werden in der Reihenfolge der Script-Einbindungen registriert und auch in dieser Reihenfolge verarbeitet. Wenn Du das bezweifelst, bau in jeden Handler ein console.log("DOMContentLoaded von script ... wird ausgeführt"); ein.
FALLS deine Scripte nichts weiter tun, als DOMContentLoaded-Handler zu registrieren - oder die Dinge, die sie außerdem tun, auch genauso gut im DOMContentLoaded-Handler stehen könnten. dann würde ich Dir empfehlen, auf DOMContentLoaded zu verzichten und den Script-Elementen statt dessen das Attribut defer zu geben. Das defer-Attribut wird hinreichend gut unterstützt. Mit defer angeforderte Scripte werden asynchron, also parallel zum DOM-Aufbau, geladen und nach Fertigstellung des DOM und nach Fertigladen der Stylesheets in der Reihenfolge der Anforderung ausgeführt. Wenn sie fertig sind, dann feuert DOMContentLoaded.
Zu beachten ist dabei, dass DOMContentLoaded normalerweise nicht darauf wartet, dass die Stylesheets alle geladen sind. Aber DOMContentLoaded wartet auf defer-Scripte, und defer-Scripte warten darauf, dass die Stylesheets da sind. D.h. ein einziges defer-Script kann dazu führen, dass DOMContentLoaded auf das Fertigladen der Stylesheets wartet. Ob das ein Problem ist oder nicht, musst Du entscheiden.
Noch besser wäre zweifellos, die Scripte mit type="module" zu laden (das impliziert defer), aber damit werden sie zu ECMAScript-Modulen mit allen Konsequenzen (sie laufen im strict mode und alles, was nicht exportiert wird, ist nur im Modul zugänglich). Ob das für deine Scripte taugt, musst Du für Dich entscheiden.
Rolf
Hallo Rolf,
danke dir für den „Blick hinter die Kulissen“.
Gruß, Linuchs
Liebe Linuchs,
in Deinem Code lese ich Unsinn.
// alle Audios auf halbe Lautstaerke for ( let i=0; i<document.querySelectorAll( "audio" ).length; i++ ) document.querySelectorAll( "audio" )[i].volume = 0.2;
Warum bildest Du zwei unterschiedliche Ergebnismengen, anstatt mit nur einer zu arbeiten? Unterschiedlich soll heißen, dass die Arrays nicht ein und das selbe Objekt sind, auch wenn ihre Inhalte (vielleicht!) identisch sind. Also schreibe das in Zukunft so:
document.querySelectorAll("audio").forEach(function (audio) {
audio.volume = 0.2;
});
Mit Pfeilfunktionen schreibt sich das noch besser:
document.querySelectorAll("audio").forEach(audio => audio.volume = 0.2);
Vom Server geholt, wird jetzt (bei mir) die Tonart (C ist Standard) nicht gesetzt, das Ergebnis sieht so aus:
Keine Ahnung, was da genau nicht tut. Aber das verwendete DOM ist in meinen Augen nicht sinnvoll gewählt. Du willst Akkordsymbole anzeigen, die je nach Tonart dynamischen Inhalt bekommen. Dazu verwendest Du ein solches Markup:
<div class=text style="font-size:180%;line-height:160%">
<!-- (To)nika (Do)minante (Su)bdominante (Su7)-->
<p class="akkorde"><l>1</l>
Wa-(To)rum bist du gekommen, wenn (Do)du schon wieder gehst? <br>
Du hast mein Herz genommen und (To)wirfst es wieder weg!<br>
|: Ich (Su)bin kein Bajazzo, bin (To)auch ein Mensch wie du <br>
und (Do)leise schlägt mein Herz dir (To)zu. :|</p>
Der Validator ist jedenfalls überhaupt nicht zufrieden. Das solltest Du unbedingt in Ordnung bringen, bevor Du weiter nach Fehlfunktionen suchst!
Meiner Ansicht nach sollte das Markup eher so sein:
<ul class="lyrics">
<li>
<div>
Wa-<span class="to"></span>rum bist du gekommen, wenn
<span class="do"></span>du schon wieder gehst?
</div>
<div>
Du hast mein Herz genommen und
<span class="to"></span>wirfst es wieder weg!
</div>
...
</li>
</ul>
Die Klasse lyrics
beschreibt, dass es sich um einen Liedtext handelt. Die Liste beschreibt die Strophen und ihre Reihenfolge. In CSS kann man also .lyrics li
als Selektor für eine Strophe verwenden.
Die jeweilige Liedzeile soll als Block-Element dargestellt werden, weil Du an ihrem Ende einen Zeilenumbruch notierst. Das kannst Du auch mit einem passenden Kindelement von li
erreichen. Meine Wahl mit einem div
ist vielleicht nicht die beste, aber es ist ein block-level element, das man hier verwenden könnte.
Die eigentlichen Akkordsymbole werden in den leeren span
-Elementen geregelt. Ihr Inhalt soll ja mit JavaScript beschrieben werden, deshalb habe ich sie inhaltsleer notiert. Über ihre Klasse kann man dann den Inhalt hineinschreiben. Der passende Selektor wäre .lyrics .to
für Tonika-Akkorde - der Rest eben analog.
Mit sinnvollerem Markup sollte auch das Hineinschreiben der Akkorde besser gelingen. Wenn es dann noch immer scheitert, obwohl das Markup vom Validator gesegnet wird und die JavaScript-Konsole keine Fehler wirft, dann kann man fragen, ob vielleicht DOMContentLoaded
daran Schuld haben könnte, zu dem @Robert B. korrekt anmerkt, dass man das an das document
-Objekt binden muss.
Liebe Grüße
Felix Riesterer
@@Felix Riesterer
Liebe Linuchs,
Die Auswahl m/w/d überlässt du einer AI?
// alle Audios auf halbe Lautstaerke for ( let i=0; i<document.querySelectorAll( "audio" ).length; i++ ) document.querySelectorAll( "audio" )[i].volume = 0.2;
Warum bildest Du zwei unterschiedliche Ergebnismengen, anstatt mit nur einer zu arbeiten?
Wenn man da schon mit for
-Schleife rumhantieren will (Spoiler: will man nicht), dann so – mit einundderselben Ergebnismenge:
const audios = document.querySelectorAll( "audio" );
for ( let i=0; i<audios.length; i++ ) audios[i].volume = 0.2;
Nach for
eine Anweisung in derselben Zeile zu notieren ist auch eher bäh. Fehleranfällig. Sollte man nicht machen, sondern immer einen {}
-Block verwenden.
Mit Pfeilfunktionen schreibt sich das noch besser:
document.querySelectorAll("audio").forEach(audio => audio.volume = 0.2);
Statt forEach
kann man[1] auch die for … of
-Schleife verwenden:
for (let audio of document.querySelectorAll("audio")) {
audio.volume = 0.2;
}
Bei mir hieße die Variable nicht audio
, sondern audioElement
.
Kwakoni Yiquan
Auf Arbeit beim Tagesspiegel würden da die Alarmglocken des Linters schellen. Da ist for … of
aus irgendeinem Grund verpönt, der sich mir jetzt nicht erschließt. ↩︎
Die Auswahl m/w/d überlässt du einer AI?
Ja klar, soll die doch verzweifeln, wie die Anrede wäre, wenn die audis gemischtgeschlechtlich sind.
Hallo Felix,
habe die Pfeilfunktion eingesetzt, keine Änderung des Verhaltens. Aber was dazugelernt heute.
Deine Vorschläge
Wa-<span class="to"></span>rum bist du gekommen, wenn
<span class="do"></span>du schon wieder gehst?
mögen technisch korrekt sein, aber macht den Quellcode unlesbar. Ich arbeite mit Texteditor.
Statt 4 Zeichen (To) nun deren 24 <span class="to"></span>
Gruß, Linuchs
@@Felix Riesterer
Meiner Ansicht nach sollte das Markup eher so sein:
<ul class="lyrics"> <li> <div> Wa-<span class="to"></span>rum bist du gekommen, wenn <span class="do"></span>du schon wieder gehst? </div> <div> Du hast mein Herz genommen und <span class="to"></span>wirfst es wieder weg! </div> ... </li> </ul>
Meiner Ansicht nicht. Ein Liedtext ist keine Liste.
Und wie würdest du mit Listen-Markup solch ein Lied hinbekommen wollen: 1. Strophe, 2. Strophe, Refrain, 3. Strophe, Refrain, 4. Strophe, Refrain?
IMHO passt für Strophen und Refrains das p
-Element mit br
darin für die Zeilen – so wie ich es habe und wie Linuchs es auch hat.
Noch besser wäre freilich ein natives HTML-Element für Zeilen. Das wurde bei der Entwicklung von HTML5 geflissentlich übersehen – dazu hätte Hixie ja eingestehen müssen, dass es auch Sinnvolles in XHTML2 gab (da war nähmlich ein l
-Element geplant), und das wäre ihm wohl nie über die Lippen gekommen.
Ich verwende deshalb ein custom element x-l
, um die Einrückung hinzubekommen, wenn eine Liedzeile über mehrere Bildschirmzeilen geht.
Und ja, custom elements haben einen -
im Elementtypbezeichner, um sie von HTML-Elementen abzugrenzen. Das von Linuchs verwendete Phantasie-Element l
verhält sich wie ein span
[1] – sollte also keine Gefahr sein. Noch nicht. Das würde sich schlagartig ändern, wenn in HTML doch noch ein l
-Element eingeführt wird.
Dass Linuchs nicht l
verwenden sollte, haben wir schon oft angesprochen. Er bleibt starrköpfig.
Die eigentlichen Akkordsymbole werden in den leeren
span
-Elementen geregelt. […] Mit sinnvollerem Markup sollte auch das Hineinschreiben der Akkorde besser gelingen.
Aber sowas von. Keine Ahnung, was Linuchs da treibt. Nach (To)
, (Do)
, (Su)
suchen und durch Markup für die Akkorde ersetzen?
Wenn man die Elemente schon im Markup hat (ruby
/rt
dürfte sich für Akkorde anbieten), muss nur noch deren Textinhalt ersetzt werden – das sollte einfacher und performanter sein.
Wie sind denn eigentlich die Paralleltonarten benannt?
Wenn ich sowas implementieren würde, würde ich Zahlen verwenden. Ist auch Standard: I
für die Tonika, V
für die Dominante, IV
für die Subdominante. Paralleltonart der Tonika ist VIm
; Paralleltonart der Dominante ist IIIm
.
Die Hälfte aller Lieder geht dann so: I – V – VIm – IIIm – IV – I – IV – V.
Kwakoni Yiquan
In der CSSBattle nutzt man das gnadenlos aus. Eine Lösung für Target 73 (Elephant) war <s><l><o><n><style>* *{margin:var(--m,-70-20);--p:0/50%;--:9q,#0000 42q,#998235}s{--:,#1A4341 0;--m:130}l{--m:31;--:at top,#0B2429 0 11q,#998235 0 21q,#0000 0;--p:0 62q/63q}o{--m:99-1-97;--p:0-60q;--:at bottom,#0000 5ch,#fff 0 63q,#0000}n{padding:68 20;--m:-10 40;--:,#0B2429 0}*{float:left;border-radius:1in;background:var(--p,3vw/47%)radial-gradient(4q var(--,9q,#0B2429 42q,#1A4341)42.7q
.
Fun fact: „slon“ heißt „Elefant“ in so ziemlich allen(?) slawischen Sprachen. ↩︎
Hallo,
// alle Audios auf halbe Lautstaerke for ( let i=0; i<document.querySelectorAll( "audio" ).length; i++ ) document.querySelectorAll( "audio" )[i].volume = 0.2;
Du verwirrst dich, uns und alle anderen Leser deines Codes, wenn Kommentare nicht zum Code passen. Volume 0.2 ist nur dann halbe Lautstärke, wenn es vorher 0.4 war.
Möchtest du durch 2 teilen oder auf 0.2 setzen?
Gruß
Kalk
Hallo kalk,
Volume 0.2 ist nur dann halbe Lautstärke, wenn es vorher 0.4 war.
Die Einen sagen so, die Anderen so. Vor Jahren hatte ich die Information, dass die Lautstärke nicht linear, sondern logarithmisch geregelt wird.
Aber auf Web-Informationen ist überhaupt kein Verlass. Wenn ich von 0.2 auf 1.0 gehe, nehme ich das als Verdoppelung wahr.
Vielleicht kann mal jemand messen, ich habe kein solches Gerät.
Gruß, Linuchs
Moin Linuchs,
Edit: Gunnar war schneller.
Nachdem ich über das DOMContentLoaded
-Event gestolpert bin, ist mir jetzt erst durch Tabellenkals Antwort noch etwas in diesem (langen und daher der Übersichtlichkeit halber umbrochenen) Einzeiler aufgefallen:
// alle Audios auf halbe Lautstaerke for (let i = 0; i < document.querySelectorAll("audio").length; i++) document.querySelectorAll("audio")[i].volume = 0.2;
Neben der Anmerkung von @Tabellenkalk, dass du die Lautstärke absolut auf 0.2
setzt – unabhängig von der vorher tatsächlich verwendeten Lautstärke, ist deine Schleife auch ziemlich ineffizient, weil die Selektoren n mal „gequeryd“ werden. Besser wäre einer der folgenden Ansätze:
const audios = document.querySelectorAll("audio");
// Explizite Schleife:
for (let i = 0; i < audios.length; ++i) {
audios[i].volume = 0.2;
}
// Einzeiler:
audios.forEach((audio) => audio.volume = 0.2);
Viele Grüße
Robert
Moin Robert,
absolut auf 0.2 setzt – unabhängig von der vorher tatsächlich verwendeten Lautstärke
Das läuft nach dem Laden des Dokuments und da sitzt das immer auf 1.0 - oder gibt es versteckte Schrauben, an denen man drehen könnte?
Youtube Videos brüllen mir den ganz Wohnblock zusammen, wenn ich die bösen Cookies gelöscht habe. Ich verlasse den Firefox mehrmals am Tag, wer weiß, was der eingefangene Dreck alles anstellt.
Cookies KRÜMELN überall hin. Sogar bis in die USA.
Gruß, Linuchs
Moin Linuchs,
absolut auf 0.2 setzt – unabhängig von der vorher tatsächlich verwendeten Lautstärke
Das läuft nach dem Laden des Dokuments und da sitzt das immer auf 1.0 - oder gibt es versteckte Schrauben, an denen man drehen könnte?
also die Lautstärkeregelung meines Betriebssystems ist nicht jetzt nicht so versteckt …
Youtube Videos brüllen mir den ganz Wohnblock zusammen, wenn ich die bösen Cookies gelöscht habe. Ich verlasse den Firefox mehrmals am Tag, wer weiß, was der eingefangene Dreck alles anstellt.
Aber zumindest nicht die Lautstärkeeinstellungen des Betriebssystems verändern.
Viele Grüße
Robert
Es gibt zwei Möglichkeiten um Skripte nach und nach zu ausführen zu lassen. Entweder du arbeitest im nächsten Script per EventListener ab ob das vorherige Script geladen wurde oder du machst das Ganze mithilfe von Promises.
Dazu hier ein Beispielscript:
function ladenDesSkripts(url) {
return new Promise((resolve, reject) => {
const skriptElement = document.createElement('script');
skriptElement.src = url;
skriptElement.onload = resolve;
skriptElement.onerror = reject;
document.head.appendChild(skriptElement);
});
}
// Beispiel: Laden des ersten Skripts
ladenDesSkripts('erstesSkript.js')
.then(() => {
console.log('Das erste Skript wurde geladen.');
// Nachdem das erste Skript geladen wurde, lade das nächste Skript
return ladenDesSkripts('zweitesSkript.js');
})
.then(() => {
console.log('Das zweite Skript wurde geladen.');
// Führe hier weitere Aktionen aus oder lade weitere Skripte
})
.catch((fehler) => {
console.error('Ein Fehler ist aufgetreten:', fehler);
});
Hallo Hörnchen,
Welches Problem haben nacheinander notierte Script Elemente, die du mit deinem Beispiel löst?
Rolf
Sorry, ich hab den Text überflogen und diesmal nicht aufgepasst. Das passiert wenn man gerade programmiert auf einem Bildschirm und gleichzeitig Fragen beantworten möchte.