在上一篇文章中,我们发现了如何检查用户是否更改了单个表单元素。 今天,我们将使用这些信息来编写JavaScript代码,该代码可以检测任何形式的更新。
以下是示例和代码链接:
我们的先决条件
由于我们都是优秀的开发人员,因此我们将在切割任何代码之前定义要求:
- 我们将编写一个函数FormChanges(),该函数接受一个重载的表单参数-表单的DOM节点或字符串ID。
- 该函数将返回用户已更改的表单元素节点的数组。 这使我们能够确定哪些字段已更改,或者如果数组为空,则没有字段已更改。
- 如果找不到任何形式,该函数将返回NULL。
- 我们不会依赖任何特定的JavaScript库,因此该功能仍与所有它们兼容。
- 它必须在所有现代浏览器以及IE6或IE7中都可以使用。
FormChanges()函数
为了让您轻轻松松,这是我们功能的开始:
function FormChanges(form) {
我们正在重载form参数-它可以是DOM元素,但是,如果它是ID字符串,则需要在DOM中定位该元素:
if (typeof form == "string") form = document.getElementById(form);
如果没有表单节点,则该函数将返回null而不进行任何进一步的工作:
if (!form || !form.nodeName || form.nodeName.toLowerCase() != "form") return null;
现在,我们将声明将在整个函数中使用的变量:
- “ changed”是用户已更新的表单元素的返回数组
- 'n'是一个表单元素节点
- 如果元素已更改,则将'c'设置为true
- 'def'是选择框的默认选项
- 'o','ol'和'opt'是循环中使用的临时变量
var changed = [], n, c, def, o, ol, opt;
现在,我们可以开始我们的主循环,该循环依次检查每个表单元素。 最初将c设置为false,指示未对我们正在检查的元素进行任何更改:
for (var e = 0, el = form.elements.length; e < el; e++) {
n = form.elements[e];
c = false;
接下来,我们将提取节点名称(输入,文本区域,选择),并在switch语句中对其进行检查。 我们仅在查找选择节点和非选择节点,因此,严格来说switch语句不是必需的。 但是,它更易于阅读,并允许我们在引入其他节点类型时添加它们。
请注意,大多数浏览器都以大写形式返回节点名称,但我们正在安全地进行操作,并始终将字符串转换为小写形式。
switch (n.nodeName.toLowerCase()) {
第一个case语句评估select
下拉列表。 这是最复杂的检查,因为我们必须遍历所有子option
元素以比较selected和defaultSelected属性。
该循环还将def设置为具有“ selected”属性的最后一个选项。 如果我们有一个单选框,则将def与该节点的selectedIndex属性进行比较,以确保我们处理的情况是没有option
或多个option
元素具有“ selected”属性( 完整说明请参阅上一篇文章) )。
// select boxes
case "select":
def = 0;
for (o = 0, ol = n.options.length; o < ol; o++) {
opt = n.options[o];
c = c || (opt.selected != opt.defaultSelected);
if (opt.defaultSelected) def = o;
}
if (c && !n.multiple) c = (def != n.selectedIndex);
break;
现在,我们需要处理input
和textarea
元素。 请注意,我们的case "textarea":
语句不使用换行符,因此它属于case "input":
代码。
复选框和单选元素的checked属性和defaultChecked属性进行比较,而所有其他类型的值与defaultValue进行比较:
// input / textarea
case "textarea":
case "input":
switch (n.type.toLowerCase()) {
case "checkbox":
case "radio":
// checkbox / radio
c = (n.checked != n.defaultChecked);
break;
default:
// standard values
c = (n.value != n.defaultValue);
break;
}
break;
}
如果c的值为true,则元素已更改,因此我们将其附加到更改后的数组中。 循环现已完成:
if (c) changed.push(n);
}
我们只需要返回更改后的数组并结束函数:
return changed;
}
示例用途
假设我们创建了以下表单:
<form id="myform" action="index.html" method="post">
<fieldset>
<legend>Your profile</legend>
<input type="hidden" id="changed" name="changed" value="yes" />
<div>
<label for="name">name:</label>
<input type="text" id="name" name="name" value="Jonny Dough" />
</div>
<div>
<label for="job">job title:</label>
<select id="job" name="job">
<option>web designer</option>
<option selected="selected">web developer</option>
<option>graphic artist</option>
<option>IT professional</option>
<option>other</option>
</select>
</div>
<div>
<button type="submit">Update Profile</button>
</div>
</fieldset>
</form>
我们可以使用以下代码检查用户是否更改了任何表单字段:
var changed = FormChanges("myform");
alert(changed.length + " field(s) have been updated.");
或者,如果未进行任何更改,则可以在提交表单时将隐藏的“已更改”值更新为“否”。 这将允许服务器端代码跳过字段验证和数据库更新:
var form = document.getElementById("myform");
form.onsubmit = function() {
if (FormChanges(form).length == 0) {
document.getElementById("changed").value = "no";
}
return true;
}
(注意:将“ yes”更改为“ no”会优雅地降低性能,因为如果JavaScript不可用,服务器将始终处理传入的数据。)
希望对你有帮助。
From: https://www.sitepoint.com/javascript-form-change-checker/