首页 > 解决方案 > HTML 中的命名空间是什么?

问题描述

我试图理解 HTML 中的命名空间非常简单。

使用这两个命令有什么区别。为什么要使用createElementNS过来createElement

const a = document.createElementNS("http://www.w3.org/2000/svg", "svg")
const b = document.createElement("svg")

资源:

标签: javascripthtml

解决方案


命名空间使不同类型的 XML¹ 可以具有具有不同含义的相同标记。这是MDN 上命名空间速成课程的摘录:

W3C 的长期目标是使不同类型的基于 XML 的内容可以在同一个 XML 文件中混合在一起。例如,SVG 和 MathML 可以直接合并到基于 XHTML 的科学文档中。能够像这样混合内容类型有很多优点,但也需要解决一个非常现实的问题。

自然,每种 XML 方言都定义了其规范中描述的标记元素名称的含义。在单个 XML 文档中混合来自不同 XML 方言的内容的问题在于,一种方言定义的元素可能与另一种方言定义的元素具有相同的名称。例如,XHTML 和 SVG 都有一个元素。用户代理应该如何区分这两者?事实上,用户代理如何知道 XML 内容何时是它所知道的,而不仅仅是一个包含它不知道的任意元素名称的无意义的 XML 文件?

在您的具体示例中,不同之处在于createElement("svg")创建了一个带有标签名称的HTML元素svg(不存在,没有带有该标签名称的HTML元素)。但是createElementNS("http://www.w3.org/2000/svg", "svg")会创建一个带有标签名称(确实存在)的SVG元素。svg

这很重要,因为 SVG 元素已经定义了行为和各种方法,以及您可能想要的。尝试将其创建为 HTML 元素,您不会获得这些行为和方法:

const a = document.createElementNS("http://www.w3.org/2000/svg", "svg");
const b = document.createElement("svg");

console.log("a instanceof SVGSVGElement?", a instanceof SVGSVGElement); // a instanceof SVGSVGElement? true
console.log("b instanceof SVGSVGElement?", b instanceof SVGSVGElement); // b instanceof SVGSVGElement? false

console.log("typeof a.currentScale:", typeof a.currentScale); // typeof a.currentScale: number
console.log("typeof b.currentScale:", typeof b.currentScale); // typeof b.currentScale: undefined


¹ HTML 不是 XML,但有时会在其中嵌入 XML(例如:SVG)。(有 XHTML,它是 XML,但请注意 XHTML 不是 HTML。)


推荐阅读