表单脚本

表单脚本

表单基础

Web 表单在 HTML 中以 元素表示,在 JavaScript 中则以 HTMLFormElement 类型表示。

  • acceptCharset:服务器可以接收的字符集,等价于 HTML 的 accept-charset 属性。
  • action:请求的 URL,等价于 HTML 的 action 属性。
  • elements:表单中所有控件的 HTMLCollection。
  • enctype:请求的编码类型,等价于 HTML 的 enctype 属性。
  • length:表单中控件的数量。
  • method:HTTP 请求的方法类型,通常是 “get” 或 “post”,等价于 HTML 的 method 属性。
  • name:表单的名字,等价于 HTML 的 name 属性。
  • reset():把表单字段重置为各自的默认值。
  • submit():提交表单。
  • target:用于发送请求和接收响应的窗口名字,等价于 HTML 的 target 属性。

取得对 元素的引用。

// 通过 id 获取表单引用
let form = document.getElementById("form1");
// 通过索引获取表单引用
let firstForm = document.forms[0];
// 通过表单 name 属性获取引用
let xkcForm = document.forms["xkcForm"];

提交表单

表单的提交按钮可以使用 type 属性为 “submit” 的 或 元素来定义,图片按钮可以使用 type 属性为 “image” 的 元素来定义。

<!-- 通用提交按钮 -->
<input type="submit" value="Submit Form">
<!-- 自定义提交按钮 -->
<button type="submit">Submit Form</button>
<!-- 图片按钮提交 -->
<input type="image" src="xkc.png">

表单上有任意一种提交按钮,且焦点在表单中某个控件上,按回车键可以提交表单(textarea 控件忽略,回车键不发生提交,而是发生换行)。

阻止默认行为可以取消提交表单。

let form = document.getElementById("xkcForm");
form.addEventListener("submit", function(event) {
    event.preventDefault();
});

可以调用 submit() 方法来提交表单。

form.submit();

注意:

通过 submit() 方法提交表单时, submit 事件不会触发。 因此需要在 submit() 方法前面先进行提交数据验证。

多次提交表单的解决方式:

  • 在表单提交后禁用提交按钮;
  • 通过 onsubmit 事件处理程序取消之后的表单提交。

重置表单

重置按钮可以使用 type 属性为 “reset” 的 或 元素来创建。

<!-- 通用重置按钮 -->
<input type="reset" value="Reset Form">
<!-- 自定义重置按钮 -->
<button type="reset">Reset Form</button>

重置表单之后,整个表单会重置回第一次渲染时的状态。

阻止重置表单行为,可以通过阻止默认行为

let form = document.getElementById("xkc");
form.addEventListener("reset", (event) => {
    event.preventDefault();
});

重置表单可以通过调用 reset() 方法来完成。

form.reset();

注意:

submit() 方法不同的是,调用 reset() 方法会触发 reset 事件。一般不推荐重置表单的操作。

表单字段

所有表单都是表单 elements 属性中包含的一个值。这个 elements 集合是一个有序列表,包含对表单中所有字段的引用。可以通过索引位置和 name 属性来访问。

let form = document.getElementById("xkcForm");
// 根据索引获取
let field1 = form.elements[0];
// 根据 name 属性获取
let field2 = form.elements["text1"];
let fieldCount = form.elements.length;
表单字段的公共属性:
  • disabled:布尔值,表示表单字段是否禁用。
  • form:指针,指向表单字段所属的表单。只读。
  • name:字符串,这个字段的名字。
  • readOnly:布尔值,表示这个字段是否只读。
  • tabIndex:数值,表示这个字段在按 Tab 键时的切换顺序。
  • type:字符串,表示字段类型。
  • value:要提交给服务器的字段值。只读。
表单字段的公共方法:

两个公共方法:focus()blur()

  • focus():把浏览器焦点设置到表单字段。如果被修改的字段是 type 是 “hidden” 的 元素,或者该字段被 CSS 属性 display 或 visibility 隐藏了,则报错。

    HTML5 为表单字段增加了 autofocus 属性,支持的浏览器会自动为带有该属性的元素设置焦点。该属性是布尔值。

    注意:

    默认下只能给表单元素设置焦点。也可以通过将 tabIndex 属性设置为 -1 再调用 focus() 可以给任意元素设置焦点。

  • blur():用于从元素上移除焦点。

表单字段的公共事件:
  • blur:在字段失去焦点时触发。
  • change:在 和 元素的 value 发生变化且失去焦点时触发,在 元素被选中时发生变化时触发。
  • focus:在字段获得焦点时触发。

blur 和 focus 事件会因为用户手动改变字段焦点或者使用 blur()focus() 方法而触发。

文本框编程

选择文本

select() 方法用于全部选中文本框中的文本。

select 事件

select 事件在当选中文本框中的文本时,会触发。

取得选中文本

为提供选中文本信息。 HTML5 对此进行了扩展,为文本框添加了两个属性:selectionStartselectionEnd。分别表示文本选区的起点和终点(文本选区起点的偏移量和文本选区终点的偏移量)。

老版本IE有包含整个文档中文本选择信息的 document.selection 对象。必须先创建一个范围。再从中取得文本。

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;
    }
}
部分选中文本

HTML5 在文本框中选中部分文本提供支持。 setSelectionRange() 方法也可以在所有文本框中使用。这个方法接收两个参数:要选择的第一个字符的索引和停止选择的字符的索引。

注意:

在调用 setSelectionRange() 方法之前要先给文本框设置焦点。

IE早期版本提供的 createTextRange() 方法创建一个范围,并使用 moveStart()moveEnd()范围方法。在使用这两个方法之前需要先调用 collapse() 方法把范围折叠到文本框的开始。接着,moveStart() 可以把范围的起点和终点都移动到相同的位置,再给 moveEnd()传入要选择的字符总数作为参数。最后使用 select()选中文本。

let textbox = document.forms[0].elements["textbox1"];
textbox.value = "Hello World!";
var range = textbox.createTextRange();
range.collapse(true);
range.moveStart("charactor", 0);
range.moveEnd("charactor", textbox.value.length); 
range.select(); // Hello World!

range.collapse(true);
range.moveStart("charactor", 0);
range.moveEnd("charactor", 3);
range.select(); // Hel

注意:

要想看到效果文本框必须先获得焦点。

输入过滤

屏蔽字符

// 用户输入手机号文本框不应该出现非数字字符
textbox.addEventListener("keypress", (event) => {
    if (!/\d/.test(String.fromCharCode(event.charCode)) && event.charCode > 9 && !event.ctrlKey) {
        event.preventDefault();
    }
});
处理剪贴板

剪贴板相关事件:

  • beforecopy:复制操作发生前触发。
  • copy:复制操作发生时触发。
  • beforecut:剪切操作发生前触发。
  • cut:剪切操作发生时触发。
  • beforepaste:粘贴操作发生前触发。
  • paste:粘贴操作发生时触发。

剪贴板上的数据可以通过 window 对象(IE) 或 event 对象(Firefox、Safari 和 Chrome) 上的 clipboardData 对象获取。Firefox、Safari 和 Chrome 中只能再剪贴板事件期间访问 clipboardData 对象。IE 在任何时候都会暴露 clipboardData 对象。

兼容的获取和设置剪贴板内容

function getClipboardText(event) {
    var clipboardData = (event.clipboardData || window.clipboardData);
    return clipboardData.getData("text");
}
function setClipboardText(event, value) {
    if (event.clipboardData) {
        return event.clipboardData.setData("text/plain", value); 
    } else if (window.clipboardData) {
        return window.clipboardData.setData("text", value);
    }
}

HTML5 约束验证 API

必填字段

给表单字段添加 required 属性。

<input type="text" name="xkcName" required >

任何带有 required 属性的字段必须有值,否则无法提交表单。

可通过检测对应元素的 required 属性来判断表单字段是否为必填。

let isXkcNameRequired = document.forms[0].elements["xkcName"].required;
更多输入类型

新的输入类型 “email” 和 “url”。

<input type="email" name="email">
<input type="url" name="url">
数值范围

HTML5 定义了其他几种新的输入元素类型。包括:“number”、“range”、“datetime”、“datetime-local”、“date”、“month”、“week” 和 “time”。并非所有主流浏览器都支持。

对于上述每种数值类型。都可以指定 min 属性(最小可能值)、max 属性(最大可能值),以及 step 属性(从 min 到 max 的步长值)。

<!-- 只允许输入 0 到 100 中 5 的倍数 -->
<input type="number" min="0" max="100" step="5" name="xkc">

stepUp()stepDown() 接收一个可选参数:要从当前值加上或减去的数值。(默认,步长会增加或递减 1 )。

input.stepUp(); // 加 1
input.stepUp(2); // 加 2
input.stepDown(); // 减 1
input.stepDown(2); // 减 2
输入模式

HTML 新增 pattern 属性。用于指定一个正则表达式,用户输入的文本必须与之匹配。

<input type="text" pattern="\d+" name="count">

可以使用元素的 pattern 属性获取

let pattern = document.form[0].elements["count"].pattern;
检测有效值

使用 checkValidity() 方法可以检测表单中任意给定字段是否有效。这个方法在所有表单元素上都可以使用,字段有效则返回 true,否则返回 false。判断字段是否有效依据是上面的约束条件。

checkValidity() 方法只会告诉我们字段是否有效,而 validity 属性会告知我们字段为什么有效或者无效。validity 属性是一个对象,包含返回布尔值的属性:

  • customError:如果设置了 setCustomValidity() 就返回 true,否则返回 false。
  • patternMismatch:如果字段值不匹配指定的 pattern 属性则返回 false。
  • rangeOverflow:如果字段值大于 max 的值则返回 true。
  • rangeUnderflow:如果字段小于 min 的值则返回 true。
  • stepMisMatch:如果字段值与 min、max 和 step 的值不相符则返回 true。
  • tooLong:如果字段值的长度超过 maxlength 属性指定的值则返回 true。
  • typeMismatch:如果字段值不是 “email” 或 “url” 要求的格式返回 true。
  • valid:如果其他所有属性值都是 false 或者 true 。与 checkValidity() 条件一致。
  • valueMissing:如果字段是必填的但没有值则返回 true。
禁用验证

通过指定 novalidate 属性可以禁止对表单进行任何验证:

<form method="post" action="" novalidate></form>

如果一个表单有多个提交按钮,可以给特定的提交按钮添加 formnovalidate 属性,指定通过该按钮无须验证便可提交表单。

<form method="post" action="">
    <input type="submit" value="Submit 1">
    <input type="submit" formnovalidate value="Submit 2">
</form>

选择框编程

选择框是使用 和 元素创建的。

  • add(newOption, relOption):在 relOption 之前向控件中添加新的 。
  • multiple:布尔值。表示是否允许多选,等价于 HTML 的 multiple 属性。
  • options:控件中所有 元素的 HTMLCollection。
  • remove(index):移除给定位置的选项。
  • selectedIndex:选中项基于 0 的索引值,如果没有选中项则为 -1 。对于允许多选的列表,始终是第一个选项中的索引。
  • size:选择框中可见的行数,等价于 HTML 的 size 属性。

以下规则决定选择框的 value 属性

  • 如果没有选中项,选择框的值是空字符串。
  • 如果有一个选中项,且其 value 属性有值,则选择框的值就是选中项 value 属性的值。即使 value 属性的值是空字符串也是如此。
  • 如果有一个选中项,且其 value 属性没有指定值,则选择框的值就是该项的文本内容。
  • 如果有多个选中项,则选择框的值根据前两条规则取得第一个选中项的值。

每个 元素的属性:

  • index:选项在 options 集合中的索引。
  • label:选项的标签,等价于 HTML 的 label 属性。
  • selected:布尔值,表示是否选中了当前选项。把这个属性设置为 true 会选中当前选项。
  • text:选项的文本。
  • value:选项的值(等价于 HTML 的 value 属性)。

选项处理

只允许选择一项的选择框中,获取选项最简单的方式就是使用选择框的 selectedIndex 属性。

let selectbox = document.forms["xkcForm"].elements["xkcSelect"];
let selectedOption = selectbox.options[selectbox.selectedIndex];

允许多选的选择框, selectedIndex 属性就像只允许选择一项一样。设置 selectedIndex 会移除所有选项,只选择指定的项,而获取 selectedIndex 只会返回选中的第一项的索引。

添加选项

创建 元素节点并设置 value 和 text,并添加到选择框中。

let newOption = document.createElement("option");
newOption.appendChild(document.createTextNode("Option Text"));
newOption.setAttribute("value", "Option Value");
selectbox.appendChild(newOption);

使用 Option 构造函数创建新选项。接收两个参数:text 和 value,其中 value 是可选的。返回一个元素。

let newOption = new Option("Option text", "Option Value");
selectbox.add(newOption, undefined);

移除选项

第一种使用 DOM 的 removeChild() 方法并传入要移除的选项。

selectbox.removeChild(selectbox.options[0]);

第二种使用 remove() 方法。

selectbox.remove(0);

最后一种将选项设置为 null 。

selectbox.options[0] = null;

移动和重排选项

使用 insertBefore() 方法。

let optionMove = selectbox.option[1];
selectbox.insertBefore(optionMove, selectbox.options[optionMove.index - 1]);

表单序列化

function serialize(form) {
    let parts = [];
    let optValue;
    for (let field of form.elements) {
        switch (field.type) {
            case "select-one":
            case "select-multiple":
                if (field.name.length) {
                    for (let option of field.options) {
                        if (option.selected) {
                            if (option.hasAttribute) {
                                optValue = (option.hasAttribute("value") ? option.value :											option.text); 
                            } else {
                                optValue = (option.attribute["value"].specified ? 													option.value : option.text);
                            }
                            parts.push(encodeURIComponent(filed.name) + "=" + 												   encodeURIComponent(optValue));
                        }
                    }
                }
                break;
            case undefined:
            case "file":
            case "submit":
            case "reset":
            case "button":
                break;
            case "radio":
            case "checkbox":
                if (!field.checked) {
                    break;
                }
            default:
                if (field.name.length) {
                    parts.push(`${encodeURIComponent(field.name)}=${encodeURIComponent(field.value)}`);
                }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值