在开发Angular应用程序时,遇到了以下问题:SVG元素没有其类的样式(即使它是在<styles>
标签中定义的),还有更奇特的(和要点)问题): Chrome和Firefox DevTools不允许手动添加元素样式。
但是,如果我编辑容器元素HTML并仅复制并粘贴该标记-它突然出现并且一切都按预期工作。因此,这必须由于元素以编程方式添加到DOM的方式而发生。而且,由于Chrome和Firefox中的行为相同,因此很可能是功能而非错误。
那么如何有目的地实现这一目标?
P.S。对于那些对Angular部分感兴趣的人,这是我针对这种情况报告的GitHub问题(还包含复制回购):https://github.com/angular/material2/issues/15727
答案 0 :(得分:0)
所以我自己找到了答案。 TL; DR :使用document.createElementNS
创建的元素具有未知的名称空间(或为空),这使其成为Element
而不是SVGElement
。没有根据规范为基础Elements
定义样式。
因此,显然,关键是检查元素的类型-Chrome和Firefox均已证明SVG被创建为基础Element
:
下一个问题是它是如何发生的。本节的TL; DR:由于Angular的新实验性编译器中的一个错误(可能是),它被添加了无效的名称空间,其余的符合规范。
通过Angular的来源进行搜索,揭示了它创建元素的方式:createElementNS。
对该功能进行的快速实验已证明,最初的猜测是问题出在元素的接口(Element
)上,可以通过传递无效的名称空间来重现该问题。
并且DOM规范确切地说明了为什么会发生这种情况:
内部createElementNS步骤...:
...
4.返回给定文档localName,命名空间,前缀is和给定自定义同步元素标记的创建元素的结果。
Creating an element的定义如下:
在这种情况下,要创建给定文档,localName,名称空间和可选前缀is以及同步自定义元素标志的元素,请运行以下步骤:
...
4.让 definition 为查找给定文档,命名空间,localName和is的自定义元素定义的结果。
Looked up definition为NULL
要查找给定文档,名称空间,localName和is的自定义元素定义,请执行以下步骤。它们将返回自定义元素定义或null:
1.如果命名空间不是HTML命名空间,请返回null 。
从之前的createElementNS
返回步骤:
...
7.否则: [定义为空]
- 让 interface 成为localName和命名空间的 element接口。
- 将结果设置为实现接口的新元素,不带属性,将名称空间设置为名称空间,将名称空间前缀设置为前缀,将本地名称设置为localName,将自定义元素状态设置为“未自定义”,自定义元素定义设置为null,值设置为is,节点文档设置为document。
...
最后,element interface is defined如下:
任何名称和名称空间的元素接口均为 Element ,除非另有说明。
关于无法添加自定义样式,这是由于基础style
上缺少Element
属性所致。这可能是由于specification of the style
attribute:
所有 HTML元素可能都设置了样式内容属性。这是CSS样式属性规范所定义的样式属性。
为简化从HTML到XML的迁移,至少出于DOM和CSS的目的,符合此规范的UA会将元素放在HTML中的http://www.w3.org/1999/xhtml名称空间中。术语“ HTML元素”是指该命名空间中的任何元素,甚至在XML文档中也是如此。
但是,style
中存在SVGElement
属性,并且可能还有其他一些基本原型,因此必须有其他一些规范可以允许这样做。但是我认为这超出了我原来的问题。
这结束了我的研究。