JS动态插入SVG到HTML出现本地前缀或XML对象问题
问题根源
- 错误使用Image对象存储SVG原始字符串:
Image的src属性仅接受合法的资源URL(本地路径/远程地址/Data URI),你直接传入SVG原始字符串时,浏览器会默认将其识别为相对路径,自动拼接http://localhost前缀,导致内容完全失效。 - DOMParser解析后取值错误:
DOMParser.parseFromString返回的是完整XML文档对象,不能直接赋值给innerHTML,需要取出文档根节点的SVG元素再插入页面。
修复方案
方案1:直接存储SVG字符串(最简便,推荐新手使用)
你完全没必要把SVG字符串包进Image对象,直接存原始字符串插入DOM即可,修改代码如下:
let buildCardArray = function () { for (let rankIndex = 0; rankIndex < 13; rankIndex++) { rank = ranks[rankIndex]; for (let suitIndex = 0; suitIndex < 4; suitIndex++) { suit = suits[suitIndex]; let cardKey = `${rank}_${suit}`; // 直接存SVG原始字符串,不用封装Image对象 let thisCard = new card(rank, suit, images[cardKey]); thisCard.toString = function () { return cardKey; } cardArray.push(thisCard); } } } function placeImage(index) { imgDiv = document.createElement('div'); // 直接把SVG字符串赋值给innerHTML即可正常渲染 imgDiv.innerHTML = cardArray[index].image; }
该方案和你直接把SVG写在HTML里的效果完全一致,不会出现额外兼容问题。
方案2:使用DOMParser解析插入
如果你需要用DOMParser的写法,修改取值逻辑即可:
function placeImage(index) { imgDiv = document.createElement('div'); const svgStr = cardArray[index].image; const svgDoc = new DOMParser().parseFromString(svgStr, "image/svg+xml"); // 取出解析好的svg根元素,追加到div节点下 imgDiv.appendChild(svgDoc.documentElement); }
方案3:需要使用Image元素的处理方式
如果后续你有把卡牌当成普通图片操作的需求,要用到Image对象,就把SVG字符串转成Data URI再赋值给src:
let buildCardArray = function () { for (let rankIndex = 0; rankIndex < 13; rankIndex++) { rank = ranks[rankIndex]; for (let suitIndex = 0; suitIndex < 4; suitIndex++) { suit = suits[suitIndex]; let cardKey = `${rank}_${suit}`; let img = new Image(); // 转成Data URI,注意要对svg内容做URI编码 img.src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(images[cardKey])}`; let thisCard = new card(rank, suit, img); thisCard.toString = function () { return cardKey; } cardArray.push(thisCard); } } } // 插入的时候直接把Image元素追加到DOM中即可 function placeImage(index) { imgDiv = document.createElement('div'); imgDiv.appendChild(cardArray[index].image); }
内容的提问来源于stack exchange,提问作者Zachary Thomas
相关产品推荐
相关产品推荐

