Linuchs: Javascript-Fehler bei Arrays vereinen (concat)

problematische Seite

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

  1. problematische Seite

    sorry - habe weitere Versuche unternommen und damit den Fehler nicht nachvollziehbar gemacht. Ursprüngliche, fehlerhafte Version wiederhergestellt

    1. problematische Seite

      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

  2. problematische Seite

    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

    --
    Nein, Esel sind nicht störrisch. Sie wissen es einfach nur besser.
    1. problematische Seite

      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

      --
      sumpsi - posui - obstruxi
      1. problematische Seite

        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

        1. problematische Seite

          Hallo Linuchs,

          ja, mein Vorschlag war Mist. Und die Lösung ist auch zu kompliziert.

          Viel eleganter ist document.querySelectorAll("audio, video").

          Rolf

          --
          sumpsi - posui - obstruxi
    2. problematische Seite

      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?

      1. problematische Seite

        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

        --
        sumpsi - posui - obstruxi
  3. problematische Seite

    @@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?

    🖖 Живіть довго і процвітайте

    --
    When the power of love overcomes the love of power the world will know peace.
    — Jimi Hendrix
    1. problematische Seite

      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" );