Timo: lastChild zeigt nur #text

Hi, wie der Titel schon sagt:

  
<div>  
<p>  
<input type="file" name="file_ar[]" />  
<button onclick="alert(this.parentNode.lastChild.nodeName);">TEST</button>  
<h5>rgreg</h5>  
</p>  
</div>  

Während das ganze Beispiel mit firstChild problemlos funktioniert:

  
<div>  
<p>  
<input type="file" name="file_ar[]" />  
<button onclick="alert(this.parentNode.firstChild.nodeName);">TEST</button>  
<h5>rgreg</h5>  
</p>  
</div>  

Woran liegts?

Timo

  1. Hi,

    Hi, wie der Titel schon sagt:

    <div>
    <p>
    <input type="file" name="file_ar[]" />
    <button onclick="alert(this.parentNode.lastChild.nodeName);">TEST</button>
    <h5>rgreg</h5>
    </p>
    </div>

      
    Auch Whitespace zwischen Tags stellt Knoten dar - und das wissen auch alle Browser, ausser dem IE.  
      
    
    > Während das ganze Beispiel mit firstChild problemlos funktioniert:  
    >   
    > ~~~javascript
      
    
    > <div>  
    > <p>  
    > <input type="file" name="file_ar[]" />  
    > <button onclick="alert(this.parentNode.firstChild.nodeName);">TEST</button>  
    > <h5>rgreg</h5>  
    > </p>  
    > </div>  
    > 
    
    

    Dürfte es eigentlich nicht, denn auch das fristChild ist im gezeigten Falle ein Textknoten.

    MfG ChrisB

    --
    Light travels faster than sound - that's why most people appear bright until you hear them speak.
    1. Hi,

      Auch Whitespace zwischen Tags stellt Knoten dar - und das wissen auch alle Browser, ausser dem IE.

      anscheinend weiss er es doch, darum habe ich das Problem ja.

      Dürfte es eigentlich nicht, denn auch das fristChild ist im gezeigten Falle ein Textknoten.

      So ist das also, nicht lastChild ist verkehrt sondern firstChild.

      Welcher Sinn steckt dahinter Zeilenumbrüche als Knoten zu erfassen?

      Und wie kann ich dann die Element gezielt ansprechen, also erstes Element, letztes Element?

      Danke
      Timo

      1. Hi,

        Welcher Sinn steckt dahinter Zeilenumbrüche als Knoten zu erfassen?

        Welcher sinn sollte dahinter stecken, es nicht zu tun?
        Wenn's nicht nur ein Zeilenumbruch wäre, sondern ein Buchstabe - dann sollte der sich doch auch im DOM wiederfinden, oder? Wäre doch blöd, sonst könnte man keinen Text auf Webseiten unterbringen ...

        Und wie kann ich dann die Element gezielt ansprechen, also erstes Element, letztes Element?

        Über firstChild und lastChild bekommst du den ersten und letzten Kindknoten.

        Wenn diese gar nicht das sein sollten, was du haben willst - dann wirst du die Frage anders formulieren müssen.

        MfG ChrisB

        --
        Light travels faster than sound - that's why most people appear bright until you hear them speak.
        1. Hi,

          »» Welcher Sinn steckt dahinter Zeilenumbrüche als Knoten zu erfassen?

          Welcher sinn sollte dahinter stecken, es nicht zu tun?
          Wenn's nicht nur ein Zeilenumbruch wäre, sondern ein Buchstabe - dann sollte der sich doch auch im DOM wiederfinden, oder? Wäre doch blöd, sonst könnte man keinen Text auf Webseiten unterbringen ...

          Mir ist noch kein Beispiel untergekommen, wo DOM nicht zur Elementenkontrolle eingesetzt wurden. Daher begreife ich das nicht, ein beispiel wäre nicht schlecht.

          »» Und wie kann ich dann die Element gezielt ansprechen, also erstes Element, letztes Element?

          Über firstChild und lastChild bekommst du den ersten und letzten Kindknoten.

          Wenn diese gar nicht das sein sollten, was du haben willst - dann wirst du die Frage anders formulieren müssen.

          Was soll das denn jetzt? Du weisst doch genau was ich meine. Ausserdem habe ich nun gezielt nach "erstes Element, letztes Element" gefragt. Soll das eine erzieherische Massnahme werden?

          Timo

  2. Und da ist dann noch etwas was mich wundert nachdem ich nun weiss, dass Zeileumbrüche dafür verantwortlich sind.

      
    <div>  
    <p>  
    <button onclick="alert(this.parentNode.lastChild.nodeName);" >TEST</button>  
      
    <h5>rgreg</h5></p></div>  
    
    

    In diesem Beispiel existiert nach dem letzten Knoten(in dem Fall <h5> kein Whitspace/Umbruch mehr, also müsste das doch funktionieren? Tut es aber nicht.

    Entferne ich aber alle Umbrüche erhalte ich "BUTTON", was ja auch falsch ist, oder?

    Timo

    1. Hi,

      jetzt fällt's mir auf, vorher beim drübersehen nicht ...

      <div>

      <p>
      <button onclick="alert(this.parentNode.lastChild.nodeName);" >TEST</button>

      <h5>rgreg</h5></p></div>

      
      >   
      > In diesem Beispiel existiert nach dem letzten Knoten(in dem Fall <h5> kein Whitspace/Umbruch mehr, also müsste das doch funktionieren? Tut es aber nicht.  
      >   
      > Entferne ich aber alle Umbrüche erhalte ich "BUTTON", was ja auch falsch ist, oder?  
        
      Nein, ist es nicht. Da du fehlerhaftes HTML verwendet hast, ist die Fehlerkorrektur des Browsers eingesprungen, und hat den Absatz, der natürlich keine Überschrift enthalten darf, vor dieser beendet.  
        
      MfG ChrisB  
        
      
      -- 
      Light travels faster than sound - that's why most people appear bright until you hear them speak.
      
      1. Hi,

        Nein, ist es nicht. Da du fehlerhaftes HTML verwendet hast, ist die Fehlerkorrektur des Browsers eingesprungen, und hat den Absatz, der natürlich keine Überschrift enthalten darf, vor dieser beendet.

        autsch, klar stimmt ja. Aber wie ich nun an das erste und letzte Element innerhalb <p> kommen soll, ohne die \r\n zu entfernen weiss ich leider immer noch nicht.

        Timo

        1. Hi,

          Aber wie ich nun an das erste und letzte Element innerhalb <p> kommen soll, ohne die \r\n zu entfernen weiss ich leider immer noch nicht.

          getElementsByTagName wäre eine Möglichkeit; oder auch ausgehend vom firstChild so lange das "nächste" [1] (resp. vorherige, vom lastChild; oder gleich childNodes) Kindelement zu betrachten, bis eines mit einem anderen nodeType als #text kommt.

          [1] Das dürfte also eigentlich so gut wie immer spätestens das zweite sein, dann beim Aufbauen des DOMs kommt es nicht zu zwei oder mehr direkt hintereinanderliegenden Textknoten.

          MfG ChrisB

          --
          Light travels faster than sound - that's why most people appear bright until you hear them speak.
          1. Hi,

            [1] Das dürfte also eigentlich so gut wie immer spätestens das zweite sein, dann beim Aufbauen des DOMs kommt es nicht zu zwei oder mehr direkt hintereinanderliegenden Textknoten.

            Das kann schon vorkommen - z.B. bei riesigen Mengen Text, ich hatte den Fall mal vor einigen Jahren bei mehreren Kilobyte Text, wenn ich mich richtig erinnere, wurde der damals von einem Browser in 10K-Blöcke gesplittert.

            cu,
            Andreas

            --
            Warum nennt sich Andreas hier MudGuard?
            O o ostern ...
            Fachfragen unaufgefordert per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
          2. getElementsByTagName wäre eine Möglichkeit; oder auch ausgehend vom firstChild so lange das "nächste" [1] (resp. vorherige, vom lastChild; oder gleich childNodes) Kindelement zu betrachten, bis eines mit einem anderen nodeType als #text kommt.

            Performanter wären:

            el.lastElementChild (soll standardisiert werden, aber noch nicht breit unterstützt)
            var c = el.el.children; c[c.length -1] (nicht standardisiert, aber schon lange breit unterstützt)

            Erst wenn die nicht zur Verfügung stehen, würde ich childNodes von hinten durchlaufen.

            Am besten schreibt man sich eine kleine Bibliothek, die einem solche grundlegenden DOM-Operationen vereinfacht, wie es Christian Heilmann mit DOMhelp in seinem Buch »Beginning JavaScript with DOM Scripting and Ajax« vorgemacht hat.

            Mathias

          3. Hallo Chris,

            oder auch ausgehend vom firstChild so lange das "nächste" [...]
            Das dürfte also eigentlich so gut wie immer spätestens das zweite sein, dann beim Aufbauen des DOMs kommt es nicht zu zwei oder mehr direkt hintereinanderliegenden Textknoten.

            bist du da sicher? Ich weiß nicht, was z.B. bei einem removeChild() genau passiert. Werden zwei Textnodes, die vor und hinter dem Element liegen, dann zu einem kombiniert? Vermutlich eher nicht ...

            In einem Dokument, das noch nicht mit Javascript-Eingriffen "umgebaut" wurde, gehe ich allerdings mit deiner Argumentation mit, obwohl es anscheinend auch andere Erfahrungen gibt.

            So long,
             Martin

            --
            "Drogen machen gleichgültig."
             - "Na und? Mir doch egal."
          4. beim Aufbauen des DOMs kommt es nicht zu zwei oder mehr direkt hintereinanderliegenden Textknoten.

            Das könnte man (theoretisch) mit
            if (el.normalize) el.normalize()
            garantieren.

            Können laut http://www.quirksmode.org/dom/w3c_core.html alle relevanten Browser.

            Mathias