第十六篇 表单脚本

by caix in 深圳

表单的基础知识

在 HTML 中,表单是由 <form> 元素来表示的,而在 JavaScript 中,表单对应的则是 HTMLFormElement 类型

HTMLFormElement 具有下列独有的属性和方法

acceptCharset:服务器能够处理的字符集;等价于 HTML 中的 accept-charset 特性

action:接受请求的 URL;等价于 HTML 中的 action 特性

elements:表单中所有控件的集合

enctype:请求的编码类型;等价于 HTML 中的 enctype 特性

length:表单中控件的数量

method:要发送的 HTTP 请求类型,通常是"get"或"post";等价于 HTML 的 method 特性

name:表单的名称;等价于 HTML 的 name 特性

reset():将所有表单域重置为默认值

submit():提交表单

target:用于发送请求和接收响应的窗口名称;等价于 HTML 的 target 特性
获取表单
1、通过 document.getElementById() 与其他元素一样

2、通过 document.forms 通过集合的方式获取,可以通过 数值索引 或 name值 获取表单

var firstForm = document.forms[0]; 

=> 获取页面中的第一个表单

var myForm = document.forms["form2"]; 

=> 获取页面中 name属性值 为 form2 的表单
提交表单
1、通过提交按钮或图像按钮提交表单

   在表单中使用 <input> 或者 <button> 标签,并将其 type属性 设置为submit,图像按钮则是将 <input> 的type属性设置为 image
   
   以这种方式提交表单时,浏览器将请求发送给服务器之前会触发 submit事件
   
   并可以验证表单是否提交,不提交的话通过阻止该事件的默认行为取消提交表单。如下:

<input type = "submit" value = "提交表单">
<button type = "submit" value = "提交表单">
<input type = "image" src = "...">
    
var form = document.getElementById("myForm");
EventUtil.addHandler(form , "submit" , function(event) {
    event = EventUtil.getEvent(event); => 取得事件对象
    EventUtil.preventDefault(event); => 阻止默认行为,取消提交表单
})

2、调用submit() 方法提交表单

这种方法无需提交按钮,任何时候都可以提交表单,但是调用 submit() 方法的时候,不会触发 submit事件

所以要在调用 submit() 方法之前验证表单

var form = document.getElementById("myForm");
form.submit();
重置表单
1、使用 type值 为 reset 的 <input><button>

   用户单击重置按钮时,会触发 reset事件,因此可以取消重置操作
   
<input type = "reset" value = "重置表单">
<button type = "reset" value = "重置表单">

var form = document.getElementById("myForm");
EventUtil.addHandler(form , "reset" , function({
    event = EventUtil.getEvent(event);
    EventUtil.preventDefault(event); => 阻止表单重置
}))

2、使用表单的 reset() 方法

   调用 reset() 方法时,也会触发 reset事件
   
   var form = document.getElementById("myForm");
   form.reset();
表单字段

每个表单都有elements 属性,是表单中所有表单元素(字段)的有序列表

可以按照位置和 name 特性来访问表单中的字段

var form = document.getElementById("form1"); 

=> 取得表单中的第一个字段
var field1 = form.elements[0]; 

=> 取得 name 为 textbox1 的字段
var field2 = form.elements["textbox1"]; 

=> 取得表单中包含的字段的数量
var fieldCount = form.elements.length; 
1、表单共有的字段属性

disabled:布尔值,表示当前字段是否被禁用

form:指向当前字段所属表单的指针;只读

name:当前字段的名称

readOnly:布尔值,表示当前字段是否只读

tabIndex:表示当前字段的切换(tab)序号

type:当前字段的类型,如"checkbox"、"radio",等等

value:当前字段将被提交给服务器的值。对文件字段来说,这个属性是只读的,包含着文在计算机中的路径

2、表单共有的字段方法

focus() :将浏览器的焦点设置到表单字段

blur() :移出元素的焦点

3、表单共有的字段事件

blur:当前字段失去焦点时触发

change:对于 <input>和<textarea> 元素,在它们失去焦点且 value 值改变时触发;对 <select> 元素,在其选项改变时触发

focus:当前字段获得焦点时触发

文本框脚本

选择脚本

文本框的 select() 方法用于选择文本框中所有文本,没有参数

1、选择事件

   用户选择文本的时候,会触发 select 事件
   
2、取得选择的全部文本 

   使用 selectionStart 和 selectionEnd 两个属性可以取得所选文本
   
   function getSelectedText (textbox) {
        return textbox.value.substring(textbox.selectionStart ,  textbox.selectionEnd);
   }

3、取得选择的部分文本 setSelectionRange () 方法

   使用 setSelectionRange () 方法获得所选的部分文本,该方法接收两个参数
   
   第一个字符的索引
   
   最后一个字符的索引
   
   从0开始算,不包括最后一个字符索引
   
   textbox.value = "Hello World!";
   textbox.setSelectionRange(0 , textbox.value.length); => "Hello World!"
   textbox.setSelectionRange(0 , 3);  => 前3个字符——"Hel"
过滤输入
1、屏蔽字符

只允许输入数值

EventUtil.addHandler(textbox, "keypress", function(event){ 
  	event = EventUtil.getEvent(event); 
    var target = EventUtil.getTarget(event); 
  	var charCode = EventUtil.getCharCode(event); 
  	if (!/\d/.test(String.fromCharCode(charCode)) && charCode > 9 && !event.ctrlKey){ 
  		EventUtil.preventDefault(event); 
  	} 
}); 

2、操作剪贴板

  6个剪贴板事件
  
     beforecopy:在发生复制操作前触发
     
     copy:在发生复制操作时触发
     
     beforecut:在发生剪切操作前触发
     
     cut:在发生剪切操作时触发
     
     beforepaste:在发生粘贴操作前触发
     
     paste:在发生粘贴操作时触发
     
  clipboardData 对象可以访问剪贴板中的数据    
  
      getData():接收一个参数,要取得的数据类型
      
      setData():接收两个参数,数据类型、要放在剪贴板中的文本
      
      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); 
  		} 
  	}, 
    
  //省略的代码
}; 
自动切换焦点
可以在前一个文本框中的字符达到最大数量后,自动将焦点切换到下一个文本框
HTML5 约束验证 API
1、必填字段

  在 DOM 元素中添加 required 属性
  
  任何带有 required属性 的字段都必须有值,否则无法提交表单
  
  此属性适用于 <input>、<textarea> 和 <select> 字段
  
  <input type="text" name="username" required>
  
  => 通过JS检测对应元素的 required属性 来判断表单字段是否为必填
  let isRequired = document.forms[0].elements['username'].required;
  
  => 检测浏览器是否支持 required属性 
  let isRequiredSupported = 'required' in document.createElement('input');
 
2、新增类型

  HTML5为 <input>元素 增加了几个新的 type值  
  
  其中两个得到广泛支持的'email'和'url',二者都有浏览器提供的自定义验证
  
  <input type="email" name="email">
  <input type="url" name="homepage">
  
  浏览器在匹配模式时都存在问题,最明显的是文本"-@-"会被认为是有效的电子邮件地址
  
  对于这两个新类型,除非应用了required属性,否则空字段是有效的
  
  除了以上两种 type,还有数值类型的:
  
  number
  
  range
  
  datetime
  
  datetime-local
  
  date
  
  month
  
  week
  
  time
  
  并非所有主流浏览器都支持这些类型,因此使用时要当心

  且这些数值类型,都可以指定 min属性 和 max属性,以及 step属性
  
  每个属性在JS中也可以通过对应元素的 DOM属性 来访问和修改
  
  还有两个方法从当前值加上或减去对应的数值:
  
  stepUp(num) 
  
  stepDown(num)
  
  input.stepUp(); => 加 1 
  input.stepUp(5); => 加 5 
  input.stepDown(); => 减 1 
  input.stepDown(10); => 减 10 
  
 3、输入模式
 
   HTML5 为文本字段新增了 pattern 属性。这个属性的值是一个正则表达式,用于匹配文本框中的值
   
   限制只能输入数字
  <input type="text" pattern="\d+" name="count">
  
   与新增的输入类型一样,指定 pattern属性 也不会阻止用户输入无效内容
   
   模式会应用到值,然后浏览器会知道值是否有效
   
4、检测有效性

   使用 checkValidity()方法 可以检测表单中的某个字段是否有效,如果字段的值有效,这个方法返回 true,否则返回 false
   
   => 检查字段是否有效
    if(document.forms[0].elements[0].checkValidity()) {
       // 有效
    } else {
       // 无效
    }
    
   => 检查整个表单是否有效
   if(document.forms[0].checkValidity()) {
      // 表单有效,继续
   } else {
      // 表单无效
   }
   
   heckValidity()方法 只会告诉我们字段是否有效
   
   而 validity属性 会告诉我们字段为什么有效或无效。这个属性是一个对象,包含一系列返回布尔值的属性
   
   通过 validity属性 可以检查表单字段的有效性,从而获取更具体的信息
   
   if(input.validity && !input.validity.valid) {
    if(input.validity.valueMissing){
        console.log('Please specify a value');
    }
   }

   
 5、禁用验证
 
   通过设置 novalidate 属性,可以告诉表单不进行验证
   
   <form method="post" action="/signup" novalidate>
      ...
   </form>
   
   => 这个值也可以通过JS属性noValidate检索或设置
   => 关闭验证
   document.forms[0].noValidate = true;
   
   如果一个表单中有多个提交按钮,为了指定点击某个提交按钮不必验证表单,可以在相应的按钮上添加 formnovalidate 属性
   
   <form method="post" action="/signup">
     <input type="submit" formnovalidate name="btnNoValidate" value="Non-validating submit">
   </form>
   
 => 关闭验证
   document.forms[0].elements['btnNoValidate'].formNoValidate = true;

选择框脚本

选择框是使用 <select> 和 <option> 元素创建的

HTML Select Element类型 额外提供以下属性和方法

   add(newOption, relOption) 在 relOption 之前向控件中添加新的option
   
   multiple 布尔值,表示是否允许多选
   
   options 控件中所有 <option>元素 的 HTMLCollection
   
   remove(index) 移除给定位置的选项
   
   selectedIndex 选中项基于0的索引值。如果没有选中项则为 -1。对于允许多选的列表,始终是第一个选项的索引
   
   size 选择框中可见的行数。
每个 <option> 元素在 DOM 中都由一个 HTMLOptionElement对象 表示,此类型为方便数据存取添加了以下属性:

   index 选项在options集合中的索引

   label 选项的标签,等价于HTML的label属性

   selected 布尔值,表示是否选中了当前选项。

      要取得所有选中项,需要循环选项集合逐一检测 selected 属性

   text 选项的文本

   value  选项的值
  在操作选项时,最好使用特定于选项的属性,因为这些属性得到了跨浏览器的良好支持
  
  选择框的 change事件 与其他表单字段是不一样的
  
  其他表单字段会在自己的值改变后触发 change事件,然后字段失去焦点
  
  而选择框会在选中一项时立即触发 change事件
选择选项
对于单选的选择框,访问选中项可以使用选择框的 selectedIndex 属性,也可以利用选项的 selected 属性为 true 

let selectedOption = selectbox.options[selectbox.selectedIndex]; 
selectbox.options[0].selected = true; 

对于多选的选择框,访问选择框的 selectedIndex 属性只能获取第一个选中项,访问选项的 selected 属性为 true 可以获取所有的选中项
添加选项

有两种方式

1、使用 Option 构造函数创建选项,接收两个参数:文本(text)、值(value),第二个参数可选,兼容 DOM 的浏览器会返回一个 <option> 元素

let newOption = new Option("Option text", "Option value"); 
selectbox.appendChild(newOption); => 在 IE8 及之前版本中有问题

2、使用选择框的 add() 方法,接收两个参数:要添加的新选项、位于新选项之后的选项,第二个参数设置为null表示在列表的最后添加一个选项

let newOption = new Option("Option text", "Option value"); 
selectbox.add(newOption, undefined); => 最佳方案,undefined可以兼容IE
移除选项

有两种方式

1、利用选择框的 remove() 方法移除选项,接收一个参数: 要移除选项的索引

selectbox.remove(0);  => 移除第一个选项

2、利用将选项设置为 null 可以移除选项

selectbox.options[0] = null;   => 移除第一个选项
移动和重排选项

appendChild() 方法会从其父元素移除然后插入指定位置

insertBefore() 插入到指定位置

移动选项
let selectbox1 = document.getElementById("selLocations1"); 
let selectbox2 = document.getElementById("selLocations2");

selectbox2.appendChild(selectbox1.options[0]); 
重排选项
let optionToMove = selectbox.options[1]; 

selectbox.insertBefore(optionToMove, selectbox.options[optionToMove.index-1]); 

表单序列化

字段名和值是 URL 编码的并以和号(&)分隔。

禁用字段不会发送。

复选框或单选按钮只在被选中时才发送。

类型为"reset"或"button"的按钮不会发送。

多选字段的每个选中项都有一个值。

通过点击提交按钮提交表单时,会发送该提交按钮;否则,不会发送提交按钮。类型为"image"的<input>元素视同提交按钮。

<select>元素的值是被选中<option>元素的 value 属性。如果<option>元素没有 value 属性,则该值是它的文本。

富文本编辑

原理
在空白 HTML 文件中嵌入一个 iframe。通过 designMode 属性设置为on,将这个空白文档变成可编辑的
方法
方式一

页面嵌入一个包含空 HTML 页面的 iframe 。通过设置 designMode 属性,这个空白的 HTML 页面可以被编辑,而编辑对象则是该页面 <body> 元素的 HTML 代码。designMode 属性有两个可能的值:"off"(默认值)和 "on"。"on"表示整个文档可以编辑。

方式二

把 contenteditable 属性应用给页面中的任何元素,然后用户立即就可以编辑该元素。
与富文本交互
document.execCommand()
document.execCommand()

三个参数

  要执行的命令
  
  表示浏览器是否为命令提供用户界面的布尔值 (始终false)
  
  执行命令必须的值

2f5f4334c9d610a6ed2289f218ef02e7.png

eefb012e2a05baf987d2f0b0664f3e7a.png

queryCommandEnabled()
用于确定当前选中文本或光标所在位置是否可以执行相关命令
queryCommandState()
确定相关命令是否应用到了当前文本选区
queryCommandValue()
返回执行命令时使用的值
富文本选择
getSelection()
可以获得富文本编辑器的选区
返回的对象有以下属性

anchorNode:选区开始的节点。

anchorOffset:在 anchorNode 中,从开头到选区开始跳过的字符数。

focusNode:选区结束的节点。

focusOffset:focusNode 中包含在选区内的字符数。

isCollapsed:布尔值,表示选区起点和终点是否在同一个地方。

rangeCount:选区中包含的 DOM 范围数量。
返回的对象有以下方法

addRange(range):把给定的 DOM 范围添加到选区。

collapse(node, offset):将选区折叠到给定节点中给定的文本偏移处。

collapseToEnd():将选区折叠到终点。

collapseToStart():将选区折叠到起点。

containsNode(node):确定给定节点是否包含在选区中。

deleteFromDocument():从文档中删除选区文本。与执行 execCommand("delete", false, null)命令结果相同。

extend(node, offset):通过将 focusNode 和 focusOffset 移动到指定值来扩展选区。

getRangeAt(index):返回选区中指定索引处的 DOM 范围。

removeAllRanges():从选区中移除所有 DOM 范围。这实际上会移除选区,因为选区中至少要包含一个范围。

removeRange(range):从选区中移除指定的 DOM 范围。

selectAllChildren(node):清除选区并选择给定节点的所有子节点。

toString():返回选区中的文本内容。
示例

var selection = frames["richedit"].getSelection(); 

取得选择的文本
var selectedText = selection.toString(); 

取得代表选区的范围
var range = selection.getRangeAt(0); 

突出显示选择的文本
var span = frames["richedit"].document.createElement("span"); 
span.style.backgroundColor = "yellow"; 
range.surroundContents(span); 
posted @ 2023-04-05 22:42  caix-1987  阅读(37)  评论(0)    收藏  举报