Creating SVG fragments with Javascript and Strings
-
12-10-2019 - |
سؤال
I've seen several examples about how to use the DOM api to create SVG fragments from within Javascript, but I'm curious is there something I can use to create a SVG fragment from a string similar to innerHTML. I've tried this following:
var svg = '<foreignObject><body xmlns="http://www.w3.org/1999/xhtml"><p>Hello World</p></foreignObject>'
var range = document.createRange();
return range.createContextualFragment(svg);
Problem is createContextualFragment() with SVG blows up with an exception in Chrome. So is there a cross browser way to do this?
المحلول
So here is what I did:
parseXML('<foreignObject xmlns="http://www.w3.org/2000/svg"><body xmlns="http://www.w3.org/1999/xhtml"><p id="seriesTitle"></p><p id="seriesValue"></p><p style="margin:0;text-align:center;" id="seriesDate"></p></body></foreignObject>')
Since parseXml() isn't exactly cross browser supported I have this code at the top:
if (typeof parseXML=='undefined') {
window.parseXML = function (s,doc) {
doc = doc || document;
var doc2=(new DOMParser()).parseFromString(s, "text/xml");
return doc.adoptNode(doc2.documentElement);
}
}
Then I can use jQuery to query instead the fragment and set the values I'd like:
jQuery('#seriesTitle', detailChart.mytooltip).text( point.series.name );
jQuery('#seriesValue', detailChart.mytooltip).text( point.y );
jQuery('#seriesDate', detailChart.mytooltip).text( date.getMonth() + '/' + date.getDate() + '/' + date.getFullYear() );
Problem is VML doesn't support anything like foreignObject. SVG is so close to being a great solution for building applications that doesn't have all the HTML headaches.
نصائح أخرى
If you want something like innerHTML
, your original code should have the range select the element, to set up the right parser context. Then Chrome should fix http://crbug.com/107982
Assuming the bug was fixed, here's how I would parse a SVG fragment. https://github.com/pwnall/ddr/blob/master/javascripts/base/pwnvg.coffee#L184
In the meantime, I came up with a solution that is very similar to yours, but tells DOMParser
that it's dealing with SVG contents. I think your solution is better for your specific case, but my code is a bit closer to innerHTML
(actually I aim to match insertAdjacentHTML
).
https://github.com/pwnall/ddr/blob/master/javascripts/base/pwnvg.coffee#L169