以元素形式插入SVG不生效,字符串形式却可行?求原因
这个问题的核心其实是SVG元素的命名空间不匹配,我来给你拆解一下:
当你用document.createElement('svg')创建元素时,默认是在HTML命名空间(http://www.w3.org/1999/xhtml)下生成的标签,但SVG的内部元素(比如<symbol>、<circle>)都属于SVG专属命名空间(http://www.w3.org/2000/svg)。你直接给这个HTML命名空间的<svg>设置innerHTML插入symbol字符串,浏览器不会自动把里面的元素转换成SVG命名空间的节点——这些<symbol>本质上是HTML命名空间下的“陌生标签”,自然无法被<use>元素正确识别和引用。
而蓝色圆圈的写法中,通过div.innerHTML插入完整的SVG字符串时,浏览器会自动识别<svg>标签,并在SVG命名空间下解析其内部所有元素,所以<symbol id="circle-blue">是有效的SVG节点,能被<use>正常调用。
创建SVG元素时,必须使用带命名空间的创建方法:document.createElementNS(),明确指定SVG的命名空间地址。这样生成的<svg>元素属于正确的SVG命名空间,其内部通过innerHTML插入的<symbol>也会被解析为合法的SVG节点。
修改后的示例代码:
var sprites = document.getElementById('sprites'); var circles = [ '<symbol id="circle-yellow"><circle cx="25" cy="25" r="20" fill="yellow" /></symbol>', '<symbol id="circle-blue"><circle cx="25" cy="25" r="20" fill="blue" /></symbol>' ]; // 正确创建SVG元素:指定SVG命名空间 var yellowDiv = document.createElement('div'); // 使用createElementNS创建SVG命名空间下的svg元素 var yellow = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); yellow.innerHTML = circles[0]; yellowDiv.appendChild(yellow); sprites.appendChild(yellowDiv); // 蓝色圆圈的原有写法可以保留 var blueDiv = document.createElement('div'); blueDiv.innerHTML = '<svg>' + circles[1] + '</svg>'; sprites.appendChild(blueDiv);
你注意到的“黄色圆圈对应的<svg>元素的默认渲染尺寸(浏览器对未知HTML标签的默认处理),但因为父元素#sprites设置了display: none,它并不会显示在页面上——真正导致图标无法显示的核心问题还是命名空间不匹配,和这个盒子尺寸无关。
内容的提问来源于stack exchange,提问作者crenshaw-dev

