簡體   English   中英

setAttributeNS xmlns的 <svg> 用於通用庫

[英]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在這種情況下。

該解決方法似乎非常具體,我擔心一般情況。 是否有一般如何使用setAttributeNSsetAttribute處理設置屬性的先例?

其他Web框架不能很好地解決這個問題–通常將其與其他邏輯混合在一起。 我見過的最即時的提交是針對angular ,但它並不能直接解決這個問題。

相關: setAttribute和setAttributeNS(null,

它不會涵蓋所有情況,但是應該走很長一段路:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM