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);