Axel: Frage zum Wiki-Artikel „DOM-Scripting“

problematische Seite

ich habe drei Dateien im gleichen Verzeichnis:

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>SVG mit Button</title>
  </head>
  <body>
    <button id="meinButton">Kreis zeichnen</button>
    <object id="svg-object" data="meineSVG.svg" type="image/svg+xml"></object>
    <script src="meinSkript.js"></script>
  </body>
</html>Quelltext hier

meineSVG.svg

<svg xmlns="http://www.w3.org/2000/svg" id="meineSVG" width="200" height="200">
    <rect x="50" y="50" width="100" height="100" stroke="black" fill="none"/>
</svg>

und meinSkript.js

window.onload = function () {
  var button = document.getElementById("meinButton");
  button.addEventListener("click", function () {
    var svgObject = document.getElementById("svg-object");
    var svgDoc = svgObject.contentDocument;
    var circle = document.createElementNS(
      "http://www.w3.org/2000/svg",
      "circle"
    );
    circle.setAttribute("cx", 100);
    circle.setAttribute("cy", 100);
    circle.setAttribute("r", 50);
    circle.setAttribute("fill", "red");
    svgDoc.querySelector("svg").appendChild(circle);
  });
};

Beim ausführen bekomme ich folgenden Fehler:

Cannot read properties of null (reading 'querySelector') at HTMLButtonElement.

Ich scheine von JS aus nicht auf die SVG zugreifen zu können.

Was mache ich falsch?

  1. problematische Seite

    Hallo Axel,

    startest Du die HTML Seite über file:/// oder über http:// ?

    Das ist relevant, denn file-Zugriffe bewirken, dass das SVG Dokument und das HTML Dokument keinen gemeinsamen Origin haben - und damit steht Dir der Zugriff auf das contentDocument nicht zur Verfügung. Also, wenn Du file:/// verwendest, brauchst Du einen Webserver, damit Du http:// verwenden kannst. Welchen und wie Du das machst, hängt von deinem Betriebssystem ab.

    Wenn Du Dein Script so wie gezeigt am Ende des body einbindest, brauchst Du übrigens keinen onload-Handler. Der wäre höchstens relevant, wenn Du das SVG nicht im click-Event, sondern sofort im Script auslesen wolltest - dann könnte es noch nicht verfügbar sein.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. problematische Seite

      Hallo Rolf,

      du hast recht, vielen Dank! Hat ein wenig gedauert einen Webserver einzurichten und es auszuprobieren. Ich hatte auch ein Problem mit ausgelagerter CSS das hat sich jetzt auch aufgelöst.

      Schade ist, dass ich jetzt meine Dateien nicht einfach verteilen kann. Ohne Webserver werden sie nicht funktionieren.

      Nochmals vielen Dank, Axel.

      1. problematische Seite

        Hallo Axel,

        du kannst inline-SVG verwenden. Du musst keine externe SVG Datei einbinden.

        Und ich frage mich gerade: Ist es richtig, dass Du für den Kreis document.createElement verwendest? Müsste das nicht svgDoc.createElement sein?

        Rolf

        --
        sumpsi - posui - obstruxi
      2. problematische Seite

        Hallo Axel,

        Schade ist, dass ich jetzt meine Dateien nicht einfach verteilen kann. Ohne Webserver werden sie nicht funktionieren.

        zum Verteilen eher nicht geeignet, aber zum lokalen Testen kann man sich behelfen. Z. B. eine Chrome-/Chromium-Instanz als zusätzliche Verknüpfung anlegen und dort --allow-file-access-from-files angeben.

        Grüße,
        Thomas

        1. problematische Seite

          Hallo ThomasM,

          Superhinweis! Funktioniert (in Chromium-Edge) auch heute noch. Wobei - es schadet definitiv nichts, sich einmal die Mühe zu machen, einen Testwebserver aufzusetzen. Bei file:///-Ressourcen gibt's auch andere Probleme (wie das Fehlen von Cache, Headern und MIME-Types), die einem beim schlussendlichen Übergang auf einen realen Webserver dann auf die Füße fallen können.

          Aber wenn man es macht, bitte das Gotcha beachten, dass im Artikel im Nebensatz steht: Chrome muss zunächst komplett geschlossen werden, dann erst greift der Parameter.

          Rolf

          --
          sumpsi - posui - obstruxi