why my object contentDocument returns null?

Clash Royale CLAN TAG#URR8PPP
why my object contentDocument returns null?
My goal is by scrolling mouse wheel, to change a viewBox attribute in a SVG, which retrieved through websocket from the API server. The way I do this is the following:
generate
<object id="std-chart"
class="mouse-wheel-pannable"
type="image/svg+xml"
/>
<object id="std-chart"
class="mouse-wheel-pannable"
type="image/svg+xml"
/>
when get data svgStr from websocket, dynamically put that in the <object> element.
svgStr
<object>
let obj = document.getElementById('std-chart');
var objUrl = 'data:image/svg+xml;utf8,'+ svgStr;
obj.setAttributeNS(null,'data',objUrl);
let obj = document.getElementById('std-chart');
var objUrl = 'data:image/svg+xml;utf8,'+ svgStr;
obj.setAttributeNS(null,'data',objUrl);
where svgStr is something like:
svgStr
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="1081" height="184" viewBox="0 0 1081 184" >
<path d="M 0.0 98.7 L 0.3 98.7 .../>
</svg>
Q1. I am not quite sure why I need to add data:image/svg+xml;utf8, in front of the svgStr. If I don't, the picture cannot be shown.
data:image/svg+xml;utf8,
svgStr
in my mouseWheelScroll() function, I try to find this svg element and change its viewBox. However I cannot find the svg element, because contentDocument returns null.
contentDocument
var svgObjs = document.getElementsByClassName("mouse-wheel-pannable");
var svgObj = svgObjs[0].contentDocument; //svgObj returns null
var svg = svgObj.getElementsByTagName('svg')[0]; //error here
svg.setAttributeNS(null, 'viewBox', someNewViewBox);
var svgObjs = document.getElementsByClassName("mouse-wheel-pannable");
var svgObj = svgObjs[0].contentDocument; //svgObj returns null
var svg = svgObj.getElementsByTagName('svg')[0]; //error here
svg.setAttributeNS(null, 'viewBox', someNewViewBox);
Question. How can I get a valid contentDocument. i.e. <svg> element, so that I can change the viewBox?
<svg>
thank you.
I tried to use <embed> instead of <object>, from the Chrome console I saw the embed item, however still how to get the underneath <svg>? Is that <svg> shown in the following picture still valid?
Please click here to see the chrome console for it.
<embed>
<object>
<svg>
<svg>
thank you.
Did some more tests. If I set <object data=xxxxxx.svg/> at the first beginning, i.e. if I store the svg content in a file and loaded in when initialize <object>, everything works perfect. Then I think the question is that how to dynamically let <object> to "reload" the svg content.
<object data=xxxxxx.svg/>
<object>
<object>
thank you.
1 Answer
1
Q1. I am not quite sure why I need to add data:image/svg+xml;utf8
The data attribute of an <object> has to be a URL. The string <svg>...</svg> is not a URL.
data
<object>
<svg>...</svg>
Prefixing it with data:image/svg+xml;utf8, turns it into a Data URL. The image/svg+xml is the MIME type which tells the browser this URL is an SVG. The utf8 part tells the browser how the text is encoded.
data:image/svg+xml;utf8,
image/svg+xml
utf8
BTW, Data URLs have the same rules that other URLs have. SVGs can contain characters that are illegal in URLs. So you should be URL encoding the SVG when you create the Data URL.
var objUrl = 'data:image/svg+xml;utf8,'+ encodeURI( svgStr );
Question. How can I get a valid contentDocument. i.e. element, so that I can change the viewBox?
You can't Not for a Data URL at least. Data URLs are treated as if they are on a different domain. And you can't get the contentDocument for cross domain objects.
contentDocument
https://html.spec.whatwg.org/#origin:document-4
"If the Document was generated from a data: URL
A unique opaque origin assigned when the Document is created."
data:
Then I think the question is that how to dynamically let to "reload" the svg content.
Why do you need to use an <object>? Why not just insert your SVG directly into the page?
<object>
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.