用JavaScript获取SVG图形的大小

10

在 HTML 页面中添加 SVG 图形,通常使用 object 标签将其包裹,如下所示:

<object id="svgid" data="mysvg.svg" type="image/svg+xml" 
  wmode="transparent" width="100" height="100">

this browser is not able to show SVG: <a linkindex="3"
href="http://getfirefox.com">http://getfirefox.com</a> 
is free and does it!
If you use Internet Explorer, you can also get a plugin: 
<a linkindex="4" href="http://www.adobe.com/svg/viewer/install/main.html">
http://www.adobe.com/svg/viewer/install/main.html</a>

</object>

如果在对象标签中不使用宽度和高度属性,则svg将以全尺寸显示。通常,我从Open Graphics Library获取svg文件进行测试。是否有通过JavaScript获取svg大小的方法?或者我应该只查看svg xml文件,从顶部的svg标签找出大小?

4个回答

10

请见http://dev.opera.com/articles/view/svg-evolution-not-revolution/?page=2

只要SVG文件在同一域中(否则这将是一种安全漏洞),就可以访问由HTML:object引用的SVG DOM。如果您的对象标签具有id="myobj",则可以执行以下操作:

var obj = document.getElementById("myobj"); // reference to the object tag
var svgdoc = obj.contentDocument; // reference to the SVG document
var svgelem = svgdoc.documentElement; // reference to the SVG element

然后,您可以通过以下方式访问SVG元素的宽度/高度:

svgelem.getAttribute("width")
svgelem.getAttribute("height")

请注意,这些属性可能是像“100px”,“300”,“200em”,“40mm”,“100%”这样的东西,因此您需要仔细解析它。


只是一个警告:这在Internet Explorer(10)上不起作用:obj.contentDocument未定义。 - David Wolever

5

> 有没有办法使用JavaScript获取svg的大小?

有和没有。

没有:

JavaScript无法访问浏览器中存储的SVG文件内容。

因此,页面包含任意SVG图像并让JavaScript从SVG文件本身中确定任何信息是不可能的。

JS只能访问页面DOM中包含的数据:原始标记以及对DOM进行的任何JS相关修改。您可以访问object元素的属性和后代节点,但这不会让您看到比您自己查看页面标记时更多的内容。

有:

在现代浏览器中,JS可以将任何XML字符串解析为DOM,然后使用基于DOM的方法访问内容。

您可以通过发出类似xmlHttpRequest的请求(即JS执行SVG文件URL上的HTTP GET请求)来获取SVG文件内容。然后,JS将拥有SVG文件的完整XML字符串,您可以随意访问任何内容。

> 或者我应该只查看svg xml文件,从顶部的svg标记中找出大小?

这将远远更可行。

唯一基于JS的解决方案需要JS对SVG文件的URL执行GET请求(如上所述),这可能不可行-每个页面加载可能导致每个SVG文件的双重下载,并且JS将SVG的XML解析为DOM可能过于耗费资源。

让JS检索SVG的XML内容并将其解析为DOM以仅检索图像尺寸有点过度。这是完全可能的,但通常不实用。

在服务器端查询SVG的XML内容,确定合适的宽度和高度,然后在返回标记给浏览器之前动态添加widthheight属性将是最好的选择。


如果是跨域引用的话,“no”部分才适用。请参考https://dev59.com/1nVC5IYBdhLWcg3woSpW#1577890。 - Erik Dahlström

1
ES6:使用async/await,您可以以类似于顺序的方式完成此操作。
async function getImage(url) {
    return new Promise((resolve, reject) => {
        let img = new Image();
        img.onload = () => resolve(img);
        img.onerror = reject;
        img.src = url;
    });
}

使用上述函数
let img = await getImage("yourimage.svg");
let w = img.width;
let h = img.height; 

只要SVG文件在同一域名下(详情请见此处),您就可以使用它。工作示例

async function getImage(url) {
  return new Promise((resolve, reject) => {
    let img = new Image();
    img.onload = () => resolve(img);
    img.onerror = reject;
    img.src = url;
  });
}

async function start() {
  // here is example url with embeded svg but you can use any url
  let svgURL = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='120' width='220'%3E%3Cellipse cx='110' cy='60' rx='100' ry='50' stroke='black' stroke-width='3' fill='red' /%3E%3C/svg%3E";
  
  let img = await getImage(svgURL);
  let w = img.width;
  let h = img.height; 
  
  // print
  console.log({w,h});
  pic.src = svgURL;
}

start();
<img id="pic">


这通常可以工作,但在IE11中返回宽度和高度为0 - Sam
要使其在IE11中工作,请使用此技术:https://dev59.com/tmEh5IYBdhLWcg3wGwCO#23256878 - Sam
请注意,如果未明确设置宽度/高度属性,则此代码在Firefox中无法正常工作。 - Crashalot
@Crashalot 我在 Firefox 中运行了上面的代码片段(截图),它返回了正确的尺寸(所以看起来它可以工作)- 也许问题是因为你的 SVG 内部没有包含原始尺寸(就像这个代码片段中的那个一样)? - Kamil Kiełczewski

-6
有没有方法可以使用 JavaScript 获取 SVG 的尺寸? 是的
var filesize = function(url, requestHandler) {
  var requestObj = new XMLHttpRequest();  
  requestObj.open('head', address, true);  
  requestObj.onreadystatechange = callback;
  requestObj.send(null);  
};

现在是一个处理函数:

var requestHandler = function(result) {
    if (this.readyState === 1) {
        this.abort();
    }
    return this.getResponseHeader("Content-length");
};

var size = fileSize("http://whatever.org/someSVGFile.svg", requestHandler);
alert(size); 

这应该可以顺利返回您的SVG或任何其他文件的文件大小。服务器配置可能是唯一可能会干扰的因素。


这里的“Size”指的是尺寸,而不是磁盘空间。 - Danny Beckett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接