Rachus: Sollte man "innerHTML" verwenden?

Hallo,

leider muss ich euch wieder einmal belästigen.

Im Moment bastel ich an einer Seite, bei der ich dynamisch Inhalt anzeige. Meine Fragemente, die ich einfüge sehen im Moment etwa so aus: <div class="note">Text. <a href="#">Link</a></div>
Das füge ich mithilfe von innerHTML in das Dokument ein.

Nun frage ich mich allerdings, ob das wirklich die beste Möglichkeit für so etwas ist. Denn innerHTML ist ja kein Standard und außerdem wage ich mich zu erinnern, dass es bei XHTML Probleme macht. Gibt es denn eine andere Lösung, um solche Fragmente in ein Dokument einzubauen?
Wie bekommt es beispielsweise JQuery hin?

Eine andere Idee von mir war, das responseXML eines XMLHttpRequests in den DOM-Baum einzufügen. Allerdings werden da die Attribute nicht übernommen und das <a>-Element beispielsweise wird nicht als Link erkannt. Das liegt vermutlich an einem falschen Namespace.

Meine letzte Idee war es, den String selbst zu parsen und daraus ein normales DOM-Element zu erzeugen. Allerdings übersteigt das meine Fähigkeiten.

Wie füge ich nun so ein Fragment richtig in ein Dokument ein? Oder gibt es dazu keine standardkonforme Möglichkeit?

Schönen Nachmittag

Rachus

  1. Hi,

    Denn innerHTML ist ja kein Standard

    innerHTML ist de facto Standard - und die offizielle Standardisierung steht auch an. Unterstützt wird es ohnehin von allen DOM-Browsern (von allerersten DOM-Operas mal abgesehen).

    und außerdem wage ich mich zu erinnern, dass es bei XHTML Probleme macht.

    Nicht das ich wüßte.

    Meine letzte Idee war es, den String selbst zu parsen und daraus ein normales DOM-Element zu erzeugen. Allerdings übersteigt das meine Fähigkeiten.

    Learning by doing. ;-)

    Gruß, Cybaer

    --
    Zweck des Disputs oder der Diskussion soll nicht der Sieg, sondern der Gewinn sein.
    (Joseph Joubert, Schriftsteller)
    1. Hallo,

      Meine letzte Idee war es, den String selbst zu parsen und daraus ein normales DOM-Element zu erzeugen. Allerdings übersteigt das meine Fähigkeiten.

      Learning by doing. ;-)

      Glaub mir, ich habe das schon versucht. Aber ich habe es nicht hinbekommen über mehr als ein Tag hinauszuparsen.
      Wahrscheinlich fehlt mir das Wissen, wie man denn einen String überhaupt parst. Das müsste doch mithilfe von Rekursion und einer Zustandsmaschine gehen, oder?

      Aber das hat sich jetzt ja glücklicherweise erledigt!

      Schönen Abend

      Rachus

  2. Hi,

    [..] Das füge ich mithilfe von innerHTML in das Dokument ein.

    Nun frage ich mich allerdings, ob das wirklich die beste Möglichkeit für so etwas ist. Denn innerHTML ist ja kein Standard

    Es ist seit Jahren Quasi-Standard, und inzwischen mit HTML5 auch vom W3C standardisiert.

    und außerdem wage ich mich zu erinnern, dass es bei XHTML Probleme macht.

    Nein, tut's nicht.

    Eine andere Idee von mir war, das responseXML eines XMLHttpRequests in den DOM-Baum einzufügen. Allerdings werden da die Attribute nicht übernommen und das <a>-Element beispielsweise wird nicht als Link erkannt.

    Und wie hast du das versucht?

    Meine letzte Idee war es, den String selbst zu parsen und daraus ein normales DOM-Element zu erzeugen. Allerdings übersteigt das meine Fähigkeiten.

    Wäre auch relativ sinnfrei.
    Es ist eine der grundlegendesten Fähigkeiten von Browsern, HTML parsen zu können. Wenn du innerHTML benutzt, kann der Browser genau die gleichen Mechanismen zur Anwendung bringen, die er sowieso implementiert hat, um HTML zu parsen, wenn es nicht aus einem Textstring stammt, sondern aus einer von im selber direkt angeforderten HTML-Ressource.
    Jegliche Versuche, selber einen Parser in JavaScript zu basteln, der das gleiche leistet, werden garantiert extrem viel langsamer sein.

    Wie füge ich nun so ein Fragment richtig in ein Dokument ein? Oder gibt es dazu keine standardkonforme Möglichkeit?

    Du kannst einen Knoten aus deinem XML-Dokument auch mittels importNode in dein aktuelles Dokument importieren - dann kannst du ihn anschliessend in dessen DOM einfügen, wie sonst auch. Allerdings hat der IE diese Methode erst ab Version 8 implementiert.

    MfG ChrisB

    --
    “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
    1. Hallo,

      Es ist seit Jahren Quasi-Standard, und inzwischen mit HTML5 auch vom W3C standardisiert.

      schön zu wissen!

      und außerdem wage ich mich zu erinnern, dass es bei XHTML Probleme macht.

      Dann habe ich das wohl verwechselt. Wahrscheinlich mit document.write, das ja in XHTML nicht mehr funktioniert.

      Eine andere Idee von mir war, das responseXML eines XMLHttpRequests in den DOM-Baum einzufügen. [...]

      Und wie hast du das versucht?

      Ganz einfach: Ich habe einen XMLHttpRequest abgesetzt und dann das responseXML per appendChild eingefügt:
      document.getElementsByTagName("body")[0].appendChild(xmlHttp.responseXML.firstChild);
      wobei in der Datei, die ich dazu auslese, exakt das Fragment ist.
      Aber wie schon gesagt, ist dann der Link z.B. kein Link mehr.

      Du kannst einen Knoten aus deinem XML-Dokument auch mittels importNode in dein aktuelles Dokument importieren - dann kannst du ihn anschliessend in dessen DOM einfügen, wie sonst auch. Allerdings hat der IE diese Methode erst ab Version 8 implementiert.

      Von dieser Methode habe ich noch nie etwas gehört. Testweise habe ich aber schon ausprobiert, von dem XML des Ajax-Responses den Inhalt zu importieren. Allerdings ergab das keine Änderung.

      Schönen Abend

      Rachus

      1. Hi,

        Eine andere Idee von mir war, das responseXML eines XMLHttpRequests in den DOM-Baum einzufügen. [...]

        Und wie hast du das versucht?

        Ganz einfach: Ich habe einen XMLHttpRequest abgesetzt und dann das responseXML per appendChild eingefügt:
        document.getElementsByTagName("body")[0].appendChild(xmlHttp.responseXML.firstChild);

        Das geht nicht direkt, weil die Knoten zu unterschiedlichen Elterndokumenten gehören -

        Du kannst einen Knoten aus deinem XML-Dokument auch mittels importNode in dein aktuelles Dokument importieren

        • deshalb musst du den Knoten aus deinem XML erst in das Dokument importieren, in das du es einfügen willst.

        MfG ChrisB

        --
        “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
        1. Hallo,

          document.getElementsByTagName("body")[0].appendChild(xmlHttp.responseXML.firstChild);

          Das geht nicht direkt, weil die Knoten zu unterschiedlichen Elterndokumenten gehören -

          • deshalb musst du den Knoten aus deinem XML erst in das Dokument importieren, in das du es einfügen willst.

          habe ich gemacht:
          document.getElementsByTagName("body")[0].appendChild(document.importNode(xmlHttp.responseXML.firstChild, true));
          Und dennoch tritt der gleich Fehler auf (getestet in Firefox und Opera). Habe ich sonst noch irgendwas nicht beachtet?

          Grüße

          Rachus

          1. Hi,

            habe ich gemacht:
            document.getElementsByTagName("body")[0].appendChild(document.importNode(xmlHttp.responseXML.firstChild, true));
            Und dennoch tritt der gleich Fehler auf (getestet in Firefox und Opera).

            Welcher Fehler überhaupt? Du hast ihn noch gar nicht benannt. (Nicht „funzt nich“, sondern die Fehlermeldung aus der Fehlerkonsole.)

            Habe ich sonst noch irgendwas nicht beachtet?

            Die schon angesprochenen Namespaces könnten problematisch sein.
            Hast du das HTML-Element, dass du importieren willst, dem HTML-Namespace zugeordnet?

            MfG ChrisB

            --
            “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
            1. Hallo,

              Welcher Fehler überhaupt? Du hast ihn noch gar nicht benannt. (Nicht „funzt nich“, sondern die Fehlermeldung aus der Fehlerkonsole.)

              es ist kein Fehler im eigentlichen Sinne. Wie ich eben bereits schon geschrieben habe, wird ein <a>-Element, welches sich im Fragment befindet nicht als Link dargestellt. In der Fehlerkonsole erscheint nichts.

              Die schon angesprochenen Namespaces könnten problematisch sein.
              Hast du das HTML-Element, dass du importieren willst, dem HTML-Namespace zugeordnet?

              Ja, ich habe gerade dem Fragment einen Namespace gegeben und siehe da, der Link wird auch als Link dargestellt.

              Jetzt habe ich sogar 2 Möglichkeiten, so einen HTML-Ausschnitt in mein Dokument einzufügen.

              Danke für eure Hilfe!

              Rachus

  3. Hallo,

    mir ist da gerade noch etwas bei appendChild aufgefallen, dass ich mir allerdings schon selbst beheben konnte. Mich interessiert im Moment, ob folgendes Verhalten normal ist.

    Aus meinem XMLHttpRequest habe ich das responseXML genommen und zweimal hintereinander per appendChild im Body-Element angefügt.

    /* XMLHttpRequest hat das responseXML in der Variable "XML" gespeichert */  
      
    var body=document.getElementsByTagName("body")[0];  
      
    body.appendChild(XML);  
    body.appendChild(XML);
    

    Nun wird aber das Markup nur einmal eingefügt. Nach einigen Tests fiel mir auf, dass "XML" von appendChild irgendwie entfernt bzw. "null" gesetzt wird. Ist das normal, dass das so ist?

    Als Behelf habe ich jetzt den Knoten einfach geklont.

    Schön wenn ihr mich aufklären könntet. Denn in der Spezifikation steht eigentlich nur, dass bei DocumentFragments der Inhalt entfernt wird und nicht auch bei "normalen" Elementen.

    Schöne Grüße

    Rachus

    1. Nun wird aber das Markup nur einmal eingefügt. Nach einigen Tests fiel mir auf, dass "XML" von appendChild irgendwie entfernt bzw. "null" gesetzt wird. Ist das normal, dass das so ist?

      Ja.

      Schön wenn ihr mich aufklären könntet. Denn in der Spezifikation steht eigentlich nur, dass bei DocumentFragments der Inhalt entfernt wird und nicht auch bei "normalen" Elementen.

      und

      If the newChild is already in the tree, it is first removed.

      Struppi.

      1. Hi,

        [...] Spezifikation [...]

        und

        If the newChild is already in the tree, it is first removed.

        das ging bei mir wohl zu einem Auge rein und zum anderen wieder raus... Dankeschön fürs zeigen!

        Schönen Abend

        Rachus