在我编辑Chrome开发人员工具中的元素之前,SVG不会显示

aik*_*mcr 10 svg

我正在创建一个包含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的元素.

换句话说,因为您(可能是间接地)调用createElementHTML文档,所以它总是创建一个HTML元素.标记名为"svg"的HTML元素仅被视为未知的span-type元素.

相反,使用div.innerHTML传递标记字符串会正确创建SVG元素,因为它会调用HTML5解析器来确定要创建的元素类型.使用与从文件解析标记时相同的规则来确定命名空间.在Chrome开发人员工具中编辑HTML具有相同的效果.

旁注:避免调用.innerHTMLSVG元素.有些浏览器支持它,但它不是规范的一部分.您没有收到错误,因为您的svg变量实际上是一个实例HTMLUnknownElement.将SVG代码传递innerHTML给父级方法<div>通常有效,尽管SMIL动画存在一些错误.正如@Robert Longson在评论中所说,您可以使用DOMParser对象将HTML或XML代码解析为文档.

动态创建SVG元素的另一种方法是使用document.createElementNS(namespaceURI, tagName).您还必须使用此方法来创建SVG的所有子元素.创建它们后,您可以使用库方法设置属性,样式和类.(但是你还没有指定你正在使用的库,所以我不确定.)