javascript - 即使使用 createElementNS,动态添加的 SVG 元素也不会出现

标签 javascript xml svg dynamic

The html code and how it shows up on the inspector

你好,我开始学习一些网络开发。一直进展顺利,直到我尝试在组中动态生成一些 SVG 矩形。但即使代码显示在检查器上,当我将鼠标悬停在动态生成的矩形代码上时,它会显示“矩形 0x0”,并且不会在视觉上出现。我搜索了很多其他帖子,但没有找到解决方案。

function getMousePosition(svg, event) {
    var CTM = svg.getScreenCTM();
    if (event.touches) { event = event.touches[0]; }
    return {
        x: (event.clientX - CTM.e) / CTM.a,
        y: (event.clientY - CTM.f) / CTM.d
    };
}
var NS = "http://www.w3.org/2000/svg", elemWidth = 80, elemHeight = 40, slotWidth = 10, slotHeight = 10;

function spawnElem(event){
    let svg = event.target;
    if(event.which == 3){
        let pos = getMousePosition(svg, event)
        spawnElemHelper(svg, pos.x, pos.y);
    }
}

function spawnElemHelper(svg, x, y){
    topLeft = {x: x - elemWidth / 2,
               y: y - elemHeight / 2
            };

    // group = document.createElementNS(NS, 'g');
    // group.classList.add('draggable-group');

    main = document.createElementNS("http://www.w3.org/2000/svg", 'rect');
    main.setAttributeNS(NS, 'x', String(topLeft.x));
    main.setAttributeNS(NS, 'y', String(topLeft.y));
    main.setAttributeNS(NS, 'width', String(elemWidth));
    main.setAttributeNS(NS, 'height', String(elemHeight));
    main.setAttributeNS(NS, 'fill', 'blue');

    // slotInput = document.createElementNS(NS, 'rect');
    // slotInput.classList.add("slot");
    // slotInput.setAttributeNS(NS, 'x', String(topLeft.x));
    // slotInput.setAttributeNS(NS, 'y', String(topLeft.y + (elemHeight - slotHeight) / 2));
    // slotInput.setAttributeNS(NS, 'width', String(slotWidth));
    // slotInput.setAttributeNS(NS, 'height', String(slotHeight));
    // slotInput.setAttributeNS(NS, 'fill', 'yellow');

    // slotOutput = document.createElementNS(NS, 'rect');
    // slotOutput.classList.add("slot");
    // slotOutput.setAttributeNS(NS, 'x', String(topLeft.x + elemWidth - slotWidth));
    // slotOutput.setAttributeNS(NS, 'y', String(topLeft.y + (elemHeight - slotHeight) / 2));
    // slotOutput.setAttributeNS(NS, 'width', String(slotWidth));
    // slotOutput.setAttributeNS(NS, 'height', String(slotHeight));
    // slotOutput.setAttributeNS(NS, 'fill', 'yellow');

    // group.appendChild(main);
    // group.appendChild(slotInput);
    // group.appendChild(slotOutput);
    
    //svg.appendChild(group);
    svg.appendChild(main);
}
//var svg is the svg element in the HTML which has the id "canvas"
document.getElementById('canvas').addEventListener('mousedown', spawnElem);

最佳答案

SVG 仅对元素使用命名空间,而不对属性使用命名空间。这些属性位于“空”命名空间中。这是 XML 的典型情况(有多种格式都这样做),并且命名空间属性需要使用前缀。

您可以使用setAttribute()setAttributeNS('', ...):

const xmlns_svg = 'http://www.w3.org/2000/svg';

const svg = document.implementation.createDocument(xmlns_svg, 'svg', null);
svg.documentElement.setAttribute('width', '100');
svg.documentElement.setAttribute('height', '100');

const rect = svg.documentElement.appendChild(
  svg.createElementNS(xmlns_svg, 'rect')
);
rect.setAttribute('x', '25');
rect.setAttribute('y', '25');
rect.setAttribute('width', '50');
rect.setAttribute('height', '50');
rect.setAttribute('fill', 'blue');

document.querySelector('div.demo').appendChild(
  document.importNode(svg.documentElement, true)
);

const svgData = (new XMLSerializer()).serializeToString(svg);
document.querySelector('img.demo').setAttribute(
  'src',
  'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svgData)
);
<div class="demo"></div>

<img class="demo"/>

关于javascript - 即使使用 createElementNS,动态添加的 SVG 元素也不会出现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68297683/

相关文章:

javascript - 隐藏输入字段的内联 Javascript 无法正常工作

javascript - 如何让我的代码始终位于 Javascript Canvas 的中间

javascript - JQuery/Javascript 简单的 div 幻灯片

java - CXF、XMLStreamWriter 和编码

c# - 序列化列表持有 XML 接口(interface)

javascript - 用js移动svg框

winforms - 有没有一种方法可以在Windows窗体中呈现SVG?

javascript - JSLINT 关于条件表达式的样式或错误的警告

xml - 将股票价格从彭博社导入 Google 表格

javascript - SVG filterRes替代/替换策略