今日的鸡汤
往后岁月,愿你摆正自己,见天地之大、众生之广,行稳致远,活出精彩人生。
1、JS 红皮书 P591-596 第十九章:表单脚本
1、表单基础: Web 表单在 HTML 中以
123456
<!-- 通用提交按钮 --><input type="submit" value="Submit Form" /><!-- 自定义提交按钮 --><button type="submit">Submit Form</button><!-- 图片按钮 --><input type="image" src="graphic.gif" />
以这种方式提交表单会在向服务器发送请求之前触发 submit 事件。这样就提供了一个验证表单数据的机会,可以根据验证结果决定是否真的要提交。阻止这个事件的默认行为可以取消提交表单。例如,下面的代码会阻止表单提交:
12345
let form = document.getElementById("myForm");form.addEventListener("submit", (event) => { // 阻止表单提交 event.preventDefault();});
调用 preventDefault()方法可以阻止表单提交。通常,在表单数据无效以及不应该发送到服务器时可以这样处理。当然,也可以通过编程方式在 JavaScript 中调用 submit()方法来提交表单。可以在任何时候调用这个方法来提交表单,而且表单中不存在提交按钮也不影响表单提交。下面是一个例子:
123
let form = document.getElementById("myForm");// 提交表单form.submit();
通过 submit()提交表单时,submit 事件不会触发。因此在调用这个方法前要先做数据验证。表单提交的一个最大的问题是可能会提交两次表单。如果提交表单之后没有什么反应,那么没有耐心的用户可能会多次点击提交按钮。结果是很烦人的(因为服务器要处理重复的请求),甚至可能造成损失(如果用户正在购物,则可能会多次下单)。解决这个问题主要有两种方式:在表单提交后禁用提交按钮,或者通过 onsubmit 事件处理程序取消之后的表单提交。
1234
<!-- 通用重置按钮 --><input type="reset" value="Reset Form" /><!-- 自定义重置按钮 --><button type="reset">Reset Form</button>
这两种按钮都可以重置表单。表单重置后,所有表单字段都会重置回页面第一次渲染时各自拥有的值。如果字段原来是空的,就会变成空的;如果字段有默认值,则恢复为默认值。用户单击重置按钮重置表单会触发 reset 事件。这个事件为取消重置提供了机会。例如,以下代码演示了如何阻止重置表单:
let form = document.getElementById("myForm");form.addEventListener("reset", (event) => { event.preventDefault();});
与表单提交一样,重置表单也可以通过 JavaScript 调用 reset()方法来完成,如下面的例子所示
let form = document.getElementById("myForm");// 重置表单form.reset();
与 submit()方法的功能不同,调用 reset()方法会像单击了重置按钮一样触发 reset 事件。
1234567
let form = document.getElementById("form1");// 取得表单中的第一个字段let field1 = form.elements[0];// 取得表单中名为"textbox1"的字段let field2 = form.elements["textbox1"];// 取得字段的数量let fieldCount = form.elements.length;
如果多个表单控件使用了同一个 name,比如像单选按钮那样,则会返回包含所有同名元素的 HTMLCollection。比如,来看下面的 HTML 代码片段:
<form method="post" id="myForm"> <ul> <li><input type="radio" name="color" value="red" />Red</li> <li><input type="radio" name="color" value="green" />Green</li> <li><input type="radio" name="color" value="blue" />Blue</li> </ul></form>
这个 HTML 中的表单有 3 个单选按钮的 name 是”color”,这个名字把它们联系在了一起。在访问 elements[“color”]时,返回的 NodeList 就包含这 3 个元素。而在访问 elements[0]时,只会返回第一个元素。比如:
let form = document.getElementById("myForm");let colorFields = form.elements["color"];console.log(colorFields.length); // 3let firstColorField = colorFields[0];let firstFormField = form.elements[0];console.log(firstColorField === firstFormField); // true
1
<input type="text" size="25" maxlength="50" value="initial value" />
<textarea rows="25" cols="5">initial value</textarea>
let textbox = document.forms[0].elements["textbox1"];textbox.select();textbox.addEventListener("focus", (event) => { event.target.select();});
1、Select 事件: 当选中文本框中的文本时,会触发 select 事件。
let textbox = document.forms[0].elements["textbox1"];textbox.addEventListener("select", (event) => { console.log("Text selected: " + event.target.value);});
2、取得选中文本: 虽然 select 事件能够表明有文本被选中,但不能提供选中了哪些文本的信息。HTML5 对此进行了扩展,以方便更好地获取选中的文本。扩展为文本框添加了两个属性:selectionStart 和 selectionEnd。
function getSelectedText(textbox) { return textbox.value.substring(textbox.selectionStart, textbox.selectionEnd);}
3、部分选中文本: setSelectionRange()方法也可以在所有文本框中使用。这个方法接收两个参数:要选择的第一个字符的索引和停止选择的字符的索引(与字符串的 substring()方法一样)。下面是几个例子:
textbox.value = "Hello world!";// 选择所有文本textbox.setSelectionRange(0, textbox.value.length); // "Hello world!"// 选择前 3 个字符textbox.setSelectionRange(0, 3); // "Hel"// 选择第 4~6 个字符textbox.setSelectionRange(4, 7); // "o w"
4、自动切换: JavaScript 可以通过很多方式来增强表单字段的易用性。最常用的是在当前字段完成时自动切换到下一个字段。对于要收集数据的长度已知(比如电话号码)的字段是可以这样处理的。在美国,电话号码通常分为 3 个部分:区号、交换局号,外加 4 位数字。在网页中,可以通过 3 个文本框来表示这几个部分,比如:
<input type="text" name="tel1" id="txtTel1" maxlength="3" /><input type="text" name="tel2" id="txtTel2" maxlength="3" /><input type="text" name="tel3" id="txtTel3" maxlength="4" />
为增加这个表单的易用性并加速数据输入,可以在每个文本框输入到最大允许字符数时自动把焦点切换到下一个文本框。因此,当用户在第一个文本框中输入 3 个字符后,就把焦点移到第二个文本框,当用户在第二个文本框中输入 3 个字符后,把焦点再移到第三个文本框。这种自动切换文本框的行为可以通过如下代码实现:
123456789101112131415161718192021222324
<script> function tabForward(event) { let target = event.target; if (target.value.length == target.maxLength) { let form = target.form; for (let i = 0, len = form.elements.length; i < len; i++) { if (form.elements[i] == target) { if (form.elements[i + 1]) { form.elements[i + 1].focus(); } return; } } } } let inputIds = ["txtTel1", "txtTel2", "txtTel3"]; for (let id of inputIds) { let textbox = document.getElementById(id); textbox.addEventListener("keyup", tabForward); } let textbox1 = document.getElementById("txtTel1"); let textbox2 = document.getElementById("txtTel2"); let textbox3 = document.getElementById("txtTel3");</script>
5、HTML5为浏览器新增了在提交表单前验证数据的能力。这些能力实现了基本的验证,即使JavaScript不可用或加载失败也没关系。