深刻理解 form 系列(一)-- HTML 表單

表單元素

從 HTML 到 HTML5, 表單相關的元素已經獲得了很大的擴充, 基本可以知足咱們常見的需求。但在實際工做中, 由於交互或者瀏覽器兼容的須要, 有時候不得不對原生的表單元素進行擴展或者模擬。但在此以前, 清楚的瞭解並掌握各類表單元素仍是很重要的。在本文中, 咱們將對錶單元素 (默認是指 HTML5 表單元素)進行詳細的闡述。html

form 1

  • form 會自動處理 submit 事件 (submit 事件一般由 type=submitinput 或者 button 的元素觸發)
  • form 會自動作一層校驗,使用 form.novalidate 能夠關閉原生的 validate
  • form 會根據每個表單元素的 name 取得對應的用戶輸入, 而後將 form dataquery string 的形式添加到 action 屬性對應的 url 後面。默認的請求方法是 GET, 默認的action 是當前的 url。
  • event.target.elements 將會返回全部表單元素
<form novalidate>
  <input name='username' required/>
  <input name='passworkd' type='password' required/>
  <input name='email' type='email'/>
  <input type='submit' value='submit'/>
</form>
運行上面的代碼能夠看到, 提交表單以後,瀏覽器的地址會增長相似這樣的 query string ?username=tom&passworkd=123&email=test%40gmail.com

可交互型 elements

須要跟用戶進行交互,並得到用戶輸入的這一類表單元素,咱們把它們歸類爲 可交互型表單元素react

下面列舉出來了一些:npm

  • input: 經常使用的 type 有 checkbox, tel, number, email
  • textarea
  • select
  • option

反饋型 elements

只是單純地反饋信息, 不須要跟用戶進行交互的表單元素,咱們把它們歸類爲 反饋型表單元素segmentfault

下面列舉出來了一些:瀏覽器

  • meter
  • output
<form oninput="result.value=parseInt(a.value)+parseInt(b.value)">
    <input type='number' value='50' name='a' />
    <input type='number' value='10' name='b' />
    <output name='result'>60</output>
</form>
對於 output, 能夠在 form.oninput 設置計算出來的 value

分組型 elements

用來對多個表單元素進行分組的這一類表單元素, 咱們把他們歸類爲 分組型表單元素優化

下面列舉出來了一些:ui

  • fieldset
  • optgroup
<form>
  <select>
    <optgroup label='group1'>
      <option>1</option>
      <option>2</option>
      <option>3</option>
    </optgroup>
    <optgroup label='group2'>
      <option>4</option>
      <option>5</option>
      <option>6</option>
    </optgroup>
    <optgroup label='group3'>
      <option>7</option>
      <option>8</option>
      <option>9</optioin>
    </optgroup>
  </select>
</form>

label

  • for 可與對應關聯了 id 的交互 element 相連
  • 能夠用來包裹可交互 elment, 包括多個, 控制第一個
  • 不建議嵌套 label
<form>
  <fieldset>
    <legend>Title</legend>
    <label for='radio'>Click me</label>
    <input type='radio' id='radio'/>
  </fieldset>
</form>
<form>
  <fieldset>
    <legend>用戶信息</legend>
    <label>
      男 <input type='radio' name='gender' id='male' />
    </label>
    <label>
      女 <input type='radio' name='gender' id='female'/>
    </label>
  </fieldset>
</form>

用 JavaScript 處理表單

field 的抽象

最基本的結構:url

field: {
    name: String,
    value: String || String[]
  }
  • valueString[] 一般是用 , 分割後合成爲一個 String
  • 對於複雜結構的 name 可使用 keyPath
const fromKeyValues = {
    'user.name': 'Tom',
    'user.phone[0].number': '123456',
    'user.phone[0].type': 'mobile'
  };

  const fromValues = {
    user: {
      name: 'Tom',
      phone: [
        {
          number: '123456',
          type: 'mobile'
        }
      ]
    }
  };

若是對上面的代碼不是很清楚的, 請參考 qscode

一個完整的實現

  • 阻止 form 默認的 submit 事件
  • checkbox 須要拿 checked 而不是 value
  • select-multiple 須要存多個值
  • 除了以上幾個特殊的交互元素以外, 其餘的都默認從 value 中去取值

form.htmlorm

<form>
    <fieldset>
        <legend>Login</legend>
        <input name='username' placeholder='username' minlength='2'/>
        <input name='password' type='password' placeholder='password'/>
        <label>
            remember password
            <input name='checkbox' type='checkbox'/>
        </label>
    </fieldset>
    <fieldset>
        <div class="gender">
            <legend>More Info</legend>
            <label>
                男
                <input name='gender' type='radio' value='male' />
            </label>
            <label>
                女
                <input name='gender' type='radio' value='female' />
            </label>
        </div>
        <select name='select' multiple>
            <option>1</option>
            <optgroup label='2'>
                <option>2.1</option>
                <option>2.2</option>
            </optgroup>
        </select>
    </fieldset>
    <button type='submit'>Submit</button>
</form>

form.js

var $form = document.querySelector('form');

function getFormValues(form) {
  var values = {};
  var elements = form.elements; // elemtns is an array-like object

  for (var i = 0; i < elements.length; i++) {
    var input = elements[i];
    if (input.name) {
      switch (input.type.toLowerCase()) {
        case 'checkbox':
          if (input.checked) {
            values[input.name] = input.checked;
          }
          break;
        case 'select-multiple':
          values[input.name] = values[input.name] || [];
          for (var j = 0; j < input.length; j++) {
            if (input[j].selected) {
              values[input.name].push(input[j].value);
            }
          }
          break;
        default:
          values[input.name] = input.value;
          break;
      }
    }

  }

  return values;
}

$form.addEventListener('submit', function(event) {
  event.preventDefault();
  getFormValues(event.target);
  console.log(event.target.elements);
  console.log(getFormValues(event.target));
});

結尾

若是你還想繼續瞭解在 react 中如何使用 form, 請移步個人另外一篇博客 React.js -- 優化你的表單


  1. MDN 上關於 form 的介紹
相關文章
相關標籤/搜索