Rolf B: Problem mit anzeigen von HTML-Code beim javascript

Beitrag lesen

Hallo jonas99,

dein Problem ist - wie bei so vielen - der unsaubere Kontextwechsel.

var us = '<b>ID ' + ide + ': ' + name + '</b><br><br>';
var link = '<p>Klicke für weitere infos: <a href="http://link.de">Hier</a>';
var point = new google.maps.LatLng(...);

var contentString = us +        // Hier steht HTML
                    desc +      // Hier steht maskiertes HTML
                    link;       // Hier steht HTML

Problem ist nun, dass es nicht mal eben so eine Javascript-Funktion zu geben scheint, die die Entity-codierung in desc rückübersetzt.

Ich sehe zwei Wege, das zu umschiffen. Wenn es nur um Zeilenumbrüche geht, kannst Du Dir ein eigenes Zeichen (oder eine Zeichenfolge) ausdenken, die für einen Umbruch steht. Die ersetzt Du dann mittels split und join durch <br>.

Wenn Du mehr brauchst, also HTML-Elemente in der Description, dann könntest Du den alternativen Input für setContent verwenden: einen Node. Den baust Du on-the-fly zusammen.

(...)
var desc = markerElem.getAttribute('beschreibung');
(...)
var contentString = us + '<span class="innerInfoText"></span>' + link;

(...)

marker.addListener('click', function() {
   var infoContent = document.createElement("div");
   infoContent.innerHTML = contentString;
   infoContent.querySelector(".innerInfoText").innerHTML = desc;

   infoWindow.setContent(infoContent);
   infoWindow.open(map, marker);
};

Mit createElement erzeugst Du ein div-Element, erstmal im leeren Raum. Dem gibst Du dann ein HTML-Innenleben, ähnlich dem HTML dass Du vorher dem InfoWindow gegeben hast, aber mit einem Platzhalter für den desc Teil. Dieser Platzhalter ist ein span-Element mit einer Klasse; dieses Element suchst Du dann mit querySelector heraus und gibt ihm wiederum ein HTML Innenleben. Damit hast Du den Kontext gewahrt und das Fenster müsste sauber erscheinen.

Natürlich ist das riskant. Du musst sicherstellen, dass der desc-String vertrauenswürdig ist. Er darf nicht von einem Dir unbekannten User eingegeben sein. Andernfalls könnte er Script-Elemente enthalten, die Böses tun.

Übrigens war in deinem Code vermutlich ein Kopierfehler: der Click-Handler sollte an markerElem angehängt werden, oder?

Unabhängig von der verwendeten Variante noch eine Überlegung. Wenn Du sie nicht verstehst, ignoriere sie einfach, vermutlich ist es nicht wirklich gravierend.

Ob dein Vorgehen von der Variablenhaltung her optimal ist, da bin ich nicht sicher. Du baust hier einiges an Closures zusammen, bei vielen Markern kann das einiges an Speicher fressen. Mit der Effizienz von Closures in JavaScript bin ich nicht 100% vertraut; es mag auch von Browser zu Browser verschieden sein. Ich würde vermutlich das Anhängen des Event-Listeners in eine Funktion auslagern, die möglichst global aufgehängt ist (um möglichst wenige geschachtelte Closures zu erben), und ihr map, markerElem, contentString und desc als Parameter übergeben. Die Closure um den Eventhandler ist dann viel kleiner.

Ach ja. Was ist eine Closure. Hier steht etwas dazu. Die Kurzfassung ist: wenn Du den Eventhandler inline im Ajax-Responsehandler definierst, bekommt er den aktuellen Variablensatz des Responsehandlers als Anhängsel mit und die Variablen werden nach Ende des Responsehandlers nicht freigegeben.

Rolf

--
sumpsi - posui - clusi