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.spec.whatwg.org/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…)