为什么设置 element.className = null 会导致 class=“null”

Why does setting element.className = null result in class="null"?

本文关键字:null class className 设置 为什么 element      更新时间:2023-09-26

显然,尝试将className属性设置为 null 不会擦除 class 属性 - 相反,它会将其替换为字面上称为"null"的类名:

document.querySelector('p:nth-of-type(2)').className = null;
p[class]::before {
  content: '<p class="' attr(class) '">';
}
p:not([class])::before, p[class=""]::before {
  content: '<p>';
}
p.null {
  color: red;
}
<p class="a b c">
<p class="x y z">

最重要的是,有完整的互操作。

我本来希望className = null删除 class 属性,或者null会为了className而转换为空字符串,或者至少会产生 TypeError。

什么给?

在 JavaScript 中,null 不会转换为空字符串。它转换为字符串"null" .如果您手动转换它,您可以看到以下内容:

var x = String(null);
console.log(x);

这在 MDN 的DOMString文档中也提到过:

null传递给接受DOMString的方法或参数通常会字符串化为 "null"

className属性(以及相关的属性,如id(是DOMString类型,它直接映射到JS中的String。正是这种转换产生了一个字面上称为"null"的类名,然后反映在 class 属性中,并由 .null[class~=null] 等选择器匹配。

如果您希望null转换为空字符串,因为两者都是假值,则它不会以这种方式工作。仅仅因为两个值是假的,即两个值在转换为布尔值时都会导致false,并不能使这两个值彼此相等,甚至不会松散地相等。特别是,大多数对象,包括字符串,永远不会松散地等于null,因为某些东西不能等于什么(由于遗留原因有一些例外(。在 MDN 中有一个方便的比较表,您可以参考。

要擦除 class 属性并从元素中删除所有类名,请将 className 设置为空字符串而不是 null:

document.querySelector('p:nth-of-type(2)').className = '';
p[class]::before {
  content: '<p class="' attr(class) '">';
}
p:not([class])::before, p[class=""]::before {
  content: '<p>';
}
p.null {
  color: red;
}
<p class="a b c">
<p class="x y z">

(如果您不关心浏览器兼容性,您还可以迭代classList并单独删除每个类。有趣的是,对于性能迷来说,修改classList实际上比设置className更快——请参阅下面的评论。据推测,设置className也有更新classList的副作用,这可能是它变慢的原因。