SVG Doesn’t show until I edit the item in the Chrome Developer Tools.

I create a dom structure that includes an SVG element:

<div data-bind="with: searchable_select.f0000001" style="verticalAlign: top"> <input data-bind="value: select_filter_value, valueUpdate: 'afterkeydown', event: { change: change_filter_, blur: blur_filter_ }" style="display: none"> <div> <select data-bind="options: select_list, value: working_value, event: { change: change_selector_ }, optionsText: 'label', optionsValue: 'value'" style="display: inline-block; maxWidth: 150px"> <option value="person_full_name_asc">Member Full Name (AZ)</option> <option value="person_full_name_desc">Member Full Name (ZA)</option> </select> <svg style="display: inline-block; verticalAlign: middle" width="18" height="18" xmlns="http://www.w3.org/2000/svg" version="1.1"> <g> <circle cx="6" cy="6" r="5" fill="#AAAAAA" stroke="#000000" stroke-width="2"></circle> <path fill="#AAAAAA" stroke="#000000" stroke-width="2" d="M10,10 L17,17"></path> </g> </svg> </div> </div> 

The svg element is not actually displayed. When I find the svg element in the Chrome developer tools, the width and height are displayed as zero.

I tried to remove the style attribute. I tried to set the width and height in the style attribute.

I copied svg to a separate HTML file:

 <html> <head><title>maggen</title></head> <body> <svg style="display: inline-block; verticalAlign: middle" width="18" height="18" xmlns="http://www.w3.org/2000/svg" version="1.1"> <g> <circle cx="6" cy="6" r="5" fill="#AAAAAA" stroke="#000000" stroke-width="2"></circle> <path fill="#AAAAAA" stroke="#000000" stroke-width="2" d="M10,10 L17,17"></path> </g> </svg> </body> </html> 

Where is it displayed normally.

If I complete the svg element in the div, the svg element will appear. In fact, if I edit the HTML in the Chrome Developer Tools, it will appear.

So yes, why? I did a Google search for this, but either it does not exist, or (rather) my Google Fu is not up to the task. I mean, of course, I can wrap it in a div - and maybe that's right, but I would prefer it, because then I would need to wrap other things in divs, and dom will start cluttering up.

EDIT: While waiting, I tried to change the viewport attribute in the SVG element in Chrome tools. Voila! The item is visible! Expect me to include the viewport attribute when creating the document, it will not be visible. So I tried just adding a random attribute in Chrome tools to the SVG element. Voila! The item is visible! So, I thought the problem is with Chrome and trying to run it in Firefox ...

... where the item is not displayed.

EDIT: Great, so wrapping it in a div does not guarantee that it will appear. But doing "editing as HTML" in the Chrome developer tools makes it accessible.

EDIT: Well, I got the right job and, yes, it turns out this is a Javascript function that creates DOM elements. There are many things in the code, but I can weld this:

This code works (createElement creates a tag and sets attributes based on the passed parameters):

 var div = this.createElement( 'div', element_name + '_div', null, style_options, null, null ); div.innerHTML = [ '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width=' + width + ' height=' + height + '>', svg_xml.join(''), '</svg>' ].join(''); if (parent) parent.appendChild(div); return div; 

There is no in this code:

 var svg = this.createElement('svg', element_name, null, style_options, classlist, { viewport: '0 0 ' + width + ' ' + height, version: "1.1", xmlns: "http://www.w3.org/2000/svg", width: width, height: height }); svg.innerHTML = svg_xml.join(''); if (parent) parent.appendChild(svg); return svg; 

So, of course, something works for me now, but I don’t understand why. Or moreover, I don’t understand why one of the methods works and the other does not. I have a few conjectures, but in reality these are just wild conjectures.

+7
svg
source share
1 answer

"Something is working for me now, but I don’t understand why."

The problem is that the methods you used do not create an SVG element in the SVG namespace. The xmlns attribute only affects the behavior of the XML parser, not the DOM methods.

I am not sure which library you are using for this.createElement() method with multiple parameters. However, I suspect that this probably starts with a call to the document.createElement(tagName) base method. This is what MDN says about the standard DOM createElement :

The specified HTML element or HTMLUnknownElement is created in the HTML document if the element is unknown .... In other documents, an element with a zero URI namespace is created.

In other words, since you (presumably indirectly) call createElement in an HTML document, it always creates an HTML element. An HTML element with the tag name "svg" is simply considered an unknown span-type element.

In contrast, using div.innerHTML to pass the markup line creates the SVG element correctly because it calls the HTML5 parser to figure out what type of element to create. The namespace is defined using the same rules as when parsing markup from a file. Editing HTML in Chrome Developer Tools has the same effect.

Sidenote: Avoid calling the .innerHTML SVG element. Some browsers support it, but this is not part of the specifications. You are not getting an error because your svg variable is actually an instance of HTMLUnknownElement . Passing SVG code to the parent <div> innerHTML method usually works, although there are some bugs with SMIL animations. As @Robert Longson explains in the comments, you can use the DOMParser object to parse HTML or XML code in a document.

Another way to dynamically create an SVG element is to use document.createElementNS(namespaceURI, tagName) . You will also have to use this method to create all the children of the SVG. After creating them, you can set attributes, styles, and classes using your library methods. (But you did not specify which library you are using, so I'm not sure.)

+13
source share

All Articles