jquery의 부록이 svg 요소와 함께 작동하지 않습니까?
이 경우:
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("svg").append('<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>');
});
</script>
</head>
<body>
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100" width="200px" height="100px">
</svg>
</body>
왜 아무것도 안 보이는 거지?
을 크업문에전때달로 할 때$
을 사용하여 HTML로 구문 innerHTML
의 <div>
(와 같은 에 적합한 다른 )<tr>
).innerHTML
SVG 또는 기타 비HTML 콘텐츠를 구문 분석할 수 없으며, 설령 그것이 가능하다고 해도 그것은 말할 수 없을 것입니다.<circle>
SVG 네임스페이스에 있어야 했습니다.
innerHTML
SVGElement에서는 사용할 수 없습니다. HTMLlement만의 속성입니다.는 둘 다 .innerSVG
컨텐츠를 SVGElement로 구문 분석하는 속성 또는 다른 방법(*)입니다.따라서 DOM 스타일 메소드를 사용해야 합니다.jQuery에서는 SVG 요소를 만드는 데 필요한 네임스페이스 메소드에 쉽게 액세스할 수 없습니다.실제로 jQuery는 SVG와 함께 사용하도록 설계되지 않았으며 많은 작업이 실패할 수 있습니다.
이 HTML5를 사용할 수 것을 합니다.<svg>
xmlns
HTMLHTML) 내부에서text/html
앞으로 문서화합니다.하지만 은 단지 해킹이며, 네임스페이스에 이므로, 그러이단해파(**)일뿐을 사용할 수 입니다. SVG 콘텐츠는 여전히 SVG 네임스페이스의 SVGElements일 것이고 HTMLElements일 것이므로 사용할 수 없습니다.innerHTML
HTML 문서의 일부처럼 보이지만,
그러나 오늘날의 브라우저에서는 XHTML을 사용해야 합니다.application/xhtml+xml
로컬 테스트를 위해 .xhtml 파일 확장자로 저장)를 사용하여 SVG가 작동하도록 합니다. (어쨌든 SVG는 적절한 XML 기반 표준입니다.)이것은 당신이 탈출해야 한다는 것을 의미합니다.<
블록 섹션에 ) 및 을 합니다.xmlns
◦예:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"><head>
</head><body>
<svg id="s" xmlns="http://www.w3.org/2000/svg"/>
<script type="text/javascript">
function makeSVG(tag, attrs) {
var el= document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
el.setAttribute(k, attrs[k]);
return el;
}
var circle= makeSVG('circle', {cx: 100, cy: 50, r:40, stroke: 'black', 'stroke-width': 2, fill: 'red'});
document.getElementById('s').appendChild(circle);
circle.onmousedown= function() {
alert('hello');
};
</script>
</body></html>
DOM Level 3 LS의 parseWithContext가 있지만 브라우저 지원이 매우 부족합니다.추가하려면 편집: 그러나 SVGE 요소에 마크업을 주입할 수는 없지만 다음을 사용하여 HTML 요소에 새 SVGE 요소를 주입할 수 있습니다.innerHTML
그런 다음 원하는 대상으로 전송합니다.하지만 조금 더 느릴 수 있습니다.
<script type="text/javascript"><![CDATA[
function parseSVG(s) {
var div= document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
div.innerHTML= '<svg xmlns="http://www.w3.org/2000/svg">'+s+'</svg>';
var frag= document.createDocumentFragment();
while (div.firstChild.firstChild)
frag.appendChild(div.firstChild.firstChild);
return frag;
}
document.getElementById('s').appendChild(parseSVG(
'<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" onmousedown="alert(\'hello\');"/>'
));
]]></script>
저는 HTML5의 저자들이 XML을 무서워하고 XML 기반의 기능을 HTML이라는 복잡한 문제에 구두쇠로 만들기로 결심하는 것을 싫어합니다. XHTML은 수년 전에 이러한 문제를 해결했습니다.
받아들여진 답변은 너무 복잡한 방식을 보여줍니다.Forresto가 답변에서 주장한 것처럼, "DOM 탐색기에 추가하는 것 같지만 화면에는 추가되지 않습니다." 그리고 그 이유는 html과 svg의 다른 네임스페이스 때문입니다.
가장 쉬운 해결 방법은 전체 svg를 "새로 고침"하는 것입니다.원(또는 다른 요소)을 추가한 후 다음을 사용합니다.
$("body").html($("body").html());
이것은 효과가 있습니다.원은 화면에 있습니다.
또는 원하는 경우 컨테이너 div를 사용합니다.
$("#cont").html($("#cont").html());
그리고 svg를 용기 div 안으로 감싼다:
<div id="cont">
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100" width="200px" height="100px">
</svg>
</div>
기능적인 예:
http://jsbin.com/ejifab/1/://jsbin.com/ejifab/1/edit
이 기술의 장점:
- 기존 svg(이미 DOM에 있음)를 편집할 수 있습니다. 예를 들어 Raphael을 사용하여 작성한 경우와 같이 스크립트 없이 "하드 코딩"을 수행할 수 있습니다.
- 복잡한 요소 구조를 문자열로 추가할 수 있습니다.
$('svg').prepend('<defs><marker></marker><mask></mask></defs>');
당신이 jQuery에서 하는 것처럼. - 에는 음을사요추화표후면시에된고가되소를 사용하여
$("#cont").html($("#cont").html());
jQuery를 사용하여 할 수 .
편집:
은 " DOM " "DOM" (= document.createElement)으로 작동합니다.NS 등) 만 해당. 데 되는 경우, (내테스트에 ) 이 끊어집니다 Raphael 객체, (Raphael 객체) Raphael SVG DOM이 사용됩니다.$("#cont").html($("#cont").html());
사용됩니다.이 문제에 대한 해결 방법은 사용하지 않는 것입니다.$("#cont").html($("#cont").html());
더미 SVG 문서를 사용합니다.
이 더미 SVG는 먼저 SVG 문서의 텍스트 표현이며 필요한 요소만 포함합니다.예를 들어 라파엘 문서에 필터 요소를 추가하려면 더미가 다음과 같을 수 있습니다.<svg id="dummy" style="display:none"><defs><filter><!-- Filter definitons --></filter></defs></svg>
텍스트 표현은 먼저 jQuery의 $("body").append() 메서드를 사용하여 DOM으로 변환됩니다.그리고 (필터) 요소가 DOM에 있을 때, 표준 jQuery 메서드를 사용하여 쿼리할 수 있으며 Raphael이 작성한 메인 SVG 문서에 추가할 수 있습니다.
왜 이 더미가 필요합니까?라파엘이 만든 문서에 필터 요소를 엄격하게 추가하지 않는 이유는 무엇입니까?를 들어,를 들어, 예를 들어, 예를 들어, 예를 들어, 해 보면 됩니다.$("svg").append("<circle ... />")
HTML 요소로 생성되며 답변에 설명된 대로 화면에 아무것도 표시되지 않습니다.그러나 전체 SVG 문서가 추가되면 브라우저는 SVG 문서에 있는 모든 요소의 네임스페이스 변환을 자동으로 처리합니다.
예를 들어 기술을 설명합니다.
// Add Raphael SVG document to container element
var p = Raphael("cont", 200, 200);
// Add id for easy access
$(p.canvas).attr("id","p");
// Textual representation of element(s) to be added
var f = '<filter id="myfilter"><!-- filter definitions --></filter>';
// Create dummy svg with filter definition
$("body").append('<svg id="dummy" style="display:none"><defs>' + f + '</defs></svg>');
// Append filter definition to Raphael created svg
$("#p defs").append($("#dummy filter"));
// Remove dummy
$("#dummy").remove();
// Now we can create Raphael objects and add filters to them:
var r = p.rect(10,10,100,100);
$(r.node).attr("filter","url(#myfilter)");
이 기술의 전체 작업 데모는 다음과 같습니다. http://jsbin.com/ilinan/1/edit .
(나는 아직 (아직) 모르겠어, 왜요?$("#cont").html($("#cont").html());
Raphael을 사용할 때는 작동하지 않습니다.그것은 매우 짧은 해킹일 것입니다.)
점점 더 인기를 끌고 있는 D3 라이브러리는 svg 추가/조작의 이상한 점을 매우 잘 처리합니다.여기에 언급된 jQuery hacks와 반대로 사용하는 것을 고려해 보는 것이 좋습니다.
HTML
<svg xmlns="http://www.w3.org/2000/svg"></svg>
자바스크립트
var circle = d3.select("svg").append("circle")
.attr("r", "10")
.attr("style", "fill:white;stroke:black;stroke-width:5");
는 JQuery에 수 .<svg>
(DOM 탐색기에 추가하는 것처럼 보이지만 화면에는 추가되지 않습니다.)
한 가지 해결 방법은 다음을 추가하는 것입니다.<svg>
합니다..attr()
.
$('body')
.append($('<svg><circle id="c" cx="10" cy="10" r="10" fill="green" /></svg>'))
.mousemove( function (e) {
$("#c").attr({
cx: e.pageX,
cy: e.pageY
});
});
, 이방을언사는본람은적없만지이급하법,▁i,document.createElementNS()
이 경우 도움이 됩니다.
올바른 네임스페이스를 사용하여 바닐라 Javascript를 일반 DOM 노드로 사용하여 요소를 만든 다음 여기서 jQuery-ify화할 수 있습니다.이와 같은 경우:
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'),
circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
var $circle = $(circle).attr({ //All your attributes });
$(svg).append($circle);
유일한 단점은 올바른 네임스페이스를 사용하여 각 SVG 요소를 개별적으로 생성해야 하며 그렇지 않으면 작동하지 않는다는 것입니다.
내가 가지고 있는 모든 브라우저(Chrome 49, Edge 25, Firefox 44, IE11, Safari 5 [Win], Safari 8(MacOS))에서 작동하는 쉬운 방법을 찾았습니다.
// Clean svg content (if you want to update the svg's objects)
// Note : .html('') doesn't works for svg in some browsers
$('#svgObject').empty();
// add some objects
$('#svgObject').append('<polygon class="svgStyle" points="10,10 50,10 50,50 10,50 10,10" />');
$('#svgObject').append('<circle class="svgStyle" cx="100" cy="30" r="25"/>');
// Magic happens here: refresh DOM (you must refresh svg's parent for Edge/IE and Safari)
$('#svgContainer').html($('#svgContainer').html());
.svgStyle
{
fill:cornflowerblue;
fill-opacity:0.2;
stroke-width:2;
stroke-dasharray:5,5;
stroke:black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="svgContainer">
<svg id="svgObject" height="100" width="200"></svg>
</div>
<span>It works if two shapes (one square and one circle) are displayed above.</span>
파이어폭스에서 원을 볼 수 있습니다. 두 가지 작업을 수행합니다.
파일 이름을 html에서 xhtml로 변경
스크립트 변경
<script type="text/javascript">
$(document).ready(function(){
var obj = document.createElementNS("http://www.w3.org/2000/svg", "circle");
obj.setAttributeNS(null, "cx", 100);
obj.setAttributeNS(null, "cy", 50);
obj.setAttributeNS(null, "r", 40);
obj.setAttributeNS(null, "stroke", "black");
obj.setAttributeNS(null, "stroke-width", 2);
obj.setAttributeNS(null, "fill", "red");
$("svg")[0].appendChild(obj);
});
</script>
@chris-dolphin의 답변을 기반으로 하지만 도우미 기능을 사용합니다.
// Creates svg element, returned as jQuery object
function $s(elem) {
return $(document.createElementNS('http://www.w3.org/2000/svg', elem));
}
var $svg = $s("svg");
var $circle = $s("circle").attr({...});
$svg.append($circle);
Bobince에 의해 받아들여진 대답은 짧고 휴대하기 쉬운 해결책입니다.SVG 뿐만 아니라 조작도 필요하다면 자바스크립트 라이브러리 '파블로'(내가 작성)를 시도해볼 수 있습니다.jQuery 사용자에게 친숙하게 느껴질 것입니다.
코드 예제는 다음과 같습니다.
$(document).ready(function(){
Pablo("svg").append('<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>');
});
또한 다음과 같이 마크업을 지정하지 않고 SVG 요소를 즉시 만들 수 있습니다.
var circle = Pablo.circle({
cx:100,
cy:50,
r:40
}).appendTo('svg');
추가해야 하는 문자열이 SVG이고 적절한 네임스페이스를 추가하는 경우 문자열을 XML로 구문 분석하여 상위 항목에 추가할 수 있습니다.
var xml = jQuery.parseXML('<circle xmlns="http://www.w3.org/2000/svg" cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>');
$("svg").append(xml.documentElement)
나는 아약스를 사용하고 다른 페이지에서 svg 요소를 로드하는 것이 더 나을 수도 있다고 제안합니다.
$('.container').load(href + ' .svg_element');
여기서 href는 svg가 있는 페이지의 위치입니다.이렇게 하면 HTML 콘텐츠를 대체할 때 발생할 수 있는 민감한 영향을 방지할 수 있습니다.또한 svg가 로드된 후 랩을 해제하는 것을 잊지 마십시오.
$('.svg_element').unwrap();
다음 입니다.$("#wrapperElement").html(svgString)
이것은 크롬과 파이어폭스에서 잘 작동합니다.
var svg; // if you have variable declared and not assigned value.
// then you make a mistake by appending elements to that before creating element
svg.appendChild(document.createElement("g"));
// at some point you assign to svg
svg = document.createElementNS('http://www.w3.org/2000/svg', "svg")
// then you put it in DOM
document.getElementById("myDiv").appendChild(svg)
// it wont render unless you manually change myDiv DOM with DevTools
// to fix assign before you append
var svg = createElement("svg", [
["version", "1.2"],
["xmlns:xlink", "http://www.w3.org/1999/xlink"],
["aria-labelledby", "title"],
["role", "img"],
["class", "graph"]
]);
function createElement(tag, attributeArr) {
// .createElementNS NS is must! Does not draw without
let elem = document.createElementNS('http://www.w3.org/2000/svg', tag);
attributeArr.forEach(element => elem.setAttribute(element[0], element[1]));
return elem;
}
// extra: <circle> for example requires attributes to render. Check if missing.
저는 그것을 위해 작은 기능을 만들었습니다.메서드에 해야 하는 jQuery append, SVG의 이름 공간을 지정해야 하는 입니다."http://www.w3.org/2000/svg"
보기 »
그래서 제가 그것을 추가 방법으로 준비하면 어떨까요?이 경우 다음과 같은 매개 변수만 제공하면 됩니다.
tagName
rect, circle, text, g 등 모든 SVG 요소가 될 수 있습니다.
text
tagname과 를 지정해야
그리고 SVG 요소에 대해 알려진 다른 속성.
은 그서제할일다같음은이것정함다입니의는하수라는 입니다.createSvgElem()
파일은 document.createElementNS()입니다.
다음은 예입니다.
$("svg").append(
createSvgElem({tagName: "text", x: 10, y: 10, text: "ABC", style: "fill: red"})
)
기능은 다음과 같습니다.
function createSvgElem(options){
var settings = $.extend({
}, options);
if(!$.isEmptyObject(settings.tagName)){
var el = document.createElementNS('http://www.w3.org/2000/svg', settings.tagName);
for (var k in settings)
if(k != "tagName" && k != "text" && settings[k] != "")//If attribute has value
el.setAttribute(k, settings[k]);
if ("text" in settings)
el.textContent = settings.text; //el.innerText; For IE
return el;
}
}
여기서 직접 사용해 볼 수 있습니다.
//Definition:
function createSvgElem(options){
var settings = $.extend({
}, options);
if(!$.isEmptyObject(settings.tagName)){
var el = document.createElementNS('http://www.w3.org/2000/svg', settings.tagName);
for (var k in settings)
if(k != "tagName" && k != "text" && settings[k] != "")//If attribute has value
el.setAttribute(k, settings[k]);
if ("text" in settings)
el.textContent = settings.text; //el.innerText; For IE
return el;
}
}
//Usage:
$(function(){
$("#svg-elem").append(
createSvgElem({tagName: "rect", width: 130, height: 500, style: "fill: #000000a3;"})
)
$("#svg-elem").append(
createSvgElem({tagName: "text", x: 30, y: 30, text: "ABCD", style: "fill: red"})
)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg id="svg-elem" width="200" height="200">
</svg>
jquery를 사용하면 DataType을 'text'로 설정할 수 있습니다.
$.ajax({
url: "url-to-svg.svg",
dataType : 'text'
})
.done(function(svg) {
let svg_live = $(svg);
svg_live.append('<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>');
$('#selector-id').html(svg_live);
});
1: 안대 1: 네브티 jsinsertAdjacentHTML()
네이티브 자바스크립트로 전환하는 것을 전혀 고려하지 않는다면...
마찬가지로 편리한 표기법을 위해 네이티브 자바스크립트 방법을 사용할 수도 있습니다.
$("#svg")[0].insertAdjacentHTML(
"beforeEnd",
'<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>'
);
$("#svg")[0]
기본 JS에서 jQuery 개체를 선택할 수 있습니다.
2:를 쓰시오 2: 브티를 js성 작네.DOMParser()
mdn 웹 문서: DOMParser.parseFromString()
function createSvgEl(markup) {
markup = `<svg xmlns="http://www.w3.org/2000/svg">
${markup}</svg>`;
const svgEl = new DOMParser().parseFromString(markup, "image/svg+xml")
.documentElement.children[0];
return svgEl;
}
jQuery에서의 사용:
$("#svgXML").append(
createSvgEl(
'<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>'
)
);
데모
// native js helper
function createSvgEl(markup) {
markup = `<svg xmlns="http://www.w3.org/2000/svg">
${markup}</svg>`;
const svgEl = new DOMParser().parseFromString(markup, "image/svg+xml")
.documentElement.children[0];
return svgEl;
}
$(document).ready(function() {
// works - but will remove existing children
$("#svg1").html(
'<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>'
);
// works
// $("#svg")[0] makes your jQueryObject selectable in native JS
$("#svg")[0].insertAdjacentHTML(
"beforeEnd",
'<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>'
);
$("#svgXML").append(
createSvgEl(
'<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>'
)
);
// jquery still works! Vanilla doesn't harm!
$("#svgXML circle:nth-of-type(2)").attr('fill', 'orange');
//insert after()
$("#svgAfter circle").after(
createSvgEl(
'<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>'
)
);
//insert after native
$("#svgAfterNative circle")[0].insertAdjacentHTML(
"afterEnd",
'<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>'
);
});
svg {
border: 1px solid red;
overflow: visible;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Append via native js insertAdjacentHTML()</p>
<svg id="svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100" width="200px" height="100px">
<circle cx="10" cy="10" r="5" fill="green" />
</svg>
<p>Append via DOMParser() helper</p>
<svg id="svgXML" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100" width="200px" height="100px">
<circle cx="10" cy="10" r="5" fill="green" />
</svg>
<p>Append via jquery html() - will strip existing child nodes</p>
<svg id="svg1" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100" width="200px" height="100px">
<circle cx="10" cy="10" r="5" fill="green" />
</svg>
<p>Insert after existing element with jQuery after() using DOMParser() helper</p>
<svg id="svgAfter" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100" width="200px" height="100px">
<circle cx="10" cy="10" r="5" fill="green" />
</svg>
<p>Insert after existing element with native js insertAdjacentHTML()</p>
<svg id="svgAfterNative" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100" width="200px" height="100px">
<circle cx="10" cy="10" r="5" fill="green" />
</svg>
jquery의 메서드는 올바른 네임스페이스에 따라 SVG DOM 요소를 추가하지 못합니다.
앞서 언급한 해결 방법을 사용하면 이 문제도 해결될 수 있습니다.
이것은 오늘 저에게 FF 57과 함께 효과가 있습니다.
function () {
// JQuery, today, doesn't play well with adding SVG elements - tricks required
$(selector_to_node_in_svg_doc).parent().prepend($(this).clone().text("Your"));
$(selector_to_node_in_svg_doc).text("New").attr("x", "340").text("New")
.attr('stroke', 'blue').attr("style", "text-decoration: line-through");
}
제조업체:
언급URL : https://stackoverflow.com/questions/3642035/jquerys-append-not-working-with-svg-element
'programing' 카테고리의 다른 글
jQuery UI datepicker에서 날짜를 가져오는 방법 (0) | 2023.08.29 |
---|---|
Spring Boot 2.4.2 및 Thymeleaf 3.0.12 - 정적 방법 액세스 (0) | 2023.08.29 |
PHP에서 DEFINE vs 변수 (0) | 2023.08.29 |
구분 기호로 판다 데이터 프레임 열 분할 (0) | 2023.08.29 |
WHERE 절은 IN과 JOIN 이전 또는 이후에 더 잘 실행됩니다. (0) | 2023.08.29 |