12

Serializable property is defined as:

  • When you set a property of the element, it will be reflected in serialization queries such as getAttribute and you can see the changes in DOM Inspector
  • When you get the .innerHTML of the element's parentnode, the returned html string will contain all the serializable properties as their attribute counterparts

I have made a page that looks like it's reliably printing a table of all serializable properties of the input element in Chrome and Firefox: http://jsfiddle.net/tEVLp/16/. Custom properties are never serializable, so in firefox webkitSpeech etc are not serializable. Test in chrome for best results.

All booleans are true because serialization of a false property would be the absence of the attribute which is a false negative in the test.

So my question is, why are not properties such as .value and .checked serializable?

Technically, both are serializable. .value is just a string and the browser has no problems with serializing other boolean properties, such as .readOnly and .disabled.

My best guess is that since .defaultValue serializes to "value"-attribute and .defaultChecked serializes to "checked"-attribute, there would be a conflict and thus the .value and .checked cannot be serialized. In that case, why are the defaultX ones chosen for these and not the ones that reflect the more useful current .value and .checked states?

Esailija
  • 138,174
  • 23
  • 272
  • 326
  • In Firefox, the "type" attribute shows up with "title" in the attribute key column. Weird. – Pointy Aug 02 '12 at 13:19
  • @Pointy the test is assuming that the newly created attribute is last in the attributes list... turns out `type` is for some reason moved to the first position in firefox. See http://jsfiddle.net/tEVLp/14/ for the logs – Esailija Aug 02 '12 at 13:27
  • The "lang" attribute is also strange like that. – Pointy Aug 02 '12 at 13:28
  • @Pointy heh actually many of them are like that, I have adjusted that in my question. Workaround would be storing them in an array and comparing `attr` objects for equality to find out which one changed . – Esailija Aug 02 '12 at 13:29
  • It's really bizarre; the "value" attribute is there in the list (in the console); how/when does it get there? The length of the list is 0 before the loop that sets the properties, and it only changes by 1 when properties are (successfully) added. I need some coffee. – Pointy Aug 02 '12 at 13:38
  • @Pointy `.defaultValue` maps to the `"value"`-attribute, see the last paragraph. Changing `.defaultValue` indeed shows up in dom inspectors and `.getAttribute` etc. This conflict would be obvious answer to my first question but I also wanted to know if there is a reason for choosing `.defaultValue` over `.value` mapping. – Esailija Aug 02 '12 at 13:38
  • I would assume this is how it is for elements the user can interact with. The internal value or state of such an element can be changed during its life time (by the user) but the other attributes can't. – Felix Kling Aug 02 '12 at 13:53

2 Answers2

13

The Specification for input elements defines the exact behaviour. Start reading from here (before that, the DOM interface, attributes and types are defined).

Concise summary (value is defined similarly to checked, so for brevity, I'm going to explain value only).

The "property" value reflects value def,
the "attribute" value reflects the value content attribute def.

  • The attribute defines the default value property (ref). This value is also reflected def by the defaultValue property (ref).
  • When the value attribute is set, then the value property changes (ref) *.

That was worded very concisely. I've skipped an important detail. The specification is very clear at this point, so I'll just quote the dirty value flag section:

Each input element has a boolean dirty value flag. The dirty value flag must be initially set to false when the element is created, and must be set to true whenever the user interacts with the control in a way that changes the value.

The value content attribute gives the default value of the input element. When the value content attribute is added, set, or removed, if the control's dirty value flag is false, the user agent must set the value of the element to the value of the value content attribute, if there is one, or the empty string otherwise, and then run the current value sanitization algorithm, if one is defined.

Rob W
  • 341,306
  • 83
  • 791
  • 678
  • Excellent, I can demonstrate this here. http://jsfiddle.net/Psb2Z/1/ After you make the flag dirty, set attribute has no effect. – Esailija Aug 02 '12 at 14:26
2

value and checked properties do not correspond to HTML attributes so they cannot be serialized to HTML. As to why a defaultX property maps to the x attribute, I'm not sure. The alternative, a property x mapping to the x attribute and having another property such as currentX to represent the current value, seems slightly less intuitive because in general a script is going to need the current value more often than the default value.

Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • Yes, the `"value"` and `"checked"`-attributes actually map to `.defaultValue` and `.defaultChecked`. So there would be a conflict. So the really interesting question is why choose these over the current ones. I think Felix Kling's theory is pretty interesting. – Esailija Aug 02 '12 at 14:13
  • @Esailija: Felix's theory matches my long-held assumption, although I've never seen a definitive explanation. I feel I'm probably missing something obvious. – Tim Down Aug 02 '12 at 14:17