Onkel Schnitzel: AJAX-Response aufsplitten und ins DOM einfügen

Hallihallo,

was ist der beste Weg, einen Response aus AJAX aufzusplitten und ins DOM einzufügen? Gibt es dafür eventuell sogar spezielle Funktionen? Ich kanns mir eigentlich kaum vorstellen, aber ich wollte doch zumindest mal fragen.

Es geht darum: Ich habe eine Übersicht von Spielerbildern und per Klick auf ein Bild werden per AJAX weitere Daten des Spielers geladen und angezeigt. Nun möchte ich noch einen Button haben, mit dem ich alle Spielerdaten auf einen Schlag laden und anzeigen kann. Ich habe mir gedacht, statt 20 Mal die Funktion zu durchlaufen und immer wieder einen AJAX-Response anzufordern, den ich dann ins DOM einfüge, wäre es performanter, nur einmal per AJAX anzufragen, mir per Array-Übergabe in PHP die Daten zusammenzubauen und dann komplett ans Dokument zu liefern. Das klappt bis dahin auch. Nun habe ich einen Response in etwa dieser Form:

<ul id="daten_1">
  <li>...</li>
</ul>
<ul id="daten_6">
  <li>...</li>
</ul>
...

den ich nun in ein solches DOM einfügen möchte:

<article id="spieler_1">
  ...
</article>
...
<article id="spieler_6">
  ...
</article>

Eine Möglichkeit wäre jetzt wahrscheinlich, die ul-s mit einem regex aufzusplitten und dann die ul-Teile entsprechend ihrer id ins DOM einzufügen. Leider habe ich von regex keinen Schimmer. Gibt es also möglicherweise noch eine Möglichkeit, das zu bewerkstelligen? Ist das überhaupt eine übliche Vorgehensweise?

Beste Grüße

Onkel Schnitzel

  1. hi,

    was ist der beste Weg, einen Response aus AJAX aufzusplitten und ins DOM einzufügen?

    JSON, XML

    Gibt es dafür eventuell sogar spezielle Funktionen?

    Klar;)

    1. was ist der beste Weg, einen Response aus AJAX aufzusplitten und ins DOM einzufügen?

      JSON, XML

      Ich übergebe ja mein JS-Array zur Zeit schon per JSON an PHP und decode es da. Ich könnte also meine ul-Listen auch wieder in ein Array packen, encoden und in JS das Array durchlaufen? Verstehe ich das richtig, meinst du das?

      Gruß

      Onkel schnitzel

      1. Na gut ein konkretes Beispiel.
        Du hast einen Spieler mit der Id 7. Diese schickst du an einer bestimmtes script z.B. spieler_id_more_info.php. Dieses Script nimmt die id auf, guckt in der Datenbank nach und gibt dir ein komplettes html wieder zurück. Das nimmst du und setzt es in deinen DOM Baum.

        Wenn du mehrere ids abfragen willst, musst du natürlich ein Array übergeben. Anstatt einfach nur html zurück zu geben muss die Rückgabe jetzt ein wenig strukturierter kommen z.B. so {7:"<div>info</div>", 8:"<div>info</div>"}. Dann weißt du welche Infos zu welchem Spieler bzw. Spielerid gehören und kannst sie entsprechend in den DOM Baum setzen.
        Alternativ kannst du auch mehrere asynchrone Anfragen machen.

        Gruß
        Starspieler
        T-Rex

        1. Hallo,

          Wenn du mehrere ids abfragen willst, musst du natürlich ein Array übergeben. Anstatt einfach nur html zurück zu geben muss die Rückgabe jetzt ein wenig strukturierter kommen z.B. so {7:"<div>info</div>", 8:"<div>info</div>"}. Dann weißt du welche Infos zu welchem Spieler bzw. Spielerid gehören und kannst sie entsprechend in den DOM Baum setzen.

          Es könnte doch trotzdem als html zurückkommen:
          <div id="spieler7">info</div><div id="spieler8">info</div>
          und man könnte es über die Id an der richtigen Stelle plazieren. Was performanter ist, weiß ich allerdings nicht...

          Viele Grüße
          Siri

        2. Wenn du mehrere ids abfragen willst, musst du natürlich ein Array übergeben. Anstatt einfach nur html zurück zu geben muss die Rückgabe jetzt ein wenig strukturierter kommen z.B. so {7:"<div>info</div>", 8:"<div>info</div>"}. Dann weißt du welche Infos zu welchem Spieler bzw. Spielerid gehören und kannst sie entsprechend in den DOM Baum setzen.

          So hab ichs jetzt gemacht. Ich hatte irgendwie nicht aufm Schirm, dass man ja das komplette HTML auch als einzelne Strings in ein Array packen kann.

          Alternativ kannst du auch mehrere asynchrone Anfragen machen.

          Bis zu welcher Zahl an Anfragen macht man denn sowas? Ich hätte gedacht, dass es für den Server "aufwendiger" ist, dutzende kleine Anfragen abarbeiten zu müssen, als eine einzelne Große.

          Besten Dank

          Onkel Schnitzel

          1. Bis zu welcher Zahl an Anfragen macht man denn sowas? Ich hätte gedacht, dass es für den Server "aufwendiger" ist, dutzende kleine Anfragen abarbeiten zu müssen, als eine einzelne Große.

            Das kommt wie schon gesagt auf den Anwendungsfall drauf an. Wenn der User auf EINEN Spieler klickt und die Infos von diesem EINEN Spieler sieht, dann würde ich nur diese Infos laden. Du weißt ja nicht ob der User noch auf die anderen Spieler klickt.
            Du hast jedoch von einem Button erzählt wo man alle Spielerinfos sehen kann. Jetzt ist natürlich die Frage ob man dennoch mehrere kleinere Anfragen abschießt. Pro für dieses Vorhaben ist die Tatsache dass du nichts extra programmieren brauchst. Wenn du die Einspieler Abfrage entwickelt hast musst du nur noch eine Schleife drumherum bauen und fertig.
            Contra wäre der höhere Overhead. Bei jeder Anfrage würden Cookie, HTTP Header etc mitgesendet werden. Das wiederum spricht für eine zweite Lösung wo alle Daten zurück kommen.
            Am Ende bleibt die Frage wie oft ein User den alles sehen Button anklickt bzw. ob es diesen Button überhaupt geben muss.

            Alternativ kannst du auch die Daten gleich ins HTML laden und verstecken. Das würde zwar absolut entgegen allem laufen was ich gerade gesagt habe, könnte aber unter Umständen ein Vorteil für SEO sein. Außerdem müsstest du dann nicht mehr auf JS zurück greifen sondern kannst css wählen, was wiederum eine Barrierefreiheit wäre.

            Gruß
            Olympia Muffel
            T-Rex

            1. Du hast jedoch von einem Button erzählt wo man alle Spielerinfos sehen kann. Jetzt ist natürlich die Frage ob man dennoch mehrere kleinere Anfragen abschießt. Pro für dieses Vorhaben ist die Tatsache dass du nichts extra programmieren brauchst. Wenn du die Einspieler Abfrage entwickelt hast musst du nur noch eine Schleife drumherum bauen und fertig.

              Richtig, das wäre das Einfachste gewesen.

              Contra wäre der höhere Overhead. Bei jeder Anfrage würden Cookie, HTTP Header etc mitgesendet werden. Das wiederum spricht für eine zweite Lösung wo alle Daten zurück kommen.

              Ok, also ist es ja schon so, dass da n bissel was passiert. Ich denke, meinen Server wird es freuen.

              Am Ende bleibt die Frage wie oft ein User den alles sehen Button anklickt bzw. ob es diesen Button überhaupt geben muss.

              Der Button ist ne Komfortfunktion. Wenn man einmal auf den Geschmack gekommen ist, wird man nicht mehr anders können, als ihn immer wieder zu drücken :-)

              Alternativ kannst du auch die Daten gleich ins HTML laden und verstecken. Das würde zwar absolut entgegen allem laufen was ich gerade gesagt habe, könnte aber unter Umständen ein Vorteil für SEO sein. Außerdem müsstest du dann nicht mehr auf JS zurück greifen sondern kannst css wählen, was wiederum eine Barrierefreiheit wäre.

              Stimmt, da ist naürlich was dran. Da ich mich aber bewusst mal mit AJAX beswchäftigen wollte, ists das so jetzt ok.

      2. hi,

        Ich übergebe ja mein JS-Array zur Zeit schon per JSON an PHP und decode es da. Ich könnte also meine ul-Listen auch wieder in ein Array packen, encoden und in JS das Array durchlaufen? Verstehe ich das richtig, meinst du das?

        JSON ist nur der Transport. Serverseitig hast Du eine Datenstruktur, z.B. ein array in PHP

          
        $data[$user_id]['firstname'];  
        $data[$user_id]['lastname'];
        ~~~ usw.  
          
        Idealerweise liefert ein clientseitiger Parser genau dieselbe Datenstruktur für's DOM:  
          
        ~~~javascript
          
        data[user_id]['firstname'];  
        data[user_id]['lastname'];
        ~~~ usw. damit hast Du wahlfreien Zugriff auf diese Daten, kannst per Selector Elemente mit den Daten betanken, li-Childs anhängen usw. und das geht freilich auch mit Schleifendurchläufen.  
          
        Horst  
          
        
        
  2. Moin,

    Also wie immer gibt es da unterschiedliche Möglichkeiten.

    Du kannst entweder die Daten nackt in einem bestimmten Format übergeben. JSON wäre hier das einfachste.
    Vorteil wäre, dass du gleichzeitig eine universelle Schnittstelle hättest, die du z.B. für Apps benutzen könntest.

    Du kannst die Daten aber auch gleich mit html übergeben. Der Vorteil wäre, dass du Server seitig wahrscheinlich die gleiche Template Engine benutzen kannst. jQuery bietet dir sehr einfache Funktionen wie du in ein paar wenigen Codezeilen das Ajax laden und sofort einem Knoten zuweisen kannst.

    Bleibt noch die Frage ob du alle Daten auf einmal laden solltest. Das kommt ganz auf die Anwendung drauf an. Wenn die Daten per Click geladen werden, dann kann man dem User einen kleinen Moment zumuten den er auf die Daten wartet -(eventuell mit Ladebalken oder Zahnrad oder so). Sollten die Daten jedoch per Mausover sichtbar werden, dann würde ich es so wie du machen und die Daten auf einmal laden. Wobei da auch die Überlegung ist ob die Daten von vornherein schon geladen sind und erst bei einem Mausover sichtbar gemacht werden.
    Generell bin ich eher der Freund davon sowenig Daten wie möglich zu laden. Du weißt nicht was der User am Ende wirklich sehen will. Deshalb würde ich nicht alle Spielerdaten zusammen schmeißen sondern nur das laden was gebraucht wird. Das verringert unnötigen Overhead.

    Gruß
    Fussballgott
    T-Rex

    1. Du kannst entweder die Daten nackt in einem bestimmten Format übergeben. JSON wäre hier das einfachste.

      Ja, das wäre dann wohl mein Mittel der Wahl. Jetzt muss ich nur noch herausfinden, wie genau ich das angehe :-)

      Bleibt noch die Frage ob du alle Daten auf einmal laden solltest. Das kommt ganz auf die Anwendung drauf an. Wenn die Daten per Click geladen werden, dann kann man dem User einen kleinen Moment zumuten den er auf die Daten wartet -(eventuell mit Ladebalken oder Zahnrad oder so). Sollten die Daten jedoch per Mausover sichtbar werden, dann würde ich es so wie du machen und die Daten auf einmal laden.

      Eine Ladegrafik wäre durchaus ok für mich. Nichtsdestotrotz versuche ich immer, den Server so wenig wie möglich zu belasten, auch wenn der Unterschied wahrscheinlich marginal ist, ich kann einfach nicht anders. Deswegen wollte ich eine 20-fache AJAX-Anfrage vermeiden.

      Generell bin ich eher der Freund davon sowenig Daten wie möglich zu laden. Du weißt nicht was der User am Ende wirklich sehen will. Deshalb würde ich nicht alle Spielerdaten zusammen schmeißen sondern nur das laden was gebraucht wird. Das verringert unnötigen Overhead.

      Im Grunde lade ich ja erstmal so wenig Daten wie möglich, indem die Daten für jeden Spieler, den der User anklickt, einzeln geholt werden. Klickt er auf 'Alle Daten anzeigen', ist das ja eine bewusste Entscheidung und dann will ich die Daten natürlich auch holen.

      T-Rex

      1. hi,

        Eine Ladegrafik wäre durchaus ok für mich. Nichtsdestotrotz versuche ich immer, den Server so wenig wie möglich zu belasten, auch wenn der Unterschied wahrscheinlich marginal ist, ich kann einfach nicht anders. Deswegen wollte ich eine 20-fache AJAX-Anfrage vermeiden.

        Interessehalber, für den Fall, dass das nur ein Request werden soll: Wie groß ist denn die zu sendende Datenmenge (bytes), hast Du das mal abgeschätzt?

        Horst

        1. Interessehalber, für den Fall, dass das nur ein Request werden soll: Wie groß ist denn die zu sendende Datenmenge (bytes), hast Du das mal abgeschätzt?

          Chrome zeigt mir unter Network schlappe 7.0 KB an.

          Gruß

          Onkel Schnitzel

          1. Interessehalber, für den Fall, dass das nur ein Request werden soll: Wie groß ist denn die zu sendende Datenmenge (bytes), hast Du das mal abgeschätzt?

            Chrome zeigt mir unter Network schlappe 7.0 KB an.

            Das ist nicht viel, das lohnt keinen Aufwand für eine Progressbar.

            Eine richtig fette Ajax-Response habe ich hier als Demo, das sind 2MB, die Response dauert ca. 3s bei DSL6000.

            Also, pack Deine Daten in JSON und alles wird gut ;)

            Horst

  3. Hallo,

    <ul id="daten_1">
      <li>...</li>
    </ul>
    <ul id="daten_6">
      <li>...</li>
    </ul>
    ...

    den ich nun in ein solches DOM einfügen möchte:

    <article id="spieler_1">
      ...
    </article>
    ...
    <article id="spieler_6">
      ...
    </article>

    Eine weitere Möglichkeit:

    Sende die Daten als XML (Markup im XHTML-Namensraum, MIME-Typ application/xml oder application/xhtml+xml) und greife auf XMLHttpRequest#responseXML zu. Das ist direkt ein DOM, die Eigenschaft liefert einen Document-Knoten.

    Suche die ul-Elemente darin (doc.getElementsByTagName, doc.querySelectorAll…), importiere sie ins HTML-DOM und hänge sie an die zugehörigen Elemente. Die Zuordnung kannst du anhand der IDs vornehmen.

    Eine Möglichkeit wäre jetzt wahrscheinlich, die ul-s mit einem regex aufzusplitten

    Reguläre Ausdrücke wären hier die schlechteste Wahl. Arbeiten auf DOM-Ebene ist immer sinnvoller.

    Ist das überhaupt eine übliche Vorgehensweise?

    Nein. JSON und XML sind Formate zur Übertragung allgemeiner strukturierter Daten.

    Mathias

    1. Sende die Daten als XML (Markup im XHTML-Namensraum, MIME-Typ application/xml oder application/xhtml+xml) und greife auf XMLHttpRequest#responseXML zu. Das ist direkt ein DOM, die Eigenschaft liefert einen Document-Knoten.

      Aaaah, ich wünschte, ich hätte noch gewartet. So ist's wesentlich eleganter. Zumal ich nicht meine komplette PHP-Datei noch einmal hätte umbauen müssen, um mein JSON-Array zusammenzubasteln. Nun fasse ich's nicht nochmal an. Beim nächsten Mal...

      Besten Dank

      Onkel Schnitzel

      1. Hallo,

        So ist's wesentlich eleganter.

        Naja, geht… Vorausgesetzt ist, dass das PHP wohlgeformtes XHTML produziert. Das ist durch String-Concatenation nicht gewährleistet – so arbeiten aber die meisten PHP-Scripte. Schon eher durch Nutzung von SimpleXML oder DOM. X(HT)ML richtig umzusetzen führt einen tief in den XML-Abgrund.

        Und es kommt das Importieren der Knoten im JavaScript hinzu. Gut, das ist nur eine Zeile und eine kleine Formalie.

        Mathias