2022 年 2 月 9 日

表单属性和方法

表单和控件元素(如 <input>)有很多特殊属性和事件。

当我们了解这些属性和事件时,使用表单会更加方便。

导航:表单和元素

文档表单是特殊集合 document.forms 的成员。

这是一个所谓的“命名集合”:它既有名称又有顺序。我们可以使用文档中的名称或编号来获取表单。

document.forms.my; // the form with name="my"
document.forms[0]; // the first form in the document

当我们有一个表单时,任何元素都可以在命名集合 form.elements 中使用。

例如

<form name="my">
  <input name="one" value="1">
  <input name="two" value="2">
</form>

<script>
  // get the form
  let form = document.forms.my; // <form name="my"> element

  // get the element
  let elem = form.elements.one; // <input name="one"> element

  alert(elem.value); // 1
</script>

可能有多个具有相同名称的元素。单选按钮和复选框中常见这种情况。

在这种情况下,form.elements[name] 是一个集合。例如

<form>
  <input type="radio" name="age" value="10">
  <input type="radio" name="age" value="20">
</form>

<script>
let form = document.forms[0];

let ageElems = form.elements.age;

alert(ageElems[0]); // [object HTMLInputElement]
</script>

这些导航属性不依赖于标记结构。所有控件元素,无论它们在表单中的深度如何,都可以在 form.elements 中找到。

字段集作为“子表单”

一个表单可能包含一个或多个 <fieldset> 元素。它们还具有 elements 属性,该属性列出了其中的表单控件。

例如

<body>
  <form id="form">
    <fieldset name="userFields">
      <legend>info</legend>
      <input name="login" type="text">
    </fieldset>
  </form>

  <script>
    alert(form.elements.login); // <input name="login">

    let fieldset = form.elements.userFields;
    alert(fieldset); // HTMLFieldSetElement

    // we can get the input by name both from the form and from the fieldset
    alert(fieldset.elements.login == form.elements.login); // true
  </script>
</body>
更简洁的表示法:form.name

有一个更简洁的表示法:我们可以将元素访问为 form[index/name]

换句话说,我们可以写 form.login,而不是 form.elements.login

这也可以,但有一个小问题:如果我们访问一个元素,然后更改其 name,那么它仍然可以在旧名称(以及新名称)下找到。

在一个示例中很容易看到这一点

<form id="form">
  <input name="login">
</form>

<script>
  alert(form.elements.login == form.login); // true, the same <input>

  form.login.name = "username"; // change the name of the input

  // form.elements updated the name:
  alert(form.elements.login); // undefined
  alert(form.elements.username); // input

  // form allows both names: the new one and the old one
  alert(form.username == form.login); // true
</script>

不过,这通常不是问题,因为我们很少更改表单元素的名称。

反向引用:element.form

对于任何元素,表单都可用作 element.form。因此,一个表单引用所有元素,而元素引用表单。

以下是图片

例如

<form id="form">
  <input type="text" name="login">
</form>

<script>
  // form -> element
  let login = form.login;

  // element -> form
  alert(login.form); // HTMLFormElement
</script>

表单元素

让我们讨论一下表单控件。

input 和 textarea

我们可以将它们的值访问为 input.value(字符串)或 input.checked(布尔值),对于复选框和单选按钮来说。

像这样

input.value = "New value";
textarea.value = "New text";

input.checked = true; // for a checkbox or radio button
使用 textarea.value,而不是 textarea.innerHTML

请注意,即使 <textarea>...</textarea> 将其值作为嵌套 HTML 保存,我们也绝不应使用 textarea.innerHTML 来访问它。

它只存储页面上最初的 HTML,而不是当前值。

select 和 option

一个 <select> 元素有 3 个重要的属性

  1. select.options<option> 子元素的集合,
  2. select.value – 当前选中的 <option>
  3. select.selectedIndex – 当前选中的 <option>编号

它们提供了三种不同的方式来为 <select> 设置值

  1. 找到相应的 <option> 元素(例如,在 select.options 中),并将它的 option.selected 设置为 true
  2. 如果我们知道一个新值:将 select.value 设置为新值。
  3. 如果我们知道新选项的编号:将 select.selectedIndex 设置为该编号。

以下是所有这三种方法的示例

<select id="select">
  <option value="apple">Apple</option>
  <option value="pear">Pear</option>
  <option value="banana">Banana</option>
</select>

<script>
  // all three lines do the same thing
  select.options[2].selected = true;
  select.selectedIndex = 2;
  select.value = 'banana';
  // please note: options start from zero, so index 2 means the 3rd option.
</script>

与大多数其他控件不同,如果 <select> 具有 multiple 属性,则它允许一次选择多个选项。不过,此属性很少使用。

对于多个选定的值,请使用第一种设置值的方法:从 <option> 子元素中添加/删除 selected 属性。

以下是如何从多选框中获取选定值的一个示例

<select id="select" multiple>
  <option value="blues" selected>Blues</option>
  <option value="rock" selected>Rock</option>
  <option value="classic">Classic</option>
</select>

<script>
  // get all selected values from multi-select
  let selected = Array.from(select.options)
    .filter(option => option.selected)
    .map(option => option.value);

  alert(selected); // blues,rock
</script>

<select> 元素的完整规范可在规范 https://html.whatwg.com.cn/multipage/forms.html#the-select-element 中获得。

new Option

规范 中,有一个简洁的语法来创建 <option> 元素

option = new Option(text, value, defaultSelected, selected);

此语法是可选的。我们可以使用 document.createElement('option') 并手动设置属性。不过,它可能更短,因此这里列出了参数

  • text – 选项内的文本,
  • value – 选项值,
  • defaultSelected – 如果为 true,则会创建 selected HTML 属性,
  • selected – 如果为 true,则会选择此选项。

defaultSelectedselected 之间的区别在于,defaultSelected 设置 HTML 属性(我们可以使用 option.getAttribute('selected') 获取),而 selected 设置选项是否被选中。

在实践中,通常应将两个值都设置为 truefalse。(或者,直接省略它们;两者都默认为 false。)

例如,这是一个新的“未选中”选项

let option = new Option("Text", "value");
// creates <option value="value">Text</option>

相同的选项,但已选中

let option = new Option("Text", "value", true, true);

选项元素具有属性

option.selected
选项是否被选中。
option.index
选项在其 <select> 中的其他选项中的编号。
option.text
选项的文本内容(访问者可见)。

参考

摘要

表单导航

document.forms
表单可用作 document.forms[name/index]
form.elements
表单元素可用作 form.elements[name/index],或仅使用 form[name/index]elements 属性也适用于 <fieldset>
element.form
元素在 form 属性中引用其表单。

值可作为 input.valuetextarea.valueselect.value 等使用。(对于复选框和单选按钮,使用 input.checked 确定是否选择了值。)

对于 <select>,还可以通过索引 select.selectedIndex 或通过选项集合 select.options 获取值。

这些是开始使用表单的基础知识。我们将在本教程中遇到许多示例。

在下一章中,我们将介绍 focusblur 事件,这些事件可能发生在任何元素上,但主要在表单上处理。

任务

重要性:5

有一个 <select>

<select id="genres">
  <option value="rock">Rock</option>
  <option value="blues" selected>Blues</option>
</select>

使用 JavaScript

  1. 显示所选选项的值和文本。
  2. 添加选项:<option value="classic">Classic</option>
  3. 使其被选中。

请注意,如果您已正确完成所有操作,则您的警报应显示 blues

解决方案,逐步

<select id="genres">
  <option value="rock">Rock</option>
  <option value="blues" selected>Blues</option>
</select>

<script>
  // 1)
  let selectedOption = genres.options[genres.selectedIndex];
  alert( selectedOption.value );

  // 2)
  let newOption = new Option("Classic", "classic");
  genres.append(newOption);

  // 3)
  newOption.selected = true;
</script>
教程地图

评论

在评论之前阅读此内容…
  • 如果您有改进建议 - 请 提交 GitHub 问题或提交拉取请求,而不是发表评论。
  • 如果您无法理解文章中的内容 – 请详细说明。
  • 要插入一些代码,请使用 <code> 标记,对于多行代码 – 将其包装在 <pre> 标记中,对于超过 10 行的代码 – 使用沙盒(plnkrjsbincodepen…)