简体   繁体   English

在JavaScript中:为什么不将标准属性的DOM属性设置为空字符串,则像Element.removeAttribute()一样删除属性?

[英]In JavaScript: Why doesn't setting a standard attribute's DOM property to an empty string remove the attribute like Element.removeAttribute() does?

I've learned that it's generally best to use DOM properties to set, access, and modify attributes which has lead me to avoid using setAttribute() and getAttribute(). 我了解到,通常最好使用DOM属性来设置,访问和修改属性,这使我避免使用setAttribute()和getAttribute()。 Is there a similar way to remove DOM attribute properties without using removeAttribute()? 是否有类似的方法可以在不使用removeAttribute()的情况下删除DOM属性属性?

Given this HTML code: 给出以下HTML代码:

<div id=el></div>

And this JavaScript code: 这段JavaScript代码:

let el = document.getElementById('el');
console.log(el.outerHTML); //<div id='el'></div>
console.log(el.align === ''); //true
el.align = 'center';
console.log(el.outerHTML); //<div id="el" align="center"></div>
el.align = '';
log(el.outerHTML); //<div id="el" align=""></div>

It appears that el.align is set to an empty string by default. 似乎el.align默认情况下设置为空字符串。 Why does resetting el.align to an empty string after assigning a value to el.align not remove the align attribute from the el.outerHTML presentation? 在为el.align分配值后,为什么将el.align重置为空字符串不会从el.outerHTML演示文稿中删除align属性? Is this method just as effective even so? 这种方法是否同样有效? Or will this cause issues that removeAttribute() won't? 还是这会导致removeAttribute()无法解决的问题?

You need to understand the difference between markup attributes and DOM properties. 您需要了解标记属性和DOM属性之间的区别。 Attributes don't always directly align with with a property on the JavaScript object. 属性并不总是与JavaScript对象上的属性直接对齐。

The mapping between IDL attribute (properties) and the corresponding content attribute (markup) depends on the definition of this Interface Definition Language. IDL属性(属性)和相应的内容属性(标记)之间的映射取决于此接口定义语言的定义。

Setting some IDL attributes to false or null will remove them, for instance the ones mapping to boolean attributes , whose simple presence signifies a truthy value: 将某些IDL属性设置为falsenull将删除它们,例如,那些映射到boolean属性的属性 ,其简单存在表示真值:

 console.log(aud.loop); console.log(aud.outerHTML); aud.loop = false; console.log(aud.outerHTML); 
 <audio id='aud' loop></audio> 

However, some others like keywords attributes won't get removed, because the value you did set even if not part of the list of valid keywords will map to an invalid default value , for instance HTMLInputElement's type IDL will default to "text", if you set an invalid value, but the markup will still show this invalid value. 但是,其他一些属性(例如关键字属性)将不会被删除,因为即使您未设置的值也不包含在有效关键字列表中,它也会映射为无效的默认值 ,例如HTMLInputElement的IDL type将默认为“ text”(如果您设置了无效值,但标记仍将显示该无效值。 (Your align attribute was part of this category, before it's been deprecated). (不推荐使用align属性,此属性属于该类别)。

 console.log(inp.type); // "number" inp.type = "foobar"; // invalid console.log(inp.type); // => default to "text console.log(inp.outerHTML); // markup: "foobar" inp.type = null; // invalid console.log(inp.type); // => default to "text console.log(inp.outerHTML); // markup: "null" 
 <input id="inp" type="number"> 

This makes sense since even though the browser doesn't recognize the set value as being one they support, it could very well be one that will be supported in the future. 这是有道理的,因为即使浏览器没有将设置值识别为它们支持的值,也很可能会在将来被支持。

The only way to remove such attributes is then to use Element.removeAttribute() method. 然后,删除此类属性的唯一方法是使用Element.removeAttribute()方法。

Same goes for other attributes which will accept any string as a valid value, for instance class (that is for HTML, CSS have stricter rules), here setting the IDL to any value will coerce it to a string, which will map to a valid in value in the IDL className . 对于将任何字符串作为有效值的其他属性(例如, class (对于HTML,CSS具有更严格的规则))也是如此,此处将IDL设置为任何值都会将其强制为字符串,该字符串将映射为有效值。值在IDL className

 console.log(el.className); // "" el.className = null; // coerced to string console.log(el.className); // "null" console.log(el.outerHTML); // markup: "null" el.className = false; // coerced to string console.log(el.className); // "false" console.log(el.outerHTML); // markup: "false" el.className = ""; // "" console.log(el.className); // "" console.log(el.outerHTML); // markup: "" 
 <div id="el"></div> 

And some will have different default values whether the attribute is missing , or in an invalid state, making their relation with the IDL even more obscure. 无论属性是缺少属性还是处于无效状态,其中一些将具有不同的默认值,这使得它们与IDL的关系更加模糊。

 // crossOrigin IDL when no set is `null`. console.log(img.crossOrigin);// attribute unset => IDL `null` img.crossOrigin = 'use-credentials' // only non default valid value. console.log(img.crossOrigin); console.log(img.outerHTML); img.crossOrigin = false; // invalid console.log(img.crossOrigin); // IDL defaults to "anonymous" console.log(img.outerHTML); // markup is `"false"` img.crossOrigin = null; // remove console.log(img.crossOrigin); console.log(img.outerHTML); 
 <img id="img"> 

Finally some won't get reflected at all in the content attribute, like the HTMLInputElement.value . 最后,有些内容根本不会反映在content属性中,例如HTMLInputElement.value

 inp.value = "new value"; console.log(inp.outerHTML); 
 <input id="inp" value="initialValue"> 

So you'd need to search for the definition of any IDL attribute to be sure how it should behave. 因此,您需要搜索任何IDL属性的定义以确保其行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM