如何将SVG文件作为foreignObject插入到以<object>嵌入DOM的SVG中?
在嵌入的SVG中使用foreignObject插入外部SVG文件
首先得明确两个核心前提:你通过<object>嵌入的SVG是一个独立的文档,必须等它加载完成后才能进行内部DOM操作;另外,虽然foreignObject主要设计用来嵌入HTML内容,但也可以用来嵌套SVG(不过如果只是单纯插入SVG,用<image>或<use>其实更直接,不过既然你明确问的是foreignObject的实现方式,我会一步步拆解)。
步骤1:等待嵌入的SVG加载完成
<object>加载SVG是异步过程,所以必须监听它的load事件,确保内部SVG文档已经完全可用:
const motorObject = document.getElementById('motor'); motorObject.addEventListener('load', () => { // 拿到嵌入的SVG内部文档 const svgInnerDoc = motorObject.contentDocument; if (!svgInnerDoc) { console.error('无法访问嵌入的SVG文档,大概率是跨域限制导致的'); return; } // 执行插入外部SVG的逻辑 insertSvgWithForeignObject(svgInnerDoc); });
步骤2:创建foreignObject并插入外部SVG
找到目标<g id="shape35-26">容器后,我们用fetch获取外部SVG的内容,再把它塞进foreignObject里:
function insertSvgWithForeignObject(svgInnerDoc) { const targetGroup = svgInnerDoc.getElementById('shape35-26'); if (!targetGroup) { console.error('找不到指定的g容器'); return; } // 读取rect的位置和尺寸参数,用来匹配插入SVG的大小和位置 const rect = targetGroup.querySelector('rect'); const rectX = rect.getAttribute('x'); const rectY = rect.getAttribute('y'); const rectWidth = rect.getAttribute('width'); const rectHeight = rect.getAttribute('height'); // 替换成你要插入的SVG文件路径 fetch('img/your-target.svg') .then(res => res.text()) .then(svgContent => { // 创建foreignObject元素,设置对应尺寸 const foreignObj = svgInnerDoc.createElementNS('http://www.w3.org/2000/svg', 'foreignObject'); foreignObj.setAttribute('x', rectX); foreignObj.setAttribute('y', rectY); foreignObj.setAttribute('width', rectWidth); foreignObj.setAttribute('height', rectHeight); foreignObj.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); // 把获取到的SVG文本转为DOM节点,插入foreignObject const parser = new DOMParser(); const importedSvgDoc = parser.parseFromString(svgContent, 'image/svg+xml'); const importedSvg = importedSvgDoc.querySelector('svg'); foreignObj.appendChild(importedSvg); // 把foreignObject添加到目标g容器里 targetGroup.appendChild(foreignObj); }) .catch(err => { console.error('加载外部SVG失败:', err); }); }
额外提醒
- 跨域问题:如果外部SVG文件和当前页面不在同一个域名下,必须确保服务器配置了CORS,否则
fetch请求会被浏览器拦截。 - 更简便的替代方案:如果只是单纯插入SVG,完全不需要
foreignObject,用<image>标签会更简单,比如:
这种方式代码更少,也更符合SVG的常规使用场景。const svgImg = svgInnerDoc.createElementNS('http://www.w3.org/2000/svg', 'image'); svgImg.setAttribute('href', 'img/your-target.svg'); svgImg.setAttribute('x', rectX); svgImg.setAttribute('y', rectY); svgImg.setAttribute('width', rectWidth); svgImg.setAttribute('height', rectHeight); targetGroup.appendChild(svgImg);
内容的提问来源于stack exchange,提问作者Gerasim Gerasimov
相关产品推荐
相关产品推荐

