JavaScript createElement и SVG
Я хочу создать встроенную графику SVG с помощью Javascript.
Однако, похоже, что функция createElementNS применяет некоторую нормализацию и преобразует все теги в нижний регистр. Это хорошо для HTML, но не для XML/SVG. Я использовал NS, http://www.w3.org/2000/svg.
В частности, у меня возникают проблемы с созданием элемента. Поскольку он будет добавлен как, таким образом, не будет работать.
Я сделал поиск, но не смог найти решение.
Кто-нибудь знает решение?
Спасибо большое!
document.createElementNS("http://www.w3.org/2000/svg","textPath");
приводит к
<textpath></textpath>
Ответы
Ответ 1
Надеюсь, вам поможет следующий пример:
function CreateSVG() {
var xmlns = "http://www.w3.org/2000/svg";
var boxWidth = 300;
var boxHeight = 300;
var svgElem = document.createElementNS(xmlns, "svg");
svgElem.setAttributeNS(null, "viewBox", "0 0 " + boxWidth + " " + boxHeight);
svgElem.setAttributeNS(null, "width", boxWidth);
svgElem.setAttributeNS(null, "height", boxHeight);
svgElem.style.display = "block";
var g = document.createElementNS(xmlns, "g");
svgElem.appendChild(g);
g.setAttributeNS(null, 'transform', 'matrix(1,0,0,-1,0,300)');
// draw linear gradient
var defs = document.createElementNS(xmlns, "defs");
var grad = document.createElementNS(xmlns, "linearGradient");
grad.setAttributeNS(null, "id", "gradient");
grad.setAttributeNS(null, "x1", "0%");
grad.setAttributeNS(null, "x2", "0%");
grad.setAttributeNS(null, "y1", "100%");
grad.setAttributeNS(null, "y2", "0%");
var stopTop = document.createElementNS(xmlns, "stop");
stopTop.setAttributeNS(null, "offset", "0%");
stopTop.setAttributeNS(null, "stop-color", "#ff0000");
grad.appendChild(stopTop);
var stopBottom = document.createElementNS(xmlns, "stop");
stopBottom.setAttributeNS(null, "offset", "100%");
stopBottom.setAttributeNS(null, "stop-color", "#0000ff");
grad.appendChild(stopBottom);
defs.appendChild(grad);
g.appendChild(defs);
// draw borders
var coords = "M 0, 0";
coords += " l 0, 300";
coords += " l 300, 0";
coords += " l 0, -300";
coords += " l -300, 0";
var path = document.createElementNS(xmlns, "path");
path.setAttributeNS(null, 'stroke', "#000000");
path.setAttributeNS(null, 'stroke-width', 10);
path.setAttributeNS(null, 'stroke-linejoin', "round");
path.setAttributeNS(null, 'd', coords);
path.setAttributeNS(null, 'fill', "url(#gradient)");
path.setAttributeNS(null, 'opacity', 1.0);
g.appendChild(path);
var svgContainer = document.getElementById("svgContainer");
svgContainer.appendChild(svgElem);
}
#svgContainer {
width: 400px;
height: 400px;
background-color: #a0a0a0;
}
<body onload="CreateSVG()">
<div id="svgContainer"></div>
</body>
Ответ 2
Во-первых, используйте createElementNS, как вы это делаете. createElement (без NS) автоматически уменьшает имена элементов внутри документов HTML, в соответствии с документацией Mozilla.
Во-вторых, не доверяйте функции Google Check Inspect Element. Кажется, он отображает каждый элемент в нижнем регистре, независимо от фактического имени узла. Попробуйте следующее:
> document.createElementNS("http://www.w3.org/2000/svg", "textPath").nodeName
"textPath"
> document.createElement("textPath").nodeName
"TEXTPATH"
Ваша проблема может быть несвязанной проблемой. Например, этот код отлично работает в Firefox, но разбивается на Chrome (12.0.742.112):
<html>
<head>
<script>
function animateSVG() {
var svgNS = "http://www.w3.org/2000/svg";
var textElement = document.getElementById("TextElement");
var amElement = document.createElementNS(svgNS, "animateMotion");
console.log(textElement);
console.log(amElement);
console.log(amElement.nodeName);
amElement.setAttribute("path", "M 0 0 L 100 100");
amElement.setAttribute("dur", "5s");
amElement.setAttribute("fill", "freeze");
textElement.appendChild(amElement);
//amElement.beginElement();
};
</script>
</head>
<body onload="animateSVG()">
<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(100,100)">
<text id="TextElement" x="0" y="0" style="font-family:Verdana;font-size:24">
It SVG!
<!-- <animateMotion path="M 0 0 L 100 100" dur="5s" fill="freeze"/> -->
</text>
</g>
</svg>
</body>
</html>
Моя проблема, вероятно, имеет какое-то отношение к нарушенной обработке animateMotion в Chrome (Проблема 13585).
Ваша проблема может быть одинаковой или может быть другой проблемой, но убедитесь, что инспектор элементов не обманул.
Ответ 3
Я только что решил аналогичную проблему.
document.createElement(и я предполагаю document.createElementNS), при вызове с HTML-страницы создается HTML node (где дело не имеет значения), а не xml node.
В Chrome работает следующее:
doc = document.implementation.createDocument(null, null, null);
doc.createElementNS( "http://www.w3.org/2000/svg", "textPath" );
вы получите свой смешанный футляр node.
Ответ 4
приведенный ответ слишком обширен и не очень полезен для меня, и я нахожу его очень хлопотным или просто сказать фикцию. Если бы я был вами, я бы просто получил по элементу в html с тегом say:
<b id="myElement"></b>
и когда мне нужно создать элемент или добавить информацию, я просто сделаю:
document.getElementById('myElement').innerHTML = 'your stuff here';
Надеюсь, что это было полезно.