计算HTML页面中SVG元素的大小

时间:2014-05-15 17:18:31

标签: html firefox svg

如何可靠地询问SVG元素在主页上占用的大小(以像素为单位)?

  • {vl。{/ 1}}和svg.offsetWidth都适用于Chrome v34。
  • 这些都不能在Firefox v29中正常运行。 (前者为空,后者返回不正确的值。)

测试页面:http://jsfiddle.net/dL5pZ/3/

这个问题的动机是为this answer获得可靠的实现,这需要知道元素外部的宽高比。此外,对于this question我需要知道SVG的实际大小,或者至少在不同的调用和调整大小元素之间返回比例值的东西。

6 个答案:

答案 0 :(得分:7)

我以前一直在那条路上。不幸的是,获取<svg>元素大小的大多数函数在Firefox中都是错误的。我找到的唯一可行解决方案是使用window.getComputedStyle(svgElement).width(或height),需要对其进行解析(并且仅在svgElement.display ==&#39; block&#39;时才有效,它是在你的例子中)。 我已经采用你的小提琴在Firefox中工作:http://jsfiddle.net/dL5pZ/5/

更新:显示&#39;内联&#39;的问题{29}围绕Firefox 29。

更新2:如上所述was fixed some time agogetBoundingClientRect现在也应该有效。

答案 1 :(得分:3)

我的研究得到了更多信息,因为我在过去的两天里一直在研究这个问题。

所以,它总是适用于Chrome和Opera,如果添加preserveAspectRatio="xMinYMin slice",它可以在IE中运行,但Firefox似乎有问题。

要使其跨平台工作,请尝试: a)直接访问SVG的宽度和高度 - Ch,O,IE b)getComputedStyle:

var style = window.getComputedStyle(svg, null);
var svgWidth = style.getPropertyValue("width").slice(0, -2);  // "1240px" -> "1240"

请记住,对于单个查询,它很好,但是当你尝试每秒执行大约60次时,浏览器变得很慢 c)我们知道这个问题发生在我们

<div><svg style="width:100%; height:100%"></svg></div>

并且Firefox中SVG元素的宽度和高度为1 ..但这些尺寸与您可以访问的div父元素的尺寸相同!但为了让生活更艰难,它在IE中无法发挥作用。

如此谦虚,这是我最后的跨浏览器代码:

if(!svg.width.baseVal.value || svg.width.baseVal.value < 2){
  //this is the FF case
  if(!this.parentElement) return;
  this.width = this.parentElement.clientWidth;
  this.height = this.parentNode.clientHeight;
}
else{
  //this works for Ch,O,IE
  this.width = svg.width.baseVal.value;
  this.height = svg.height.baseVal.value
}

答案 2 :(得分:2)

getBoundingClientRect已经在版本33之后在Firefox中得到修复,并且可以按照您的需要进行操作。有关详细信息,请参阅bug 530985

答案 3 :(得分:1)

这是我修复它的方式:

var heightComponents = ['height', 'paddingTop', 'paddingBottom', 'borderTopWidth', 'borderBottomWidth'],
    widthComponents = ['width', 'paddingLeft', 'paddingRight', 'borderLeftWidth', 'borderRightWidth'];

var svgCalculateSize = function (el) {

    var gCS = window.getComputedStyle(el), // using gCS because IE8- has no support for svg anyway
        bounds = {
            width: 0,
            height: 0
        };

    heightComponents.forEach(function (css) { 
        bounds.height += parseFloat(gCS[css]);
    });
    widthComponents.forEach(function (css) {
        bounds.width += parseFloat(gCS[css]);
    });
    return bounds;
};

使用您的jsFiddle:http://jsfiddle.net/dL5pZ/7/

答案 4 :(得分:0)

这是我最终使用的:

var svgWidth = svg.clientWidth || window.getComputedStyle(svg).width.slice(0, -2),
    svgHeight = svg.clientHeight || window.getComputedStyle(svg).height.slice(0, -2);

因为clientWidth和clientHeight在Firefox中总是返回0。

对于d3用户:

var svg = d3.select('#yoursvg')[0][0],
    svgWidth = svg.clientWidth || window.getComputedStyle(svg).width.slice(0, -2),
    svgHeight = svg.clientHeight || window.getComputedStyle(svg).height.slice(0, -2);

希望它有所帮助。

答案 5 :(得分:0)

<button onclick="demosvg()">click on</button>

<svg>       
  //<image xlink:href="demo.jpg" id="img1" height="200" width="200"/>    
  <img id="myImg" src="demo.jpg" style="width:500px;height:98px;">
</svg>

<div id="demo"></div>


<script>
function demosvg() {
    var var1 = document.getElementById("img1").naturalWidth;
    document.getElementById("demo").innerHTML = "width is: " + var1+ " pixels";


}
</script>