Элементы управления формы имеют defaultValue свойство , которое является их начальным значением (по умолчанию), указанным в источнике HTML. Значение будет всегда возвращаться к defualtValue при сбросе формы.
внутренние HTML и внешние HTML свойства отражают defaultValue , а не текущее значение (вероятно, что-то есть в алгоритме сериализации фрагмента HTML , который его охватывает).
Далее вы можете изменить Значение текстовой области на любое значение, defaultValue останется прежним.
Вы можете изменить defaultValue , присвоив ему новое значение. Поэтому, если вы копируете элемент управления формы, используя external HTML и хотите, чтобы defaultValue отличался от копируемого элемента, вам необходимо явно установить его.
Метод cloneNode (который я считаю лучшим выбором, чем external HTML) имеет такое же поведение.
function showStuff(el) {
let frag = document.createDocumentFragment();
let span = document.createElement('span');
let br = document.createElement('br');
[['Value property: ', el.value],
['Value attribute: ', el.getAttribute('value')],
['Default value: ', el.defaultValue],
['outerHTML: ', el.outerHTML]
].forEach(props => {
frag.appendChild(span.cloneNode()).textContent = props.join(' ');
frag.appendChild(br.cloneNode());
});
let t = document.getElementById('elData');
t.innerHTML = '';
t.appendChild(frag);
}
<form onsubmit="return false">
<table>
<tr>
<td>Textarea
<td><textarea name="ta0">Initial value</textarea>
<tr>
<td>Show props and atts
<td><button onclick="showStuff(this.form.ta0)">Show stuff</button>
<tr>
<td id="elData" colspan="2">
<tr>
<td>Reset the form
<td><input type="reset">
<tr>
<td>Set defaultValue<br>
<input name="newValue0">
<td><button onclick="this.form.ta0.defaultValue = this.form.newValue0.value">Change default value to this</button>
<tr>
<td>Set value via setAttribute(value)<br>
<input name="newValue1">
<td><button onclick="this.form.ta0.setAttribute('value', this.form.newValue1.value)">Change value attribute to this</button>
<tr>
<td>Clone textarea
<td><button onclick="
let ta1 = this.form.ta0.cloneNode(true);
ta1.name = ta1.name + this.form.elements.length;
form.appendChild(ta1);
">Clone text area</button>
</table>
</form>
defaultValue
Согласно HTML spe c, defualtValue должен отражать значение атрибута содержимого . Для большинства элементов управления формы атрибут value является явным, например <input value="foo">
. Однако для элементов textarea атрибут содержимого значения выводится по начальному значению в HTML, например, <textarea>foo</textarea>
.
Свойство значения DOM (input.value
) будет отражать текущее значение элемента управления однако атрибут value (input.getAttribute('value')
) будет отражать атрибут value в HTML (если только он не изменяется с помощью setAttribute ).
Элементы Textarea исторически не имели атрибута значения, поэтому, хотя они поддерживаются через get / setAttribute , они по сути бессмысленны, поскольку они ни для чего не используются (т. Е. Либо value * 1068) * или defaultValue ). При установке этого параметра он появляется в external HTML, но это не влияет на свойства value или defaultValue .
Алгоритм сериализации требует копирования атрибутов содержимого (то есть тех, которые находятся в источнике HTML или измененных с помощью setAttribute), а не свойств DOM, поэтому, когда они различаются, используется атрибут содержимого. Например, для элемента ввода:
<input name="userID" value="1234">
не имеет значения, на что значение изменяется с помощью пользовательского интерфейса или с помощью свойства значения DOM (например, form.userID = '5678'
), defaultValue останется как "1234". Это можно изменить, установив свойство defaultValue , используя setAttribute , которое не изменит его.
Разорванная связь между свойствами DOM и атрибутами HTML является историей c и в значительной степени исправлено так, что они отражают друг друга, но странности все еще остаются.