内部框架中的SVG具有奇怪的不一致性问题 [英] SVGs inside iframes having strange inconsistency problems

查看:149
本文介绍了内部框架中的SVG具有奇怪的不一致性问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在iframe内部渲染一些SVG,并且我需要使用srcdoc属性来完成它。出于某种原因,我所做的一些事情导致SVG的某些属性无法正常显示。



在下面的屏幕截图中,iframe中的代码是相同的。





以下是重现此的代码:

 < svg height =150width = 300 > 
< defs>
< linearGradient id =grad1x1 =0%y1 =0%x2 =100%y2 =0%>
< stop offset =0%style =stop-color:rgb(255,255,0); stop-opacity:1/>
< / linearGradient>
< / defs>
< / svg>

< br>< br>

< iframe width =300height =150srcdoc ='< svg height =150width =300>
< defs>
< linearGradient id =grad1x1 =0%y1 =0%x2 =100%y2 =0%>
< stop offset =0%style =stop-color:rgb(255,255,0); stop-opacity:1/>
< / linearGradient>
< / defs>
< / svg>'>< / iframe>

它看起来好像和linearGradients或者urls有关,以及它们在这里的表现如何情况。



我最近在iframe和srcdocs上遇到了一些其他问题,我在SO上发布了这个问题,并得到了很好的回应:与常规网页呈现神秘不同的图片? - 这有助于解决很多不一致问题,但似乎并没有涉及到这一点。



我使用Chrome / Webkit。

解决方案

这似乎是iframe srcdoc 文档解析内部目标链接的不幸结果。

使用 srcdoc 应该被提供关于特殊基础URL :srcdoc 然而,在该文件中,用于解析外部链接或样式表的基本URL是父文档的URL 。这可能意味着ID应该在父DOM内而不是本地DOM中解析。但是这显然不会发生,因为在您的原始示例中,在父文档中存在具有该ID的有效渐变。现在,可能是跨源限制阻止来自单独文档的资源的结果,但是我没有在控制台上收到相应的错误。



当你开始将目标片段用于其他事情时,情况会变得非常糟糕(和跨浏览器不一致)。

在这个小提琴中,作为下面的代码片段转载,我使用目标片段


  • 引用两个文档中的渐变(一个用于笔画,一个用于填充; Chrome(v38)或Firefox(v33)都不算幸运(IE根本不支持srcdoc)。


  • 重复使用两个文档中的元素;既不是< use> 在FF中呈现,Chrome呈现在这种情况下,它会根据本地文档解析片段。


  • 定义超链接的目的地,在这种情况下, FF给我一个POST错误,但Chrome成功了完全导航到父文档中的目标 <注意:target 样式被应用)。当然,只有当父文档具有可导航的URL(即,保存的JS小提琴,而不是堆栈片段)时,该功能才有效。




所有这些都是说,这是规范中不确定性和实现中不一致的绝对混乱,我建议找到一种替代方案,例如使用数据URI作为 src 的iframe。请注意,这在IE中不起作用(它不支持iframe的数据URI),并且您需要对任何和<

iframe srcdoc 和网址片段测试案例



  ellipse:target {stroke:red;}  

 < svg height =150width =300> < DEFS> < linearGradient id =grad1> < stop offset =0style =stop-color:rgb(255,255,0); stop-opacity:1/> < stop offset =1style =stop-color:rgb(255,0,0); stop-opacity:1/> < /&的LinearGradient GT; < / DEFS> < ellipse id =parentEllipsecx =100cy =70rx =85ry =55fill =url(#grad1)/>< / svg>< br><< ; br>< iframe width =300height =150srcdoc ='< svg height =150width =300> < DEFS> < linearGradient id =grad2> < stop offset =0style =stop-color:rgb(255,255,0); stop-opacity:1/> < stop offset =1style =stop-color:rgb(255,0,0); stop-opacity:1/> < /&的LinearGradient GT; < / defs>< a xlink:href =#parentEllipse> < ellipse id =ellipsecx =100cy =70rx =85ry =55fill =url(#grad1)bluestroke =url(#grad2)green width =10px/>< / a> < use xlink:href =#ellipsey =50/> < use xlink:href =#parentEllipsex =50/>< / svg>'>< / iframe>  


I need to render some SVGs inside iframes, and I need to do it using the srcdoc attribute. For some reason, something about the way I'm doing it is causing certain attributes of the SVG to not display properly.

In the screenshot below, the code in the iframe is identical.

Here's the code to reproduce this:

<svg height="150" width="300">
  <defs>
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
  <ellipse cx="100" cy="70" rx="85" ry="55" fill="url(#grad1)" />
</svg>

<br><br>

<iframe width="300" height="150" srcdoc='<svg height="150" width="300">
  <defs>
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
  <ellipse cx="100" cy="70" rx="85" ry="55" fill="url(#grad1)" />
</svg>'></iframe>

It looks like it has something to do with linearGradients, or with urls, and how they behave in this situation.

I was recently having some other problems with iframes and srcdocs, and I posted this on SO, and got a good response: iframes rendering mysteriously differently from regular web pages? -- this helped with a lot of inconsistencies, but does not seem related to this one in particular.

I'm using Chrome/Webkit.

解决方案

This appears to be an unfortunate result of how iframe srcdoc documents resolve internal target links.

Documents created using srcdoc are supposed to be given the special base URL about:srcdoc.

However, within that document, the base URL for resolving external links or stylesheets is the parent document's URL. Which could mean that the ID should be resolved within the parent DOM instead of the local DOM. But that's clearly not happening, since in your original example there was a valid gradient with that ID in the parent document. Now, that could be a result of cross-origin restrictions blocking resources from a separate document, but I'm not getting corresponding errors on the console.

Things get really wonky (and cross-browser inconsistent) when you start using target fragments for other things.

In this fiddle, reproduced as a snippet below, I use target fragments to

  • Reference the gradients from both documents (one for stroke and one for fill; neither luck in either Chrome (v38) or Firefox (v33) (IE doesn't support srcdoc at all).

  • Re-use elements from both documents; neither <use> renders in FF, Chrome renders the local ellipse re-use, indicating in this case it resolves the fragment according to the local document.

  • Define the destination of a hyperlink. In this case, FF gives me a POST error, but Chrome successfully navigates to the target in the parent document (note that the :target styles get applied). Of course, that only works if the parent document has a navigable URL (i.e., a saved JS Fiddle, but not a stack snippet).

All of which is to say that, this is an absolute mess of ambiguity in the specs and inconsistency in the implementations, and I would recommend finding an alternative, such as using a data URI as the src of the iframe. Be aware that this still won't work in IE (which doesn't support data URIs for iframes), and that you'll need to URL-encode any # and % characters within the document.

iframe srcdoc and URL fragments test case

ellipse:target {
    stroke:red;
}

<svg height="150" width="300">
  <defs>
    <linearGradient id="grad1" >
      <stop offset="0" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="1" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
  <ellipse id="parentEllipse" cx="100" cy="70" rx="85" ry="55" fill="url(#grad1)" />
</svg>

<br><br>

<iframe width="300" height="150" srcdoc='<svg height="150" width="300">
  <defs>
    <linearGradient id="grad2" >
      <stop offset="0" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="1" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
<a xlink:href="#parentEllipse">
  <ellipse id="ellipse" cx="100" cy="70" rx="85" ry="55" fill="url(#grad1) blue"  stroke="url(#grad2) green" stroke-width="10px" /></a>
  <use xlink:href="#ellipse" y="50"/>
  <use xlink:href="#parentEllipse" x="50" />
</svg>'></iframe>

这篇关于内部框架中的SVG具有奇怪的不一致性问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆