Javascript 表單屬性和方法

2023-02-17 10:55 更新

表單(form)以及例如 ?<input>? 的控件(control)元素有許多特殊的屬性和事件。

當(dāng)我們學(xué)習(xí)了這些相關(guān)內(nèi)容后,處理表單會(huì)變得更加方便。

導(dǎo)航:表單和元素

文檔中的表單是特殊集合 document.forms 的成員。

這就是所謂的“命名的集合”:既是被命名了的,也是有序的。我們既可以使用名字,也可以使用在文檔中的編號(hào)來(lái)獲取表單。

document.forms.my; // name="my" 的表單
document.forms[0]; // 文檔中的第一個(gè)表單

當(dāng)我們有了一個(gè)表單時(shí),其中的任何元素都可以通過(guò)命名的集合 form.elements 來(lái)獲取到。

例如:

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

<script>
  // 獲取表單
  let form = document.forms.my; // <form name="my"> 元素

  // 獲取表單中的元素
  let elem = form.elements.one; // <input name="one"> 元素

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

可能會(huì)有多個(gè)名字相同的元素,這種情況經(jīng)常在處理單選按鈕中出現(xiàn)。

在這種情況下,form.elements[name] 將會(huì)是一個(gè)集合。例如:

<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>

這些導(dǎo)航(navigation)屬性并不依賴于標(biāo)簽的結(jié)構(gòu)。所有的控件元素,無(wú)論它們?cè)诒韱沃杏卸嗌?,都可以通過(guò) form.elements 獲取到。

Fieldset 作為“子表單”

一個(gè)表單內(nèi)會(huì)有一個(gè)或多個(gè) <fieldset> 元素。它們也具有 elements 屬性,該屬性列出了 <fieldset> 中的表單控件。

例如:

<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

    // 我們可以通過(guò)名字從表單和 fieldset 中獲取 input
    alert(fieldset.elements.login == form.elements.login); // true
  </script>
</body>

更簡(jiǎn)短的表示方式:?form.name?

還有一個(gè)更簡(jiǎn)短的表示方式:我們可以通過(guò) form[index/name] 來(lái)訪問(wèn)元素。

換句話說(shuō),我們可以將 form.elements.login 寫(xiě)成 form.login。

這也有效,但是會(huì)有一個(gè)小問(wèn)題:如果我們?cè)L問(wèn)一個(gè)元素,然后修改它的 name,之后它仍然可以被通過(guò)舊的 name 訪問(wèn)到(當(dāng)然也能通過(guò)新的 name 訪問(wèn))。

我們可以很直觀地通過(guò)一個(gè)例子看到這個(gè)情況:

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

<script>
  alert(form.elements.login == form.login); // true,與 <input> 相同

  form.login.name = "username"; // 修改 input 的 name

  // form.elements 更新了 name:
  alert(form.elements.login); // undefined
  alert(form.elements.username); // input

  // form 允許我們使用兩個(gè)名字:新的名字和舊的名字
  alert(form.username == form.login); // true
</script>

這通常來(lái)說(shuō)并不是一個(gè)問(wèn)題,因?yàn)槲覀兒苌傩薷谋韱卧氐拿帧?

反向引用:element.form

對(duì)于任何元素,其對(duì)應(yīng)的表單都可以通過(guò) element.form 訪問(wèn)到。因此,表單引用了所有元素,元素也引用了表單。

這是一張示意圖:


例如:

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

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

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

表單元素

讓我們來(lái)談?wù)劚韱慰丶?/p>

input 和 textarea

我們可以通過(guò) input.value(字符串)或 input.checked(布爾值)來(lái)訪問(wèn)復(fù)選框(checkbox)和單選按鈕(radio button)中的 value。

像這樣:

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

input.checked = true; // 對(duì)于復(fù)選框(checkbox)或單選按鈕(radio button)

使用 ?textarea.value? 而不是 ?textarea.innerHTML?

請(qǐng)注意,即使 <textarea>...</textarea> 將它們的 value 作為嵌套的 HTML 標(biāo)簽來(lái)保存,我們也絕不應(yīng)該使用 textarea.innerHTML 來(lái)訪問(wèn)它。

它僅存儲(chǔ)最初在頁(yè)面上的 HTML,而不是存儲(chǔ)的當(dāng)前 value。

select 和 option

一個(gè) <select> 元素有 3 個(gè)重要的屬性:

  1. ?select.options? —— ?<option>? 的子元素的集合,
  2. ?select.value? —— 當(dāng)前所選擇的 ?<option>? 的 value
  3. ?select.selectedIndex? —— 當(dāng)前所選擇的 ?<option>? 的編號(hào)。

它們提供了三種為 <select> 設(shè)置 value 的不同方式:

  1. 找到對(duì)應(yīng)的 ?<option>? 元素(例如在 ?select.options? 中),并將其 ?option.selected? 設(shè)置為 ?true?。
  2. 如果我們知道新的值:將 ?select.value? 設(shè)置為對(duì)應(yīng)的新的值。
  3. 如果我們知道新的選項(xiàng)的索引:將 ?select.selectedIndex? 設(shè)置為對(duì)應(yīng) ?<option>? 的編號(hào)。

下面是這三種方式的示例:

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

<script>
  // 下面這三行做的都是同一件事
  select.options[2].selected = true;
  select.selectedIndex = 2;
  select.value = 'banana';
  // 請(qǐng)注意:選項(xiàng)編號(hào)是從零開(kāi)始的,所以編號(hào) 2 表示的是第三項(xiàng)
</script>

和大多數(shù)其它控件不同,如果 <select> 具有 multiple 特性(attribute),則允許多選。盡管這個(gè)特性(attribute)很少被用到。

對(duì)于多選的值,使用第一種設(shè)置值的方式:在 <option> 子元素中添加/移除 selected 屬性。

這是一個(gè)如何從多選的 <select> 中獲取選擇的值的示例:

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

<script>
  // 從 multi-select 中獲取所有選定的 `value`
  let selected = Array.from(select.options)
    .filter(option => option.selected)
    .map(option => option.value);

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

<select> 元素的完整規(guī)范可以在規(guī)范 https://html.spec.whatwg.org/multipage/forms.html#the-select-element 中找到。

new Option

在 規(guī)范 中,有一個(gè)很好的簡(jiǎn)短語(yǔ)法可以創(chuàng)建一個(gè) <option> 元素:

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

此語(yǔ)法是可選的。我們可以使用 document.createElement('option') 并手動(dòng)設(shè)置特性(attribute)。不過(guò),這種語(yǔ)法寫(xiě)起來(lái)可能會(huì)更短,其參數(shù)如下:

  • ?text? —— ?<option>? 中的文本,
  • ?value? —— ?<option>? 的 ?value?,
  • ?defaultSelected? —— 如果為 ?true?,那么 ?selected? HTML-特性(attribute)就會(huì)被創(chuàng)建,
  • ?selected? —— 如果為 ?true?,那么這個(gè) ?<option>? 就會(huì)被選中。

defaultSelected 和 selected 的區(qū)別是,defaultSelected 設(shè)置的是 HTML-特性(attribute),我們可以使用 option.getAttribute('selected') 來(lái)獲得。而 selected 設(shè)置的是選項(xiàng)是否被選中。

在實(shí)際使用中,通常應(yīng)該將同時(shí)將這兩個(gè)值設(shè)置為 true 或 false。(或者,直接省略它們;兩者都默認(rèn)為 false。)

例如,下面是一個(gè)新的未被選中的選項(xiàng):

let option = new Option("Text", "value");
// 創(chuàng)建 <option value="value">Text</option>

相同的選項(xiàng),但被選中了:

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

?<option>? 元素具有以下屬性:

?option.selected ?

?<option>? 是否被選擇。

?option.index ?

?<option>? 在其所屬的 ?<select>? 中的編號(hào)。

?option.text ?

?<option>? 的文本內(nèi)容(可以被訪問(wèn)者看到)。

參考資料

總結(jié)

表單導(dǎo)航:

?document.forms ?

一個(gè)表單元素可以通過(guò) ?document.forms[name/index]? 訪問(wèn)到。

?form.elements ?

表單元素可以通過(guò) form.elements[name/index] 的方式訪問(wèn),或者也可以使用 form[name/index]。elements 屬性也適用于 <fieldset>。

?element.form ?

元素通過(guò) ?form? 屬性來(lái)引用它們所屬的表單。

value 可以被通過(guò) input.value,textarea.valueselect.value 等來(lái)獲取到。(對(duì)于單選按鈕(radio button)和復(fù)選框(checkbox),可以使用 input.checked 來(lái)確定是否選擇了一個(gè)值。

對(duì)于 <select>,我們可以通過(guò)索引 select.selectedIndex 來(lái)獲取它的 value,也可以通過(guò) <option> 集合 select.options 來(lái)獲取它的 value

這些是開(kāi)始使用表單的基礎(chǔ)。我們將在本教程中進(jìn)一步介紹更多示例。

在下一章中,我們將介紹可能在任何元素上出現(xiàn),但主要在表單上處理的 focus 和 blur 事件。

任務(wù)


在 select 元素中添加一個(gè)選項(xiàng)

重要程度: 5

下面是一個(gè) <select> 元素:

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

使用 JavaScript 來(lái)實(shí)現(xiàn):

  1. 顯示所選選項(xiàng)的值和文本。
  2. 添加一個(gè)選項(xiàng):?<option value="classic">Classic</option>?。
  3. 使之變?yōu)榭蛇x的。

請(qǐng)注意,如果你已正確完成所有事項(xiàng),那么 alert 應(yīng)該顯示 blues。


解決方案

解決方案,分步進(jìn)行:

<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>


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)