IE11 上的 SVG 自然宽度
SVG naturalWidth on IE11
我正在尝试从 IE11 上的 SVG 图像获取自然宽度 属性。我可以在 Chrome、Firefox 和 Safari 上获得 naturalWidth 和 naturalHeight,但在 IE11 上它总是 returns 0.
Here is a simple Codepen that shows the issues and here 是调试视图,所以你可以在 IE11 上执行它(或者你可以 运行 下面的代码),你会看到在 IE11 上宽度是正确的,但 naturalWidth 总是0.
document.getElementById('mbutton').onclick = function() {
var divNatural = document.getElementById('natural-width');
divNatural.innerHTML = 'Natural Width: ' + document.getElementById('msvg').naturalWidth;
var divWidth = document.getElementById('width');
divWidth.innerHTML = 'Width: ' + document.getElementById('msvg').width;
}
<button id="mbutton">Get Width</button>
<div id="natural-width">0</div>
<div id="width">0</div>
<img id="msvg" src="https://upload.wikimedia.org/wikipedia/commons/6/6b/Bitmap_VS_SVG.svg">
所有与此相关的问题都指向不等待图像加载,这里不是这种情况,这是 IE11 中的已知问题吗?有什么解决方法吗?
感谢@Robert Longson,我最终从 SVG 文件中读取了尺寸。这不是一个完美且万无一失的实现,但可以很好地满足我的需求。这样我就可以在所有浏览器中获得 SVG 宽度和高度:
// Load SVG into an image
var svgImage = new Image();
svgImage.onload = function () {
// We need to attach the Image to the DOM temporarily so we can read its size on IE
svgImage.style.opacity = 0;
svgImage.style.position = 'fixed';
document.body.appendChild(svgImage);
// Save SVG width and height.
scope._svgHeight = svgImage.naturalHeight;
scope._svgWidth = svgImage.naturalWidth;
if (scope._svgHeight === 0 || scope._svgWidth === 0) {
// On IE, naturalWidth and naturalHeight are 0 so try parsing the SVG string
// and see if it has width and height attributes.
var parser = new DOMParser();
var doc = parser.parseFromString(value, "image/svg+xml");
if (doc && doc.firstChild && doc.firstChild.tagName === 'svg') {
// Try getting the SVG dimensions from the width/height attributes
var w = doc.firstChild.getAttribute('width');
var h = doc.firstChild.getAttribute('height');
var box = doc.firstChild.getAttribute('viewBox');
// This regex checks if we have any non valid characters in the width (we need the dimensions
// to only have 'px' or no unit at all)
var regex = /[^\d.px]/;
if (w && h && !regex.test(w) && !regex.test(h)) {
scope._svgWidth = parseFloat(w);
scope._svgHeight = parseFloat(h);
}
else if(box) {
// Try to use the viewbox
var dim = box.split(' ');
scope._svgWidth = parseFloat(dim[2]);
scope._svgHeight = parseFloat(dim[3]);
}
else {
// Fallback to width (won't work correctly in all cases)
scope._svgWidth = svgImage.width || svgImage.offsetWidth;
scope._svgHeight = svgImage.height || svgImage.offsetHeight;
}
}
// If SVG could not be parsed fallback to width (won't work correctly in all cases)
else {
scope._svgWidth = svgImage.width || svgImage.offsetWidth;
scope._svgHeight = svgImage.height || svgImage.offsetHeight;
}
}
document.body.removeChild(svgImage);
// At this point scope._svgHeight and scope._svgWidth have the width and height of the SVG
};
svgImage.src = 'data:image/svg+xml,' + encodeURIComponent(svgString);
我正在尝试从 IE11 上的 SVG 图像获取自然宽度 属性。我可以在 Chrome、Firefox 和 Safari 上获得 naturalWidth 和 naturalHeight,但在 IE11 上它总是 returns 0.
Here is a simple Codepen that shows the issues and here 是调试视图,所以你可以在 IE11 上执行它(或者你可以 运行 下面的代码),你会看到在 IE11 上宽度是正确的,但 naturalWidth 总是0.
document.getElementById('mbutton').onclick = function() {
var divNatural = document.getElementById('natural-width');
divNatural.innerHTML = 'Natural Width: ' + document.getElementById('msvg').naturalWidth;
var divWidth = document.getElementById('width');
divWidth.innerHTML = 'Width: ' + document.getElementById('msvg').width;
}
<button id="mbutton">Get Width</button>
<div id="natural-width">0</div>
<div id="width">0</div>
<img id="msvg" src="https://upload.wikimedia.org/wikipedia/commons/6/6b/Bitmap_VS_SVG.svg">
所有与此相关的问题都指向不等待图像加载,这里不是这种情况,这是 IE11 中的已知问题吗?有什么解决方法吗?
感谢@Robert Longson,我最终从 SVG 文件中读取了尺寸。这不是一个完美且万无一失的实现,但可以很好地满足我的需求。这样我就可以在所有浏览器中获得 SVG 宽度和高度:
// Load SVG into an image
var svgImage = new Image();
svgImage.onload = function () {
// We need to attach the Image to the DOM temporarily so we can read its size on IE
svgImage.style.opacity = 0;
svgImage.style.position = 'fixed';
document.body.appendChild(svgImage);
// Save SVG width and height.
scope._svgHeight = svgImage.naturalHeight;
scope._svgWidth = svgImage.naturalWidth;
if (scope._svgHeight === 0 || scope._svgWidth === 0) {
// On IE, naturalWidth and naturalHeight are 0 so try parsing the SVG string
// and see if it has width and height attributes.
var parser = new DOMParser();
var doc = parser.parseFromString(value, "image/svg+xml");
if (doc && doc.firstChild && doc.firstChild.tagName === 'svg') {
// Try getting the SVG dimensions from the width/height attributes
var w = doc.firstChild.getAttribute('width');
var h = doc.firstChild.getAttribute('height');
var box = doc.firstChild.getAttribute('viewBox');
// This regex checks if we have any non valid characters in the width (we need the dimensions
// to only have 'px' or no unit at all)
var regex = /[^\d.px]/;
if (w && h && !regex.test(w) && !regex.test(h)) {
scope._svgWidth = parseFloat(w);
scope._svgHeight = parseFloat(h);
}
else if(box) {
// Try to use the viewbox
var dim = box.split(' ');
scope._svgWidth = parseFloat(dim[2]);
scope._svgHeight = parseFloat(dim[3]);
}
else {
// Fallback to width (won't work correctly in all cases)
scope._svgWidth = svgImage.width || svgImage.offsetWidth;
scope._svgHeight = svgImage.height || svgImage.offsetHeight;
}
}
// If SVG could not be parsed fallback to width (won't work correctly in all cases)
else {
scope._svgWidth = svgImage.width || svgImage.offsetWidth;
scope._svgHeight = svgImage.height || svgImage.offsetHeight;
}
}
document.body.removeChild(svgImage);
// At this point scope._svgHeight and scope._svgWidth have the width and height of the SVG
};
svgImage.src = 'data:image/svg+xml,' + encodeURIComponent(svgString);