嵌套svg的D3.js缩放会中断Internet Explorer中的视口 [英] D3.js zoom with nested svg breaks viewport in Internet Explorer

查看:90
本文介绍了嵌套svg的D3.js缩放会中断Internet Explorer中的视口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用d3.js动态设置嵌套的svg,即嵌套在封闭的svg内的内部svg. d3.behavior.zoom()监听外部的缩放事件svg并执行所需的转换.

I am using d3.js to dynamically set up a nested svg, i.e. an inner svg nested inside an enclosing svg. A d3.behavior.zoom() listens for zoom events on the outer svg and does the transformations needed.

除Internet Explorer(IE 11)以外,其他所有功能都可以正常运行,Internet Explorer(IE 11)似乎在涉及内部svg的转换中存在问题. Firefox和Chrome的行为均符合预期,将内部svg剪切到外部svg的视口中.但是,在Internet Explorer中,放大正确地应用了转换,但似乎忽略了封闭的svg的尺寸.内部svg的内容最终将显示在外部svg的外部以及其他主体元素的上方.外部svg的视口似乎对内部svg没有修剪效果.

All works fine except for the Internet Explorer (IE 11) which seems to have an issue with transformations involving inner svgs. Both Firefox and Chrome behave as expected clipping the inner svg to the viewport of the outer svg. In Internet Explorer, however, zooming in correctly applies transformations but seems to ignore the dimensions of the enclosing svg. The contents of the inner svg will eventually be displayed outside of the outer svg and above other body elements. The viewport of the outer svg seems to have no clipping effect on the inner svg.

我已经设置了 JSFiddle 来演示行为.

I have set up a JSFiddle demonstrating the behaviour.

var zoom = d3.behavior.zoom()
    .on("zoom", function () {
        container.attr("transform",
            "translate(" + d3.event.translate + ") " +
            "scale(" + d3.event.scale + ")");
    });

var container = d3.select("body")
                    .append("svg")
                      .attr("id", "svgcontainer")
                      .attr("width", 300)
                      .attr("height", 300)
                      .style("background-color", "#aaaaee")
                      .call(zoom)
                    .append("g");

var svg = container.append("svg")
                     .attr("width", 200)
                     .attr("height", 200)
                     .attr("x", 50)
                     .attr("y", 50);

svg.append("svg:circle")
     .style("fill", "none")
     .style("stroke", "red")
     .style("stroke-width", "2px")
     .attr("cx", 100)
     .attr("cy", 100)
     .attr("r", 50);

我错过了什么吗?有跨浏览器的解决方法吗?

Am I missing something? Is there any cross-browser workaround?

推荐答案

很抱歉,当您第一次发布该问题时,这个问题没有引起足够的重视:这实际上是一个简单的解决方法.只需将外部SVG上的overflow属性设置为hidden.

I'm sorry this question didn't get enough attention when you first posted it: it's actually a simple fix. Just set the overflow property on the outer SVG to hidden.

那么为什么您的代码可以在其他浏览器上正常工作?

So why does your code work as you intend on the other browsers?

这是因为它们默认情况下设置了此属性. CSS中overflow的初始值为visible,但是 SVG规范要求任何具有viewBox属性的元素在浏览器的默认样式表中均具有overflow:hidden,对于根SVG元素,其 except 除外.其他浏览器将这种异常解释为仅适用于作为 .svg 文档根目录的<svg>元素. Internet Explorer还应用将HTML文档中的顶级内联SVG视为根目录(因此具有overflow: visible).

It's because they set this property by default. The initial value for overflow in CSS is visible, but the SVG specs require that any element that can take a viewBox attribute has overflow:hidden in the browser's default stylesheet, except for the root SVG element. The other browsers interpret this exception as if it only applied to an <svg> element that is the root of an .svg document. Internet Explorer also applies treats the top-level inline SVG in an HTML document as if was a root (and therefore had overflow: visible).

以下代码段演示了不同的行为.它在嵌入式SVG内的嵌套SVG内使用一个圆圈.该圆形对于嵌套的SVG太大,因此,如果嵌套SVG上隐藏了溢出(所有浏览器默认情况下),则该圆形将被裁剪为一个正方形.嵌套的SVG偏移,部分在外部SVG外部.如果外部SVG上隐藏了溢出,则嵌套的SVG将被裁剪为一个矩形;否则,SVG将被裁剪为一个矩形.如果可见溢出,您会看到方形框粘在框架外面.

The following snippet demonstrates the different behaviors. It uses a circle inside a nested SVG inside an inline SVG. The circle is too big for the nested SVG, so if overflow is hidden on the nested SVG (as it is by default in all browsers) the circle will be cropped to a square. The nested SVG is offset, partly outside the outer SVG. If overflow is hidden on the outer SVG, the nested SVG will be cropped to a rectangle; if overflow is visible you'll see the square sticking outside of the frame.

第一个SVG在外部SVG上使用默认溢出(对于IE不同),而其他SVG则显式设置overflow: hiddenoverflow: visible.

The first SVG uses default overflow on the outer SVG (different for IE) while the others explicitly set overflow: hidden or overflow: visible.

svg {
    border: solid gray;
    height: 100px;
    width: 100px;
    margin: 50px;
}
circle {
    fill: royalBlue;
}

<svg>
    <svg x="-50" y="-50" width="100" height="100" >
        <circle r="100" cx="50" cy="50"/>
    </svg>
</svg>
<svg style="overflow: hidden">
    <svg x="-50" y="-50" width="100" height="100" >
        <circle r="100" cx="50" cy="50"/>
    </svg>
</svg>
<svg style="overflow: visible">
    <svg x="-50" y="-50" width="100" height="100" >
        <circle r="100" cx="50" cy="50"/>
    </svg>
</svg>

对于 SVG 2

The overflow behavior should probably be clarified for SVG 2 or in the SVG integration spec. There is also a discrepancy between Firefox and Blink/Webkit browsers regarding whether or not padding on an inline SVG is considered "overflow" or not.

这篇关于嵌套svg的D3.js缩放会中断Internet Explorer中的视口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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