简体   繁体   中英

Why element.setAttribute('checked', true) doesn't work?

I want to do something like this:

elementX.setAttribute('checked', true); // this is input type checkbox
elementY.appendChild(elementX);

It is everything ok with rendering and other things but on the page, the input is not checked. When I look at elements in chrome console I can see:

<input type="checkbox" checked="true">

What should I do?

I've already tried

elementX.setAttribute('checked', true);
elementX.setAttribute('checked', 'true');
elementX.setAttribute('checked', 'checked');

I don't have any errors in the console.

See MDN :

checked

A Boolean attribute indicating whether or not this checkbox is checked by default (when the page loads). It does not indicate whether this checkbox is currently checked: if the checkbox's state is changed, this content attribute does not reflect the change. (Only the HTMLInputElement's checked IDL attribute is updated.).

While setting the checked attribute will show a change in the serialization of the element, it won't actually check the checkbox. For that, you have to invoke the setter, eg

elementX.checked = true;

Firstly, @CertainPerformance answer is the one that I upvoted, and it's correct!

I simply wanted to shed more light on the nuances of IDL( Interface Design Language ) attributes versus content attributes and what it means for them to be reflective or not.

In this case an IDL attribute is a JavaScript Property on a DOM representation of an Element. Not just any property, but one that was predefined within the W3 Specification. IDL Examples

Attributes specified in your HTML are considered content attributes . These attributes are used to populate IDL attributes on DOM Nodes during the rendering process. content attributes are accessible from the DOM Node through a few ways including the getAttribute method, but they are not stored on it as IDL attributes are. In simple terms element.getAttribute("checked") and element.checked are actually looking in two completely different objects for the key checked .

So what's it mean to be reflective?

A DOM Node's property and its HTML attribute are interchangeable from the point of rendering if the node is not altered - but also if specific attributes are changed.

Altering id and class in any way, whether directly on the DOM Node or within the Attribute object using the element.setAttribute method, will result in both values being changed.

id and class are reflective IDL attributes because they, in effect, watch their content attributes for changes and vice versa.

Alternatively checked and value IDL attributes are not reflective . When the value or checked properties are altered on either the DOM Node or the Attribute Object, it does not alter the corresponding attributes of the other.

Outside of those properties ( there are more than id and class - though there's no real list of reflective vs not reflective - I would presume it's any property related to the identity of the Node in the DOM that would cause a re-render ) the content attributes and DOM Node properties are not bound together. This makes using getAttribute and setAttribute useless if the intent is to update or get current data , because the current data is only found within the DOM Node properties .

The examples below illustrate the difference:


ID change example: Both Attribute and Property Reflect Each Other

 let i = document.querySelector("input"); i.addEventListener("id_change", function() { let HTML_Attribute = i.getAttribute("id"), DOM_Node_Property = i.id; console.log("HTML Attribute 'value': " + HTML_Attribute + "\\n DOM Node Property 'value': " + DOM_Node_Property); }) let n = 1; let timer = setInterval(function() { if(n > 2) clearInterval(timer); i.setAttribute("id", "newId_" + String.fromCharCode(Math.floor(Math.random() * 26) + 65)); i.dispatchEvent(new CustomEvent("id_change")); n++; }, 1000); 
 <input value="Hello World"/> 


Value change example: Attribute and Property Are Different

 let i = document.querySelector("input"); i.addEventListener("input", function() { let HTML_Attribute = i.getAttribute("value"), DOM_Node_Property = i.value; console.log("HTML Attribute 'value': " + HTML_Attribute + "\\n DOM Node Property 'value': " + DOM_Node_Property); }) 
 <input value="Hello World"/> <em><small>Type into the Box</small></em> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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