欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  web前端

深入理解 HTML 表单

程序员文章站 2022-03-24 16:46:12
...
表单元素

从 HTML 到 HTML5, 表单相关的元素已经得到了很大的扩充, 基本能够满足我们常见的需求。但在实际工作中, 因为交互或者浏览器兼容的需要, 有时候不得不对原生的表单元素进行扩展或者模拟。但在此之前, 清楚的了解并掌握各种表单元素还是很重要的。在本文中, 我们将对表单元素 (默认是指 HTML5 表单元素)进行详细的阐述。

form

●form 会自动处理 submit 事件 (submit 事件通常由 type=submit 的 input 或者 button 的元素触发)

●form 会自动做一层校验,使用 form.novalidate 可以关闭原生的 validate

●form 会根据每一个表单元素的 name 取得对应的用户输入, 然后将 form data 以 query 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

需要跟用户进行交互,并获得用户输入的这一类表单元素,我们把它们归类为 可交互型表单元素。

下面列举出来了一些:

●input: 常用的 type 有 checkbox, tel, number, email 等

●textarea

●select

●option

反馈型 elements

只是单纯地反馈信息, 不需要跟用户进行交互的表单元素,我们把它们归类为 反馈型表单元素。

下面列举出来了一些:

●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

用来对多个表单元素进行分组的这一类表单元素, 我们把他们归类为 分组型表单元素。

下面列举出来了一些:

●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 的抽象

最基本的结构:

 field: {
    name: String,
    value: String || String[]
  }

●value 的 String[] 通常是用 , 分割后合成为一个 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'
        }
      ]
    }
  };

如果对上面的代码不是很清楚的, 请参考 qs

一个完整的实现

●阻止 form 默认的 submit 事件

●checkbox 需要拿 checked 而不是 value

●select-multiple 需要存多个值

●除了以上几个特殊的交互元素之外, 其他的都默认从 value 中去取值

form.html

<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>
        <p class="gender">
            <legend>More Info</legend>
            <label>
                男                <input name='gender' type='radio' value='male' />
            </label>
            <label>
                女                <input name='gender' type='radio' value='female' />
            </label>
        </p>
        <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));
});
相关标签: HTML 表单