Ajaxing für Ihr SVG Sprite

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Angenommen, Sie erstellen ein SVG-Iconsystem. Sie erstellen manuell ein SVG-Sprite voller Symbole oder verwenden ein Build-Tool wie IcoMoon oder grunt-svgstore, um es für Sie zu erstellen.

Was machen Sie mit diesem sprite.svg?

Eine Option ist, es direkt am Anfang des Dokuments einzufügen und dann damit zu arbeiten <use>.

...

</head>

<body>

  <!-- include it here -->
  <?php include_once("svg/sprite.svg"); ?>

  ...

  <!-- use it here -->
  <a href="/" class="logo">
    <svg class="logo">
      <use xlink:href="#logo" />
    </svg>
  </a>

Das funktioniert, aber es nutzt das Caching nicht sehr gut. Wenn die Website HTML-Caching verwendet, enthält jede einzelne Seite diesen großen Block identischer SVG-Daten, was etwas aufbläht. Ganz zu schweigen davon, dass der HTML-Parser vor dem Inhalt all diese Daten bei jedem Seitenaufruf im Dokument durchlesen muss.

Wahrscheinlich ist es besser, das Browser-Caching zu nutzen, wie wir es bei allen anderen Assets tun. Das können wir erreichen, indem wir unsere <use>-Elemente auf eine externe Quelle verweisen lassen. Aber einige Browser haben damit Probleme. Nämlich jede Version von IE und einige ältere WebKit-Versionen.

SVG for Everybody, das wir hier empfohlen haben, funktioniert meist gut. Aber es gibt einige Browser, die es mit dem UserAgent-Abgleich nicht erfasst.

Ein alternativer Ansatz ist, das Sprite einfach per Ajax abzurufen (immer) und es auf die Seite zu injizieren. Das bedeutet, dass Sie dieses SVG im Browser cachen können und es überall dort funktioniert, wo Inline-SVG funktioniert.

Wenn Sie ein vollständiges SVG-Dokument per Ajax abrufen (sprite.svg), ist es tatsächlich *etwas* knifflig. Sie müssen sicherstellen, dass das SVG den richtigen Namensraum hat, bevor Sie es auf die Seite einfügen (danke Amelia). Glücklicherweise können wir den HTML-Parser ausnutzen, der normalerweise dafür zuständig ist. Das erreichen wir, indem wir das SVG in ein <div> einfügen und dieses dann auf die Seite einfügen.

var ajax = new XMLHttpRequest();
ajax.open("GET", "svg/sprite.svg", true);
ajax.send();
ajax.onload = function(e) {
  var div = document.createElement("div");
  div.innerHTML = ajax.responseText;
  document.body.insertBefore(div, document.body.childNodes[0]);
}

Wenn Sie jQuery verwenden, sind die Callback-Daten, die es Ihnen liefert, bereits als SVG-Dokument formatiert. Sie müssen es also zuerst wieder in einen String umwandeln, bevor Sie es in das Div und schließlich auf die Seite einfügen.

$.get("svg/sprite.svg", function(data) {
  var div = document.createElement("div");
  div.innerHTML = new XMLSerializer().serializeToString(data.documentElement);
  document.body.insertBefore(div, document.body.childNodes[0]);
});

Denken Sie daran, dass Sie bei diesem Ansatz nur den Bezeichner verwenden, nicht die externe Quelle.

<svg class="icon" viewBox="0 0 100 100">
  <use xlink:href="#shape-icon-1" />
</svg>

Scheint in IE und Android gut zu funktionieren

Denken Sie auch daran, dass SVG for Everybody Ihnen dabei hilft, die Markup-Elemente in Nicht-Unterstützungs-Browsern in <img src="...png"> umzuwandeln. Wenn Ihnen das wichtig ist, müssten Sie das dort selbst regeln.