• WebKit策略:<foreignObject>可用于绘制svg中的html标签,但与<use>搭配不生效


      在里面可以利用绘制html标签,原本是我在iconfont采用Font class方式引入svg的无奈之举。

      起初的设计是所有icon先在中先渲染,以达到icon复用的效果,icon采用Symbol方式引入svg感觉也是比较合适的,比较规范的。

    复制代码
    
    
    
    复制代码

      然后再需要用到的地方用克隆下来,感觉很完美。

      但是理想很丰满,现实很骨感。由于某些功能会被影响到,不能使用Symbol方式引入,最后只能选择Font class引入svg。于是代码变为了下列

    复制代码
    
    
    
    复制代码

      但是在需要的地方使用克隆下来,会发现在谷歌浏览器上却完全显示不出标签的内容,即不显示iconfont图标。

      刚开始,我以为是不能在标签中使用标签,于是我就去查看了SVG规范,传送门:https://www.w3.org/TR/SVG/struct.html#DefsElement,SVG规范是支持这种写法的。打开F12,查看标签下的dom结构,也可以看到标签其实是有生成的,也是佐证了这一点。

      但是查看引用标签的地方,就没有生成对应的标签,我查看SVG规范文档并没有提到标签不能与标签共同使用的限制。最后我打开了github,在w3c的【SVG工作组规范】项目下寻找答案,传送门:https://github.com/w3c/svgwg,最后找到了一个讨论:https://github.com/w3c/svgwg/issues/511。这位程序员在讨论中说除了 Gecko 之外的所有浏览器都限制元素中的,他在思考为什么Gecko之类的浏览器允许这么做。

       这下就有点头绪了,原来是浏览器内核原因。那简单,我们找个Gecko内核的浏览器验证下就知道了,Gecko内核最出名的就是FireFox浏览器(火狐浏览器)了。其实我的电脑也装了火狐浏览器,但是由于我开发一直用的是谷歌浏览器,确实也是好久好久没打开火狐了,放着吃灰,这次也确实没想到可能是浏览器本身的问题。打开火狐浏览器,果然能显示标签的内容,即显示了iconfont图标。

      不过为什么会出现这样的情况呢,另一个叫Dirk Schulze的程序员表示:出于复杂性的原因,WebKit不允许引用foreignObject。 我们没有时间查看所有影响(包括安全影响),如果内容是基于HTML的,那么对foreignObject的支持永远不会很好。(Blink修复了后半部分)

      也就是说Blink内核修复了后半段,使浏览器更好的支持了标签,但是对于引用标签的情况,还是没有任何进展。那也就是说谷歌浏览器现在是支持的标签的,只是不支持被标签引用。

      最后直接弃用,在需要的地方直接渲染。简单粗暴,最有效。

    
      

      虽然不够优雅,但是真香。

      事情原本到这就应该结束了,但是我还是不死心,不知道为什么WebKit要做这样的一个策略。最后,功夫不负有心人,我在Bugzilla又找到了一个提交给WebKit的bug:https://bugs.webkit.org/show_bug.cgi?id=91515。底下有一名名为Nikolas Zimmermann的程序员对此进行了回应:

       原文大意是:

        是的。由于与foreignObject相关的潜在问题,我们故意禁止它。它需要经过充分测试,仅此而已。

        当启用它时,我们需要注意新类型的循环引用,这就是它变得棘手的地方。

        foo.svg,包含