SVG 精灵在 Safari 中不起作用
SVG sprite not work in Safari
对于 Web 开发人员来说,Safari 并不比 IE 好。这是我在 Safari 中看到的问题。
我正在尝试使用 SVG 精灵在我的网页中加载产品图标。
HTML代码:
<img src="https://www.abc123.com/icon_sprite.svg#amex">
SVG Sprite 代码:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="276" height="224" viewBox="0 0 276 224" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<view id="affiliate-programs" viewBox="148 0 32 32"/>
<svg width="32" height="32" viewBox="0 0 32 32" x="148"><path .../></svg>
<view id="alipay" viewBox="0 64 49 32"/>
<svg width="49" height="32" viewBox="0 0 49 32" y="64"><path .../></svg>
<view id="amex" viewBox="50 0 49 32"/>
<svg width="49" height="32" viewBox="0 0 49 32" x="50"><path .../></svg>
<view id="auction" viewBox="148 64 32 32"/>
<svg width="32" height="32" viewBox="0 0 32 32" x="148" y="64"><path .../></svg>
<view id="backorder-domain-service" viewBox="180 128 32 32"/>
<svg width="32" height="32" viewBox="0 0 32 32" x="180" y="128"><path .../></svg>
...
...
</svg>
HTML中的<img>
通过在精灵url中附加“#”+<view>
的id来定位<svg>
。这种方式适用于 Chrome、Firefox,甚至 IE,但不适用于 Safari。
在Chrome中的样子:
以及它在 Safari 5 和 Safari 9 中的外观:
所以基本上就是说<img>
中附加的#viewId
无法通过ID识别视图,这是不可接受的。
不知道有没有人看过类似的案例可以帮帮我。
顺便说一句,我也尝试了另一种解决方案。
<object data="https://www.abc123.com/icon_sprite.svg#amex" type="image/svg+xml"></object>
此解决方案显示精灵的正确 svg,但是它会先消失然后在 AJAX 调用期间重新出现,这也不是很好的用户体验。
我自己在这里回答了我自己的大部分问题。不知道是开心的事还是伤心的事
我在发布到这里后的第二天就想出了如何解决这个问题。
根据https://www.broken-links.com/2012/08/14/better-svg-sprites-with-fragment-identifiers/,Safari在Version 7中只支持xxx.svg#<viewboxId>
这样的fragment identifier,其他版本不支持,我已经在Sauce Labs确认过。它是比 IE 更糟糕的浏览器。
好了,不抱怨了。说说解决方法吧,这是最重要的。
片段标识符 xxx.svg#<viewboxId>
确实在大多数 Safari 中不起作用。它发生在 <img>
,但不会发生在 <embed>
。所以对于Safari,我们可以使用<embed>
来加载片段标识符。
如何区分浏览器:
function isSafari() {
if (navigator && navigator.userAgent) {
var userAgent = navigator.userAgent;
var isChrome = userAgent.indexOf('Chrome') > -1;
var isSafari = userAgent.indexOf('Safari') > -1;
if ((isChrome) && (isSafari)) {
isSafari = false;
}
return isSafari;
}
return false;
}
在 Safari 中:
<embed id="embedSvg" class="pi_svg" src="https://www.abc123.com/icon_sprite.svg#amex" type="image/svg+xml"></embed>
在非 Safari 中:
<img class="pi_svg" src="https://www.abc123.com/icon_sprite.svg#amex">
对于 Web 开发人员来说,Safari 并不比 IE 好。这是我在 Safari 中看到的问题。
我正在尝试使用 SVG 精灵在我的网页中加载产品图标。
HTML代码:
<img src="https://www.abc123.com/icon_sprite.svg#amex">
SVG Sprite 代码:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="276" height="224" viewBox="0 0 276 224" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<view id="affiliate-programs" viewBox="148 0 32 32"/>
<svg width="32" height="32" viewBox="0 0 32 32" x="148"><path .../></svg>
<view id="alipay" viewBox="0 64 49 32"/>
<svg width="49" height="32" viewBox="0 0 49 32" y="64"><path .../></svg>
<view id="amex" viewBox="50 0 49 32"/>
<svg width="49" height="32" viewBox="0 0 49 32" x="50"><path .../></svg>
<view id="auction" viewBox="148 64 32 32"/>
<svg width="32" height="32" viewBox="0 0 32 32" x="148" y="64"><path .../></svg>
<view id="backorder-domain-service" viewBox="180 128 32 32"/>
<svg width="32" height="32" viewBox="0 0 32 32" x="180" y="128"><path .../></svg>
...
...
</svg>
HTML中的<img>
通过在精灵url中附加“#”+<view>
的id来定位<svg>
。这种方式适用于 Chrome、Firefox,甚至 IE,但不适用于 Safari。
在Chrome中的样子:
以及它在 Safari 5 和 Safari 9 中的外观:
所以基本上就是说<img>
中附加的#viewId
无法通过ID识别视图,这是不可接受的。
不知道有没有人看过类似的案例可以帮帮我。
顺便说一句,我也尝试了另一种解决方案。
<object data="https://www.abc123.com/icon_sprite.svg#amex" type="image/svg+xml"></object>
此解决方案显示精灵的正确 svg,但是它会先消失然后在 AJAX 调用期间重新出现,这也不是很好的用户体验。
我自己在这里回答了我自己的大部分问题。不知道是开心的事还是伤心的事
我在发布到这里后的第二天就想出了如何解决这个问题。
根据https://www.broken-links.com/2012/08/14/better-svg-sprites-with-fragment-identifiers/,Safari在Version 7中只支持xxx.svg#<viewboxId>
这样的fragment identifier,其他版本不支持,我已经在Sauce Labs确认过。它是比 IE 更糟糕的浏览器。
好了,不抱怨了。说说解决方法吧,这是最重要的。
片段标识符 xxx.svg#<viewboxId>
确实在大多数 Safari 中不起作用。它发生在 <img>
,但不会发生在 <embed>
。所以对于Safari,我们可以使用<embed>
来加载片段标识符。
如何区分浏览器:
function isSafari() {
if (navigator && navigator.userAgent) {
var userAgent = navigator.userAgent;
var isChrome = userAgent.indexOf('Chrome') > -1;
var isSafari = userAgent.indexOf('Safari') > -1;
if ((isChrome) && (isSafari)) {
isSafari = false;
}
return isSafari;
}
return false;
}
在 Safari 中:
<embed id="embedSvg" class="pi_svg" src="https://www.abc123.com/icon_sprite.svg#amex" type="image/svg+xml"></embed>
在非 Safari 中:
<img class="pi_svg" src="https://www.abc123.com/icon_sprite.svg#amex">