测试 SVG 作为 img 标签的支持

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

浏览器对 SVG 的支持并非简单地是“是”或“否”。除了支持方式的一些特殊情况外,它还取决于 SVG 的使用方式。一种常见的方式是直接在图像标签中使用,例如 <img src="image.svg" alt="description">

如何检测浏览器是否支持这种 SVG 使用方式呢?

了解哪些浏览器支持是一回事。唯一真正危险的区域是 IE 8 及更早版本以及 Android 2.3。您可以进行用户代理检测,虽然我不希望对此过于苛刻,但它 通常不是一个好主意

我正在查看 SVGeezy,这是一个专门用于帮助 SVG 作为 img 标签的回退的迷你 JavaScript 插件。当然,为了使其工作,它需要进行功能检测。在 源代码 中,它只是一行代码

supportsSvg: function() {
  return document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1");
}

我以前从未见过 document.implementation.hasFeature,所以我四处询问了一下,因为它似乎对我从未听说过的事情来说太好了。大多数现有的文档都非常通用,并暗示了良好的浏览器支持,这让我更加怀疑。

事实是:它几乎没用。它几乎总是返回所有内容的 true。但是,显然,在 SVG 作为 img 标签的情况下,它是正确的。作为一个怀疑论者,我创建了一个测试来验证这是否属实。

我做的第一件事是检查 Modernizr 如何检测它,作为功能检测的首选来源。**此处的重要说明:**Modernizr 的默认 SVG 测试(Modernizr.svg)不是在测试 SVG 作为 img 标签的支持,而是在测试 SVG 作为 <object><embed> 的支持。在使用它进行回退时请注意这一点。测试正确的内容(它们有针对您可以使用 SVG 的所有方式的测试)。

它们有一个专门用于 SVG 作为 img 标签的测试,如下所示

Modernizr.addAsyncTest(function () {
  var img = new Image();

  img.onerror = function () {
    addTest('svgasimg', false);
  };
  img.onload = function () {
    addTest('svgasimg', img.width == 1 && img.height == 1);
  };

  // 1px x 1px SVG; must be base64 or URI encoded for IE9... base64 is shorter
  img.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==';
});

这会创建一个新的图像元素,注入一个 Data URI 的 1×1 SVG 图像,然后等待它失败或正确加载。

显然与 hasFeature 测试不同,因此 我创建了一个 CodePen 来显示两种方法的结果。然后我在各种不同的浏览器中进行了测试。这些浏览器中既有已知支持 SVG 作为 img 标签的,也有不支持的。在所有情况下,结果都是相同的。很奇怪,但也非常酷!

最初的 Modernizr 测试被称为“异步”测试,这意味着它依赖于回调函数来提供答案。Modernizr 通常更喜欢“同步”测试,在这种测试中,一旦测试定义,它就会得到正确的答案。

因此,在与 Modernizr 团队讨论后,它现在是 SVG 作为 img 标签的默认测试。它还没有发布,所以现在您需要自己运行它。

Modernizr.addTest('svgasimg', document.implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#Image', '1.1'));

一旦发布,我将更新这篇文章(以及我们在 CodePen 上运行的版本)。

感谢 Patrick Kettner 监督它 进入 Modernizr,感谢 Stu Cox 的反馈并批准替换他最初的方法,感谢 Ben Howdle 了解酷炫的 hasFeature() 并在 SVGeezy 中 使用它,以及感谢 Mike Taylor 验证 它的实用性。

哦,如果您检测到浏览器不支持 SVG 作为 img 标签,则需要将 src 切换为支持的图像格式。可能是 the-same-image.png,可以根据命名约定自动切换,也可以根据 data-* 属性选择性地切换。

关于“http://”的旁注

不要害怕此处涉及的参数字符串中的不安全的“http://”。不会发出 HTTP 请求,也不会损害 HTTPS 站点。事实上,如果您更改它,将会对您造成损害。Jim Coffey 在

如果您改为指定“https”,则大多数浏览器都能应对,但 IE 会失败。