Erik's Blog

《JavaScript 高级程序设计》笔记(6) —— 表单脚本

(更新于 )JavaScript#JavaScript

表单脚本

第 14 章 表单脚本

表单的基础知识

form 元素对应 HTMLFormElement (继承自 HTMLElement), 独有的属性和方法

  • elements : 表单中所有控件的集合 (HTMLCollection)
  • length : 表单中控件的数量
  • method : 要发送的 HTTP 请求的类型,通常是 “get”/“post”;等价于 HTML 的 method 特性
  • action : 接收请求的 URL;等价于 HTML 中的 action 特性
  • enctype : 请求的编码类型;等价于 HTML 中的 enctype 特性
  • name : 表单的名称;等价于 HTML 的 name 特性
  • reset() : 将所有表单域重置为默认值
  • submit() : 提交表单
  • target : 用于发送请求和接收响应的窗口名称;等价于 HTML 的 target 特性
  • acceptCharset : 服务器能够处理的字符集;等价于 HTML 中的 accept-charset 特性

取得表单

  • document.getElementById(“form1”)
  • document.forms[0]
  • document.forms[“formName”]

提交表单

  • 提交按钮 (只有通过提交按钮的方式触发表单的 submit 事件)
    • <input type="submit" value="Submit Form"> 通用提交按钮
    • <button type="submit">Submit Form</button> 自定义提交按钮
    • <input type="image" src="submit.png"> 图像按钮

使用 preventDefault() 阻止提交事件的默认行为,验证后使用 submit() 提交表单。

  • form.submit() : 不会触发 submit 事件

重置表单

  • 重置按钮

    • <input type="reset" value="Reset Form"> 通用重置按钮
    • <button type="reset">Reset Form</button> 自定义重置按钮
  • form.reset() : 会触发 reset 事件

表单字段

  • form.elements : 通过标记中的顺序或 name 特性来访问

    • form.elements[0] 返回第一个表单字段
    • form.elements [“name1”] 返回一个元素或一个 NodeList (包含相同 name 的元素)
  • form.elements.length : 表单字段的数量

  • 共有属性(除 fieldset 元素)

    • disable : 布尔值,当前字段是否被禁用
    • form : 当前字段所属表单;只读
    • name : 当前字段的名称
    • readOnly : 布尔值,当前字段是否只读
    • tabIndex : 当前字段的切换序号
    • value : 要提交到服务器的值,文件字段属性(路径)只读
    • type : 当前字段类型
      • input/button : type 特性的值 可修改
      • 单选列表(<select>...</select>) : “select-one” 只读
      • 多选列表(<select multiple>...</select>) : “select-multiple” 只读
  • 避免表单多次提交 : 第一次触发 submit 事件处理程序时禁用提交按钮(btn.disabled = true)。不能通过 onclick 实现(不同浏览器 submit click 触发顺序不同)

  • 共有方法

    • focus() : 激活表单字段, 触发 focus 事件 (为 type 为 hidden 的 input 元素 或使用 CSS display/visibility 属性隐藏的字段调用该方法会产生错误)
    • blur() : 移走焦点, 触发 blur 事件
  • autofocus : HTML5 新增 如果设置了该属性,就不用再调用 focus()

  • 共有事件

    • blur : 失去焦点时触发
    • change : select 元素选项改变 或 input/textarea 元素失去焦点且 value 改变 时触发, 常用于验证数据
    • focus : 获得焦点时触发, 常用于添加额外功能(下拉菜单等)

文本框脚本

  • input 单行文本框

    • type 特性 “text”
    • size 特性 显示的字符数
    • value 特性 初始值
    • maxlength 特性 可接受最大字符数
  • textarea 多行文本框

    • rows 字符行数
    • cols 字符列数
    • 标签间内容 初始值
    • 不能指定最大字符数
  • 处理文本框的值时,最好不要使用 DOM 方法(对 value 的修改不一定会反应在 DOM 中)

选择文本

  • select() : 选中所有文本,触发 select 事件

  • select 事件 : IE9+ 释放鼠标触发; IE8- 选择第一个字符时触发

    • 可以知道用户什么时候取得了文本,但是不知道内容
  • 取得选择的文本

    • HTML5 添加了 selectionStart 和 selectionEnd 属性,保存开头和结尾的偏移量。使用 substring() 截取文本。 IE9+
    • document.selection IE8-
function getSelectedText (textbox) {
  if (typeof textbox.selectionStart == "number") {
    return textbox.value.substring(textbox.selectionStart, textbox.selectionEnd);
  } else if (document.selection) {
    return document.selection.createRange().text;
  }
}
  • 选择部分文本
    • setSelectionRange() 获得焦点才能看到文本 IE9+
    • createTextRange() + collapse() + moveStart() 和 moveEnd() 选择的字符总数 + select() IE8-
function selectText (textbox, startIndex, stopIndex) {
  if (textbox.setSelectionRange) {
    textbox.setSelectionRange(startIndex, stopIndex);
  } else if (textbox.createTextRange) {
    var range = textbox.createTextRange();
    range.collapse(true);
    range.moveStart("character", startIndex);
    range.moveEnd("character", stopIndex - startIndex);
    range.select();
  }
  textbox.focus();
}

过滤输入

  • 屏蔽字符 通过阻止 keypress 事件的默认行为来屏蔽

  • 操作剪贴板

  • HTML5 剪贴板事件 : beforecopy copy beforecut cut beforepaste paste (取消 copy cut paste 事件的默认行为来屏蔽操作)

  • 访问剪贴板中的数据 : clipboardData 对象。(浏览器中有差异):

    • getData(“数据格式”)
    • setData(“数据类型”, “文本”) : 数据类型 IE 照样支持 “text”/“URL”, 而 Safari/Chrome 只支持 MIME 类型, 不能识别 “text” 类型(使用 “text/plain” 代替)
    • clearData()
var EventUtil = {
  getClipboardText: function (event) {
    var clipboardData = (event.clipboardData || window.clipboardData);
    return clipboardData.getData("text");
  },
  setClipboardText: function (event, value) {
    if (event.clipboardData) {
      return event.clipboardData.setData("text/plain", value);
    } else if (window.clipboardData) {
      return window.clipboardData.setData("text", value);
    }
  },
};
  • 自动切换焦点(不考虑隐藏字段)
(function () {
	function tabForward (event) {
		event = EventUtil.getEvent(event);
		var target = EventUtil.getTarget(event);
		if (target.value.length == target.maxLength) {
			var form = target.form;

			for ... if =  focus
		}
	}
})();

HTML5 约束验证 API

  • required : 必填字段

  • 其他输入类型 : “email”/“url”/…

  • 数值范围 : “number”/“range”/“datetime”/“datetime-local”/“date”/“month”/“week”/“time”

    • min/max/step
    • stepUp(num)
    • stepDown(num)
  • 输入模式 : pattern=RegExp

  • 检测有效性 :

    • checkValidity() 方法可以检测表单中的某个字段是否有效
    • validity : 为什么字段有效或无效 具体信息
      • customError
  • 禁用验证 : novalidate

选择框脚本

select 和 option 元素 HTMLSelectElement 类型

  • add(newOption, relOption) : 在 relOption 之前 添加新 option 元素

  • multiple : 是否支持多选,等价于 HTML 中的 multiple 特性

  • options : 所有 option 元素的 HTMLCollection

  • remove(index) : 移除给定位置的选项

  • selectedIndex : -1/0+ 单选索引 或 多选 第一项的索引

  • size : 选择框中可见的行数,等价于 HTML 中的 size 特性

  • type : “select-one”/“select-multiple”

  • value : “”/..

  • option 元素

    • index : 当前选项在 options 集合中的索引
    • label : 当前选项的标签;等价于 HTML 中的 label 特性
    • selected : 布尔值,表示当前选项是否被选中
    • text : 选项的文本
    • value : 选项的值,等价于 HTML 中的 value 特性

选择选项

  • 单选框 :
    • selectbox.selectedIndex (selectbox.options[selectbox.selectedIndex];)
    • option.selected

添加选项

  • DOM
  • new Option(“Option text”, “Option value”); selectbox.add(newOption, undefined);

移除选项

  • DOM removeChild()
  • selectbox.remove()
  • option = null 相应选项设置为 null

移动和重排选项

  • DOM appendChild()
  • DOM insertBefore()

表单序列化

  • 利用 type name value 实现表单序列化
function serialize (form) {
  // 遍历元素加入数组 join("&")
}

富文本编辑 : 通过一个包含空 HTML 文档的 iframe 元素实现

  • designMode : 默认 “off”,设置为 “on” 使整个文档变得可以编辑(显示插入符号),然后就可以像使用字处理软件一样,通过键盘将文本内容加粗、变成斜体

  • contenteditable : 用户可以编辑该元素。true 表示打开、 false 表示关闭, inherit 表示从父元素那里继承(因为可以在 contenteditable 元素中创建或删除元素)