[英]setAttributeNS xmlns of <svg> for a general-purpose library
當在<svg>
元素上使用setAttributeNS
設置xmlns
屬性時,Web瀏覽器似乎拋出DOMException
。 即
>>> s = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
<svg></svg>
>>> s.setAttributeNS(null, 'xmlns', '123')
Uncaught DOMException: Failed to execute 'setAttributeNS'
on 'Element': '' is an invalid namespace for attributes.
>>> s.setAttributeNS('http://www.w3.org/2000/svg', 'xmlns',
'http://www.w3.org/2000/svg')
Uncaught DOMException: Failed to execute 'setAttributeNS'
on 'Element': '' is an invalid namespace for attributes.
>>> s.setAttributeNS(null, 'xmlns', 'http://www.w3.org/2000/svg')
Uncaught DOMException: Failed to execute 'setAttributeNS'
on 'Element': '' is an invalid namespace for attributes.
Mozilla文檔建議始終使用setAttributeNS
,但是沒有提及這種可能性。 因此,該建議似乎有一些警告。
setAttributeNS
上的DOM Level 2規范提供了一些見解:
NAMESPACE_ERR:如果qualifiedName格式錯誤,qualifiedName具有前綴且namespaceURI為null,qualifiedName具有前綴“ xml”且namespaceURI與“ http://www.w3.org/XML ”不同,則引發/ 1998 / namespace ”,或者,如果qualifiedName是“ xmlns”,並且namespaceURI與“ http://www.w3.org/2000/xmlns/ ”不同。
因此,該特殊異常似乎是可能失敗的更廣泛案件的一部分。 目前尚不清楚這些情況是什么。
我正在編寫通用Web框架tko / Knockout 4.0,因此它應該支持svg
和核心HTML命名空間之外的其他標簽。
最常遇到的問題來自svg
標簽上的xmlns
,所以這是一個問題 。 我已經圍繞這個工作由專門檢查,看看是否xmlns
被設置和使用setAttribute
在這種情況下。
該解決方法似乎非常具體,我擔心一般情況。 是否有一般如何使用setAttributeNS
和setAttribute
處理設置屬性的先例?
其他Web框架不能很好地解決這個問題–通常將其與其他邏輯混合在一起。 我見過的最即時的提交是針對angular ,但它並不能直接解決這個問題。
它不會涵蓋所有情況,但是應該走很長一段路:
const NAMESPACES = {
svg: 'http://www.w3.org/2000/svg',
html: 'http://www.w3.org/1999/xhtml',
xml: 'http://www.w3.org/XML/1998/namespace',
xlink: 'http://www.w3.org/1999/xlink',
xmlns: 'http://www.w3.org/2000/xmlns/' // sic for the final slash...
}
class JsxObserver extends LifeCycle {
...
setNodeAttribute (node, name, valueOrObservable) {
const value = unwrap(valueOrObservable)
NativeProvider.addValueToNode(node, name, valueOrObservable)
if (value === undefined) {
node.removeAttributeNS(null, name)
} else if (isThenable(valueOrObservable)) {
Promise.resolve(valueOrObservable)
.then(v => this.setNodeAttribute(node, name, v))
} else {
const [prefix, ...unqualifiedName] = name.split(':')
let ns = null
if (prefix === 'xmlns' || unqualifiedName.length && NAMESPACES[prefix]) {
ns = NAMESPACES[prefix]
}
node.setAttributeNS(ns, name, String(value))
}
}
}
如果遇到的屬性是xmlns="http://www.w3.org/2000/svg"
,則將其添加為
.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', 'http://www.w3.org/2000/svg')
如果遇到的屬性是xml:space="preserve"
(SVG編輯器眾所周知使用的屬性),則將其添加為
.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.