如何在javascript中获取(X)HTML DOM 中元素名称的原始大小写?

How to get the original case of element names in (X)HTML DOM in javascript?

提问人:Gunther Schadow 提问时间:10/14/2022 最后编辑:Gunther Schadow 更新时间:10/15/2022 访问量:54

问:

我读到 HTML 总是从 Node.prototype.nodeName 和 HTMLElement.prototype.tagName 全部大写,但不是 HTML 的 XML 元素保留在原始大小写中。

这不是我发现的。一切都变成了大写字母,对着我们的脸尖叫着“我们留在 1980 年代!

<html>
  <body>
    <script>
const e = document.createElement('fooBar');
document.firstElementChild.insertBefore(e, document.firstElementChild.firstElementChild);
    </script>
    <p>
      <span>Hello</span>
      <script>       document.currentScript.parentElement.firstElementChild.innerText = e.nodeName + " (" + e.namespaceURI + ")";
      </script>
    </p>
  </body>
</html>

现在真正的真相是什么?

我怎样才能恢复原来的案件?

如何保存案例?

我知道我可以创建一个,然后我在其中创建的节点保持区分大小写。new Document()

我想如果我将HTML文档声明为XHTML,它应该是小写的并保留大小写。如何在HTML DOM中保留XML的大小写?


更新

尽管这个问题几乎已经得到了解答,但这里仍然有一个奇特的观察结果,这是来自 Chrome 控制台的

t = document.createElement('test')
<test>​</test>​

t.namespaceURI
'http://www.w3.org/1999/xhtml'

u = document.createElement('TEST')
<test>​</test>​

v = document.createElementNS(t.namespaceURI, t.nodeName)
<TEST>​</TEST>​

w = document.createElementNS(t.namespaceURI, 'test')
<test>​</test>​

x = document.createElementNS(t.namespaceURI, 'TEST')
<TEST>​</TEST>​

y = document.createElementNS(t.namespaceURI, 'Test')
<Test>​</Test>​

z = document.createElementNS('s', 'Test')
<Test>​</Test>​

[t, u, v, w, x, y, z].map(e => e.nodeName)
(7) ['TEST', 'TEST', 'TEST', 'TEST', 'TEST', 'TEST', 'Test']

请注意,虽然据说 Chrome 无法分辨标签名称的大小写,但在 XHTML 命名空间中,它实际上确实在自己的内部树显示中突然知道了它。然而,我无法找到它如何做到这一点,因为似乎没有方法或方法可以找到原始情况。

这是Firefox控制台的相同内容,它无法执行Chrome似乎可以执行的操作:

t = document.createElement('test')
<test>

t.namespaceURI
"http://www.w3.org/1999/xhtml"

u = document.createElement('TEST')
<test>

v = document.createElementNS(t.namespaceURI, t.nodeName)
<test>

w = document.createElementNS(t.namespaceURI, 'test')
<test>

x = document.createElementNS(t.namespaceURI, 'TEST')
<test>

y = document.createElementNS(t.namespaceURI, 'Test')
<test>

z = document.createElementNS('s', 'Test')
<Test>

[t, u, v, w, x, y, z].map(e => e.nodeName)
Array(7) [ "TEST", "TEST", "TEST", "TEST", "TEST", "TEST", "Test" ]

因此,虽然Firefox与我选择的答案相匹配,但Chrome有一些额外的怪癖,仍然可以获得原始拼写。

javascript html xml dom xhtml

评论

2赞 Quentin 10/14/2022
创建非标准元素并将其放入 HTML DOM 中不会使其成为 XML 元素。
2赞 Quentin 10/14/2022
这看起来像一个 XY 问题。您提供的高度人为的示例可能无法很好地表示实际问题。请专注于实际问题。
0赞 Gunther Schadow 10/15/2022
@Quentin你错了。由于 XHTML 是 XML,因此任何元素(标准或非标准)都是 XML 元素。一个非常简单的问题,答案非常简单。让它成为“XY问题”更多地说明了制造商而不是问题。
0赞 Quentin 10/15/2022
问题中的实时演示中的文档不是 XHTML 文档。它以内容类型提供,而不是内容类型。text/htmlapplication/xhtml+xml
0赞 Gunther Schadow 10/15/2022
@Quentin,错了。正如您现在在代码片段中看到的那样,namespaceURI 是 XHTML 命名空间。请注意,我没有更改任何内容,只是显示命名空间 URI

答:

0赞 Alohci 10/15/2022 #1

确保该元素不是 HTML 元素。所以用代替.命名空间不能是 HTML 命名空间。空字符串就可以了。createElementNScreateElement

<!DOCTYPE html>
<html>
  <body>
    <script>
const e = document.createElementNS('', 'fooBar');
document.firstElementChild.insertBefore(e, document.firstElementChild.firstElementChild);
    </script>
    <p>
      <span>Hello</span>
      <script>
         document.currentScript.parentElement.firstElementChild.innerText = e.nodeName;
      </script>
    </p>
  </body>
</html>

评论

0赞 Gunther Schadow 10/15/2022
谢谢,这就是答案。简单、清晰、清晰。我现在明白了,这与元素是否有效的 HTML 无关,重要的是它是否在 XHTML 命名空间中。
0赞 Gunther Schadow 10/15/2022
我又把选定的答案复选标记拿掉了一次,因为我可以证明你的答案,但发现Chrome似乎有某种方式可以记住原始情况(我在现实生活中已经注意到了这一点,这就是为什么我专门检查了这一点。
0赞 Alohci 10/15/2022
@GuntherSchadow - 转换为大写是 DOM API 和 DOM 序列化要求。它没有说明它是如何在内部存储的。但是,由于您拥有的唯一编程访问是通过这些接口,因此无法检索该信息。