Javascript-Fehler bei Arrays vereinen (concat)
Linuchs
- javascript
Moin,
ich möchte alle audio- und video-Objekte eines Dukuments auf halbe Lautstärke setzen und anschließend Eventlistener pro Objekt zuordnen.
Bei mozilla habe ich concat() gefunden und wende das an:
var av_objects = document.getElementsByTagName( "audio" ).concat(document.getElementsByTagName( "video" ));
Fehlermeldung im FF 101.0.1:
Uncaught TypeError: document.getElementsByTagName(...).concat is not a function
Was habe ich falsch gemacht oder falsch verstanden?
Fragt Linuchs
sorry - habe weitere Versuche unternommen und damit den Fehler nicht nachvollziehbar gemacht. Ursprüngliche, fehlerhafte Version wiederhergestellt
Local habe ich testweise nur die audio-Elemente genommen, das wird nicht moniert.
Dann kommt aber der Folgefehler
Uncaught (in promise) DOMException: The fetching process for the media resource was aborted by the user agent at the user's request.
beim Start eines audios
Hallo,
Bei mozilla habe ich concat() gefunden und wende das an:
var av_objects = document.getElementsByTagName( "audio" ).concat(document.getElementsByTagName( "video" ));
Fehlermeldung im FF 101.0.1:
Uncaught TypeError: document.getElementsByTagName(...).concat is not a function
Was habe ich falsch gemacht oder falsch verstanden?
du glaubst, getElementsByTagName() liefere ein Array, und das ist ein Irrtum. Es liefert eine Node List. Die hat zwar einige Merkmale eines Arrays, zum Beispiel dass man mit einem Index auf die einzelnen Elemente zugreifen kann. Aber es ist halt kein echtes Array, und deshalb gibt es da auch kein concat().
Schade eigentlich, die Idee war ja ansonsten gut.
Einen schönen Tag noch
Martin
Hallo Martin,
es ist aber ein arrayoides Objekt und lässt sich deshalb per .call als this einsteuern und sollte auch als Argument anwendbar sein. Nötig ist lediglich eine length-Eigenschaft und ein Elementzugriff über einen Indexer (also die x[i] Schreibweise).
let resultList = Array.prototype.concat.call(nodelist1, nodelist2);
// oder
let resultList = [].concat.call(nodelist1, nodelist2);
Lösung 2 ist kompakter, muss aber ein Dummy-Array erzeugen und treibt damit unnötigen Overhead.
Ich habe es jetzt aus Zeitmangel nicht ausprobieren können; es müsste aber funktionieren.
Edith sagt: Funktioniert NICHT. Das Ergebnis ist ein Array, das die beiden Nodelisten enthält.
Rolf
Hallo Rolf,
danke, das funktioniert zunächst:
const av_objects = Array.prototype.concat.call(document.getElementsByTagName( "audio" ), document.getElementsByTagName( "video" ));
Dann platzt aber diese Zeile
av_objects[i].addEventListener( "play", function() { ... }
mit dem Fehler
Uncaught TypeError: av_objects[i].addEventListener is not a function
Hallo Linuchs,
ja, mein Vorschlag war Mist. Und die Lösung ist auch zu kompliziert.
Viel eleganter ist document.querySelectorAll("audio, video").
Rolf
Okay, ich kann also eine Nodeliste für alle audios und eine andere für alle videos bekommen.
Die weitere Behandlung der audio- und video-Elemente ist aber gleich. Wie kann ich die Nodelisten vereinen?
Hallo Linuchs,
du kannst den von mir genannten concat.call() verwenden oder die eigentliche Arbeit in eine Funktion auslagern, die Du erst mit den Videos und dann mit den Audios aufrufst.
Rolf
@@Linuchs
ich möchte alle audio- und video-Objekte eines Dukuments
Das ist wohl der relevante Teil.
auf halbe Lautstärke setzen und anschließend Eventlistener pro Objekt zuordnen.
Und das der irrelevante.
var av_objects = document.getElementsByTagName( "audio" ).concat(document.getElementsByTagName( "video" ));
Du möchtest alle audio
- und video
-Elemente selektieren.
Wie ich unlängst schrieb, gibt zum Selektieren eines Elements die Methode querySelector(selector)
, wobei selector
ein Selektor ist, wie man ihn aus CSS kennt.
Zum Selektieren mehrerer Elemente gibt es querySelectorAll(selector)
. Den Selektor für alle Elemente der Typen audio
und video
kriegst du selber hin?
🖖 Живіть довго і процвітайте
wobei selector ein Selektor ist, wie man ihn aus CSS kennt.
Naja, in CSS steht er nicht zwischen Gänsefüßen. Aber danke, das war der entscheidende Hinweis.
const av_objects = document.querySelectorAll( "audio, video" );