不支持 Javascript/SVG 的 SVG 注入回退
Fallback for SVG injection with no Javascript/SVG support
我们正在考虑使用 Iconfu SVGInject 将 SVG 文件注入我们的 HTML 文件。由于某种原因,我们的一个项目仍然需要对 IE8 的支持(不要问),所以我不得不用非常旧的浏览器来测试它。
SVGInject 文档中有一个 fallback example 不支持 SVG,它看起来像这样(我添加的图像尺寸):
<html>
<head>
<script src="svg-inject.min.js"></script>
</head>
<body>
<img src="image.svg" width="128" height="128" onload="SVGInject(this)" onerror="SVGInject.err(this, 'image.png')" />
</body>
</html>
虽然回退适用于 IE8 的标准配置,但我发现如果浏览器既不支持 SVG 也不支持 Javascript(例如禁用 Javascript 的 IE8),则没有回退的情况.
以下是在不同情况下显示的内容:
现代浏览器(Chrome、Firefox、Webkit)
SVG 作为内联 SVG 注入,完全可设置样式
现代浏览器,Javascript 禁用
SVG 显示为 <img>
,不可设置样式
Internet Explorer 8
显示后备 PNG
Internet Explorer 8,Javascript 禁用
显示损坏的图像
最后一个场景没有显示图像的原因是永远不会触发 onerror,因此无法设置 fallback source 属性。
我想知道即使在 SVG 和 Javascript 支持都不可用的情况下,是否有办法(或 hack)显示后备图像。
注意:这更多是一个理论问题。虽然该项目需要 IE8 支持,但我认为这是一些遗留需求,因为需求是在 2010 年编写的。
实际上有一种方法可以做到这一点,但并不完美,因为它对 Internet Explorer 9、10 和 11 的性能有影响。
这里是没有 Javascript 和没有 SVG 支持的完全回退的实现:
<html>
<head>
<script src="svg-inject.min.js"></script>
<script>
// Wrapper for SVGInject that does a little preprocessing
SVGInject2 = function(img, options) {
if (typeof SVGRect != 'undefined') { // check if SVG is supported
// replace src with srcset if srcset is provided
var srcset = img.srcset;
if (srcset) {
img.src = srcset;
}
SVGInject(img, options);
}
}
</script>
</head>
<body>
<img src="image.png" srcset="image.svg" width="128" height="128" onload="SVGInject2(this)" />
</body>
</html>
它是如何工作的?
如您所知,HTML <img>
元素有一个 srcset
属性,如果提供,该属性优先于 src
属性。 srcset
常青浏览器(Chrome、Firefox 等)支持,但 Internet Explorer(所有版本)不支持。
如果 Javascript 被禁用,src
属性中指定的 PNG 将显示在 Internet Explorer 上。在现代浏览器上,将使用 SVG 的 srcset
属性和 URL。
如果启用Javascript,函数SVGInject2()
会在图像加载后调用。这将检查浏览器是否支持 SVG。如果未检测到 SVG 支持,则它不执行任何操作。这应该只发生在 IE8 和更早的版本上,它将显示 PNG,就像 Javascript 被禁用一样。如果检测到 SVG 支持,src
属性的值将替换为 srcset
属性的值,并调用 SVGInject()
函数。这将通过 XHR 加载 SVG(使用 src
属性中的 URL)并用加载的 SVG 替换 <img>
元素。在大多数情况下,浏览器已将 SVG 缓存在缓存中(从初始加载开始),因此 SVG 仅通过网络传输一次。
但是,对 Internet Explorer 9、10 和 11 的性能有负面影响。在这些浏览器上,无论如何都会加载 PNG,因为 srcset
不受支持。如果注入 SVG,则不使用 PNG,这意味着 PNG 传输是不必要的。在其他浏览器上,使用此后备方法应该不会对性能产生影响。
免责声明:我是 SVGInject 的作者之一。
我们正在考虑使用 Iconfu SVGInject 将 SVG 文件注入我们的 HTML 文件。由于某种原因,我们的一个项目仍然需要对 IE8 的支持(不要问),所以我不得不用非常旧的浏览器来测试它。
SVGInject 文档中有一个 fallback example 不支持 SVG,它看起来像这样(我添加的图像尺寸):
<html>
<head>
<script src="svg-inject.min.js"></script>
</head>
<body>
<img src="image.svg" width="128" height="128" onload="SVGInject(this)" onerror="SVGInject.err(this, 'image.png')" />
</body>
</html>
虽然回退适用于 IE8 的标准配置,但我发现如果浏览器既不支持 SVG 也不支持 Javascript(例如禁用 Javascript 的 IE8),则没有回退的情况.
以下是在不同情况下显示的内容:
现代浏览器(Chrome、Firefox、Webkit)
SVG 作为内联 SVG 注入,完全可设置样式
现代浏览器,Javascript 禁用
SVG 显示为 <img>
,不可设置样式
Internet Explorer 8
显示后备 PNG
Internet Explorer 8,Javascript 禁用
显示损坏的图像
最后一个场景没有显示图像的原因是永远不会触发 onerror,因此无法设置 fallback source 属性。
我想知道即使在 SVG 和 Javascript 支持都不可用的情况下,是否有办法(或 hack)显示后备图像。
注意:这更多是一个理论问题。虽然该项目需要 IE8 支持,但我认为这是一些遗留需求,因为需求是在 2010 年编写的。
实际上有一种方法可以做到这一点,但并不完美,因为它对 Internet Explorer 9、10 和 11 的性能有影响。
这里是没有 Javascript 和没有 SVG 支持的完全回退的实现:
<html>
<head>
<script src="svg-inject.min.js"></script>
<script>
// Wrapper for SVGInject that does a little preprocessing
SVGInject2 = function(img, options) {
if (typeof SVGRect != 'undefined') { // check if SVG is supported
// replace src with srcset if srcset is provided
var srcset = img.srcset;
if (srcset) {
img.src = srcset;
}
SVGInject(img, options);
}
}
</script>
</head>
<body>
<img src="image.png" srcset="image.svg" width="128" height="128" onload="SVGInject2(this)" />
</body>
</html>
它是如何工作的?
如您所知,HTML <img>
元素有一个 srcset
属性,如果提供,该属性优先于 src
属性。 srcset
常青浏览器(Chrome、Firefox 等)支持,但 Internet Explorer(所有版本)不支持。
如果 Javascript 被禁用,src
属性中指定的 PNG 将显示在 Internet Explorer 上。在现代浏览器上,将使用 SVG 的 srcset
属性和 URL。
如果启用Javascript,函数SVGInject2()
会在图像加载后调用。这将检查浏览器是否支持 SVG。如果未检测到 SVG 支持,则它不执行任何操作。这应该只发生在 IE8 和更早的版本上,它将显示 PNG,就像 Javascript 被禁用一样。如果检测到 SVG 支持,src
属性的值将替换为 srcset
属性的值,并调用 SVGInject()
函数。这将通过 XHR 加载 SVG(使用 src
属性中的 URL)并用加载的 SVG 替换 <img>
元素。在大多数情况下,浏览器已将 SVG 缓存在缓存中(从初始加载开始),因此 SVG 仅通过网络传输一次。
但是,对 Internet Explorer 9、10 和 11 的性能有负面影响。在这些浏览器上,无论如何都会加载 PNG,因为 srcset
不受支持。如果注入 SVG,则不使用 PNG,这意味着 PNG 传输是不必要的。在其他浏览器上,使用此后备方法应该不会对性能产生影响。
免责声明:我是 SVGInject 的作者之一。