如何在javascript中修改只读属性(element.classList)或将其分配给其他值?

时间:2017-01-08 12:01:48

标签: javascript



window.addEventListener('keydown',function(e) {
    const key= document.querySelector(`div[data-key='${e.keyCode}']`);
    console.log(key.className);
    console.log(key.classList);
    key.classList=['ajay','dish'];
}

<div data-key="65" class="key ajay">
			<kbd>A</kbd>
</div>
&#13;
&#13;
&#13;

enter image description here

以上是Chrome devtools的屏幕截图,其值已修改。

我在MDN上看到element.classList是只读属性,但可以由add()等进行修改。

我将它分配给其他一些阵列,这也有效。

在其他情况下,每当我尝试修改/指定只读属性时,它总是提供typeError

2 个答案:

答案 0 :(得分:1)

非常好的问题。

我原本不知道你问题的确切答案,但我对此行为并不感到惊讶。规范定义了所有合规用户(浏览器)必须实现的最小值。它还定义了开发人员在针对合规用户(浏览器)时可以期待和依赖的所有功能。浏览器可以添加其他非标准功能。

这意味着所有浏览器都必须实现名为get的{​​{1}}属性。开发人员应该只期望浏览器中可以使用classList属性。浏览器可能认为开发人员实现get功能也很方便。浏览器做这种事情相当普遍。有时,这种功能会被添加到标准的新版本中,有时它永远不会成功,因为标准委员会不同意该功能的纯度。

有时非标准功能会被弃用甚至删除,虽然需要数年时间 - 但是当其他标准功能可以达到相同的目标时,开发人员依赖非标准功能是一个很好的理由(对于例如,属性set可用于覆盖className)。

但毕竟技术上怎么做呢?

Chrome以非常聪明的方式实现了这一点(可能最初是WebKit)。它将属性classList应用于PutForwards的定义。

这允许将属性定义为classList,但是在分配值时,将分配对象的一个​​属性,而不是整个对象。在这种情况下,子属性名称为readonly

所以,代码value
document.body.classList = '123';

相同

您可以通过在Chrome控制台中运行以下内容来确认未替换该对象

document.body.classList.value = '123';

Chromium源代码中const body = document.body; const oldClassList = body.classList; const oldValue = body.classList.value; body.classList = "new-class"; const newClassList = body.classList; const newValue = body.classList.value; console.log( "classList changed:", oldClassList !== newClassList, // false "value changed:", oldValue !== newValue // true ); 的定义

classList

可在以下位置找到: https://github.com/chromium/chromium/blob/4141778eb03a31a20d9e109f74faf2f756b4a8c4/third_party/blink/renderer/core/dom/element.idl#L37

请注意这与规范

中的定义有何不同
[Affects=Nothing, SameObject, PerWorldBindings, PutForwards=value] readonly attribute DOMTokenList classList;

可以在https://www.w3.org/TR/dom/#element

找到

源代码中的测试解释了属性与覆盖其注释中readonly属性的能力之间的关系

[SameObject] readonly attribute DOMTokenList classList;`  

可在以下位置找到: https://github.com/chromium/chromium/blob/f18e79d901f56154f80eea1e2218544285e62623/third_party/WebKit/LayoutTests/fast/dom/HTMLElement/resources/class-list.js#L13

答案 1 :(得分:0)

只需使用.add()方法


    const key= document.querySelector(`div[data-key='${e.keyCode}']`);
    key.classList.add("your class");