我正在创建一个包含SVG元素的dom结构:
<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 (A-Z)</option>
<option value="person_full_name_desc">Member Full Name (Z-A)</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>
Run Code Online (Sandbox Code Playgroud)
svg元素实际上并不显示.当我在Chrome开发人员工具中找到svg元素时,宽度和高度都显示为零.
我试过删除样式属性.我已经尝试在style属性中设置宽度和高度.
我已将svg复制到单独的HTML文件中:
<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>
Run Code Online (Sandbox Code Playgroud)
它显示的很好.
如果我将svg元素包装在div中,则显示svg元素.事实上,如果我在Chrome开发者工具中编辑HTML,它就会显示出来.
所以,是的,为什么?我已经在谷歌搜索了这个,但要么它不存在,或者(更有可能)我的Google Fu无法完成任务.我的意思是,当然,我可以将它包装在一个div中 - 也许这是正确的事情 - 但我不愿意,因为那时我需要将其他东西包装在div中并且dom将开始变得杂乱无章.
编辑:在预感中,我尝试将视口属性编辑到Chrome工具中的SVG元素中.瞧!元素是可见的!当我在创建文档时包含viewport属性时,它是不可见的.所以我尝试在Chrome工具中添加一个随机属性到SVG元素.瞧!元素是可见的!所以,我想,问题是Chrome特有的,并尝试在Firefox中运行它...
......元素没有出现的地方.
编辑:很好,所以将它包装在div中并不能保证它会显示出来.但是,在Chrome开发者工具中进行"编辑为HTML"会让它显示出来.
编辑:嗯,我已经让它正常工作,是的,它原来是Javascript创建DOM元素的功能.代码中有很多东西,但我可以归结为:
此代码有效(createElement根据传入的参数创建标记并设置属性):
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;
Run Code Online (Sandbox Code Playgroud)
此代码不会:
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;
Run Code Online (Sandbox Code Playgroud)
所以,当然,我现在有一些工作,但我不明白为什么.或者更重要的是,我不明白为什么一种方式有效而另一种方式无效.我有几个猜测,但它们只是猜测,真的.
Ame*_*aBR 19
"我现在有一些工作,但我不明白为什么."
问题是您使用的方法不会在SVG名称空间中创建SVG元素.该xmlns
属性仅影响XML解析器的行为,而不影响DOM方法的行为.
我不确定您使用哪个库用于this.createElement()
具有多个参数的方法.但是,我怀疑它可能是从调用基本document.createElement(tagName)
方法开始的.这就是MDN关于标准DOM createElement
方法的说法:
在HTML文档中创建指定的HTML元素,或者
HTMLUnknownElement
如果元素未知....在其他文档中创建一个null namespaceURI的元素.
换句话说,因为您(可能是间接地)调用createElement
HTML文档,所以它总是创建一个HTML元素.标记名为"svg"的HTML元素仅被视为未知的span-type元素.
相反,使用div.innerHTML
传递标记字符串会正确创建SVG元素,因为它会调用HTML5解析器来确定要创建的元素类型.使用与从文件解析标记时相同的规则来确定命名空间.在Chrome开发人员工具中编辑HTML具有相同的效果.
旁注:避免调用.innerHTML
SVG元素.有些浏览器支持它,但它不是规范的一部分.您没有收到错误,因为您的svg
变量实际上是一个实例HTMLUnknownElement
.将SVG代码传递innerHTML
给父级方法<div>
通常有效,尽管SMIL动画存在一些错误.正如@Robert Longson在评论中所说,您可以使用DOMParser对象将HTML或XML代码解析为文档.
动态创建SVG元素的另一种方法是使用document.createElementNS(namespaceURI, tagName)
.您还必须使用此方法来创建SVG的所有子元素.创建它们后,您可以使用库方法设置属性,样式和类.(但是你还没有指定你正在使用的库,所以我不确定.)