使用jQuery检测表单中的数据更改

我正在使用带有母版页的ASP.NET 2.0,我想知道是否有人知道某种方法来检测某个

fieldset的字段何时被更改(例如,标记为’ IsDirty ‘)?

您可以为所有输入绑定Change事件,并将变量标记为true。 像这样。

 var somethingChanged = false; $(document).ready(function() { $('input').change(function() { somethingChanged = true; }); }); 

但是,请记住,如果用户更改了某些内容,然后更改回原始值,则仍会将其标记为已更改。

更新:对于特定的div或fieldset。 只需使用给定fieldset或div的id。 例:

 var somethingChanged = false; $(document).ready(function() { $('#myDiv input').change(function() { somethingChanged = true; }); }); 

快速(但非常脏)的解决方案

这很快,但它不会处理ctrl+zcmd+z ,当按shiftctrltab键时它会给你一个误报:

 $('#my-form').on('change keyup paste', ':input', function(e) { // The form has been changed. Your code here. }); 

用这个小提琴测试它。


快速(不太脏)的解决方案

这将防止shiftctrltab键的误报,但它不会处理ctrl+zcmd+z

 $('#my-form').on('change keyup paste', ':input', function(e) { var keycode = e.which; if (e.type === 'paste' || e.type === 'change' || ( (keycode === 46 || keycode === 8) || // delete & backspace (keycode > 47 && keycode < 58) || // number keys keycode == 32 || keycode == 13 || // spacebar & return key(s) (if you want to allow carriage returns) (keycode > 64 && keycode < 91) || // letter keys (keycode > 95 && keycode < 112) || // numpad keys (keycode > 185 && keycode < 193) || // ;=,-./` (in order) (keycode > 218 && keycode < 223))) { // [\]' (in order)) // The form has been changed. Your code here. } }); 

用这个小提琴测试它。


完整(不太快)的解决方案

如果要处理所有情况,您应该使用:

 // init the form when the document is ready or when the form is populated after an ajax call $(document).ready(function() { $('#my-form').find(':input').each(function(index, value) { $(this).data('val', $(this).val()); }); }) $('#my-form').on('change paste', ':input', function(e) { $(this).data('val', $(this).val()); // The form has been changed. Your code here. }); $('#my-form').on('keyup', ':input', function(e) { if ($(this).val() != $(this).data('val')) { $(this).data('val', $(this).val()); // The form has been changed. Your code here. } }); 

用这个小提琴测试它。

一个简单而优雅的解决方案(它可以实时检测表单元素的变化):

 var formChanged = false; $('#my-div form').on('keyup change paste', 'input, select, textarea', function(){ formChanged = true; }); 

只是为了澄清因为问题是“在某个字段集/ div内”:

 var somethingChanged = false; $(document).ready(function() { $('fieldset > input').change(function() { somethingChanged = true; }); }); 

要么

 var somethingChanged = false; $(document).ready(function() { $('div > input').change(function() { somethingChanged = true; }); }); 

你可以给fieldset或div一个ID并将change事件绑定到它…事件应该从内部子节点传播。

 var somethingChanged = false; $('#fieldset_id').change(function(e) { // e.target is the element which triggered the event // console.log(e.target); somethingChanged = true; }); 

此外,如果您想拥有单个事件监听function,可以将更改事件放在表单上,​​然后检查哪个字段集已更改:

 $('#form_id').change(function(e) { var changedFieldset = $(e.target).parents('fieldset'); // do stuff }); 

我在CoffeeScript中提出了这段代码(还没有经过现场测试):

  • 将类“change_warning”添加到应该观察更改的表单中。

  • 将类“change_allowed”添加到保存按钮。

change_warning.coffee:

 window.ChangeWarning = { save: -> $(".change_warning").each (index,element) -> $(element).data('serialized', $(element).serialize()) changed: (element) -> $(element).serialize() != $(element).data('serialized') changed_any: -> $.makeArray($(".change_warning").map (index,element) -> ChangeWarning.changed(element)).some (f)->f # AKA $(".change_warning").any (element) -> ChangeWarning.changed(element) # But jQuery collections do not know the any/some method, yet (nor are they arrays) change_allowed: -> ChangeWarning.change_allowed_flag = true beforeunload: -> unless ChangeWarning.change_allowed_flag or not ChangeWarning.changed_any() "You have unsaved changes" } $ -> ChangeWarning.save() $(".change_allowed").bind 'click', -> ChangeWarning.change_allowed() $(window).bind 'beforeunload', -> ChangeWarning.beforeunload() 

.live现已弃用,并替换为.on

 var confirmerSortie = false; $(document).on('change', 'select', function() { confirmerSortie = true; }); $(document).on('change keypress', 'input', function() { confirmerSortie = true; }); $(document).on('change keypress', 'textarea', function() { confirmerSortie = true; }); 

对于表单,您可以在加载时序列化内容,然后在稍后比较序列化,例如:

 $(function(){ var initdata=$('form').serialize(); $('form').submit(function(e){ e.preventDefault(); var nowdata=$('form').serialize(); if(initdata==nowdata) console.log('nothing changed'); else console.log('something changed'); $.post('settings.php',$('form').serialize()).done(function(){ initdata=$('form').serialize(); }); }); }); 

以下解决方案对我有用:

 $("#myDiv :input").change(function() { $("#myDiv").data("changed",true);}); } if($("#myDiv").data("changed")) { console.log('Form data changed hence proceed to submit'); } else { console.log('No change detected!'); }