18

使用 jquery,我在表单中添加了一个更改处理程序。这适用于任何输入更改但仅当用户手动更改输入而不是其他代码更改输入时。

即使表单的输入被代码更改,是否有任何方法可以检测表单是否已更改?

4

6 回答 6

39

是的,这似乎有些混乱。在理想的世界中,您会期望在输入发生变化时发生 onchange 事件,但事实并非如此。我确信有充分的理由——也许不是。

我克服这个障碍的一种方法是在显示表单状态之后将其捕获到一个变量中,然后在提交它之前检查状态是否已更改并采取相应措施。

一个易于存储的状态是序列化函数返回的状态。存储状态的一个简单地方是使用数据功能。序列数据都可用于 jquery。

当然,您可以使用其他不同形式的状态(某种形式的哈希)或存储此状态(例如标准全局变量)。

这是一些原型代码:

如果您的表单 ID 是“xform”,那么您可以在表单显示时调用以下代码:

$('#xform').data('serialize',$('#xform').serialize());

然后,当您需要检查时,例如在按钮提交之前,您可以使用:

if($('#xform').serialize()!=$('#xform').data('serialize')){
    // Form has changed!!!
}

您可以将所有这些包装到一个复制和粘贴 javascript 代码段中,该代码段将为您提供一个formHasChanged()函数,可以在您需要的任何地方调用它(未测试):

$(function() {
    $('#xform').data('serialize',$('#xform').serialize());
});
function formHasChanged(){
    if($('#xform').serialize()!=$('#xform').data('serialize')){
        return(true);
    }
    return(false);
}

但我会停在这里,否则我将创建另一个 jquery 插件。

于 2012-04-25T08:37:40.283 回答
10

序列化表单当然是一种选择,但如果出现以下情况,它将不起作用:

  • 你想知道哪些字段发生了变化
  • 它只需要检查字段的子集
  • 动态添加或删除字段。

幸运的是,每个表单元素都有一个与其对象关联的默认值:

  • 输入,文本区域:默认值
  • 复选框,单选:defaultChecked
  • 选择:默认选择

例如:检查输入或文本区域是否已更改:

var changed = false;
$(":text,textarea").each(function(){
    changed = this.value != this.defaultValue;
    return !changed; // return if at least one control has changed value
});
于 2012-04-25T10:40:47.463 回答
4

这很容易在没有 jQuery 的 JavaScript 中实现。initChangeDetection()可以多次调用:

function initChangeDetection(form) {
  Array.from(form).forEach(el => el.dataset.origValue = el.value);
}
function formHasChanges(form) {
  return Array.from(form).some(el => 'origValue' in el.dataset && el.dataset.origValue !== el.value);
}

在 JS Bin 上测试


对于不支持新箭头/数组函数的旧浏览器:

function initChangeDetection(form) {
  for (var i=0; i<form.length; i++) {
    var el = form[i];
    el.dataset.origValue = el.value;
  }
}
function formHasChanges(form) {
  for (var i=0; i<form.length; i++) {
    var el = form[i];
    if ('origValue' in el.dataset && el.dataset.origValue !== el.value) {
      return true;
    }
  }
  return false;
}
于 2018-10-01T14:04:42.237 回答
1

不是以常规方式。

您可以通过输入进行更改,然后触发更改事件。

$('#inputId').val('foo').trigger('change');

或者这样:

$('#inputId').val('foo').change();
于 2012-04-25T08:04:26.933 回答
0

这是我所做的(我使用 zaf 的答案找到了我的解决方案)

$("form").change(function() {
    $(this).data("changed","true");
});

$("input[type='submit']").click(function() {
    if($("form").data("changed") == "true") {
        var discard = confirm("Some unsaved changes. Discard them ?");
        if(!discard) return false;
    }
});
于 2014-10-23T18:51:40.703 回答
-1

尝试onchange属性 根据W3c,它应该在元素的内容、选择或选中状态发生变化的任何时候触发。

于 2012-04-25T08:06:45.123 回答