浏览器对 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 会失败。
感谢发布此信息,Chris!几周前我遇到了同样的问题。您可能已经看到,Safari 5.1 中的 SVG 会计算出非常高的高度,因此您会得到非常高的 SVG 图像。
我的临时解决方案是查看高度,如果它非常高,则回退到 png。
很高兴看到这将进入 Modernizr!
Ryan:我不能确定,但您遇到的问题可能与以下问题相同: https://twitter.com/zachleat/status/251446429418127360
一个更简单的解决方法是使用 max-height: 100%;
我在 Safari 5.1 中也有完全相同的体验。max-height 技巧对我不起作用,尽管 img(svg 容器)变得稍微短了一些。宽度工作正常。
我从侧边栏找到了这个 jQuery 插件,它似乎非常强大,我正在考虑在我的网站上使用它: http://svgmagic.bitlabs.nl/
是的,这很不错,因为回退是为您创建的,而不是您自己处理。但它通过在不支持浏览器的每个页面加载时向其服务器发出 Ajax 调用来实现此目的,因此请注意这一点。
就其价值而言,此类功能测试称为“弱推断”。旧的功能测试有其缺点(异步等),但它更强大。
我 专门提出了这一点——但团队认为值得使测试同步。我同意,因为 hasFeature 很可能永远返回 true,并且浏览器将永远以这种方式支持 SVG,所以它可能永远不会出错。
我一周前在浏览 Rafael.js 源代码 时第一次发现了
document.implementation.hasFeature
。即使您不使用 Rafael 创建 SVG,它也是了解如何在旧版浏览器中使用 SVG 的极好的参考。document.implementation.hasFeature
最近在我的雷达上出现,当时我正在寻找一种解决方法,以解决 Modernizr.touch 在 Windows 8 上的 Chrome 或 Firefox 中返回 true,即使设备上没有触摸屏的问题。这段代码,在我能够测试的范围内,似乎有助于很好地确定设备是否仅限于触摸操作document.implementation && document.implementation.hasFeature('MouseEvent', '3.0')===false
我在 SVG 徽标方面遇到了另一个问题。
在我的 Windows 电脑上,SVG 徽标在 Safari 浏览器中工作正常,但是当我将其上传到服务器后,SVG 徽标在 Safari 浏览器中无法加载。
有人有解决方案吗?……
如果您的 Web 服务器使用的是 Microsoft IIS,则它可能缺少 SVG 文件的 MIME 类型—— http://www.iis.net/learn/manage/managing-your-configuration-settings/adding-ie-9-mime-types-to-iis
在 HTML 邮件中使用 SVG 图像时要小心。在我花费数天时间将我的电子邮件模板转换为更符合响应式电子邮件客户端的格式并使用 svg 图像作为我的徽标和社交媒体标题图像后,看来 Gmail 的图像代理没有计划支持 svg 图像。如果有人有相反的信息,请分享。
http://stackoverflow.com/questions/20815613/svg-images-blocked-by-gmail-proxy?lq=1