提醒未保存的表单更改
Posted
技术标签:
【中文标题】提醒未保存的表单更改【英文标题】:Alert for unsaved changes in form 【发布时间】:2012-08-04 08:48:33 【问题描述】:我想在主文件中编写 Jquery 代码,这样如果用户更改页面并且有任何未保存的更改,用户应该得到警报。 我得到了一个答案:link
但在大多数解决方案中,我必须在所有页面上编写代码。我希望它只写在一个地方,这样每个人都不必担心在他们的模块中编写它。我的代码是这样的:
<script type="text/javascript">
var isChange;
$(document).ready(function ()
$("input[type='text']").change(function ()
isChange = true;
)
);
$(window).unload(function ()
if (isChange)
alert('Handler for .unload() called.');
);
</script>
但每次我在文本框中进行更改时,.change() 事件都不会触发。
代码有什么问题?
编辑: 我将 .change() 更改为 .click 并被触发。我正在使用 jquery 1.4.1 ..是因为 jquery 版本导致 change() 不起作用吗?
【问题讨论】:
所有输入字段都是静态的还是有些是动态添加到表单中的(或通过ajax加载)? 但在大多数解决方案中,我必须在所有页面上编写代码。 为什么不使用外部脚本文件? @Raminson 是对的,写一个外部 js 文件,然后将它包含在页面中。 非 jquery 版本:***.com/questions/7317273/… 【参考方案1】:这就是我正在使用的,将所有这些代码放在一个单独的 JS 文件中并将其加载到您的头文件中,这样您就不需要一次又一次地复制它:
var unsaved = false;
$(":input").change(function() //triggers change in all input fields including text type
unsaved = true;
);
function unloadPage()
if(unsaved)
return "You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?";
window.onbeforeunload = unloadPage;
未找到 $ 编辑:
此错误只能由以下三种情况之一引起:
您的 JavaScript 文件未正确加载到您的页面中 您有一个拙劣的 jQuery 版本。这可能是因为有人编辑了核心文件,或者插件可能覆盖了 $ 变量。 您在页面完全加载之前运行了 JavaScript,因此,在 jQuery 完全加载之前。
确保所有的 JS 代码都放在这个:
$(document).ready(function ()
//place above code here
);
编辑保存/发送/提交按钮异常
$('#save').click(function()
unsaved = false;
);
编辑以使用动态输入
// Another way to bind the event
$(window).bind('beforeunload', function()
if(unsaved)
return "You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?";
);
// Monitor dynamic inputs
$(document).on('change', ':input', function() //triggers change in all input fields including text type
unsaved = true;
);
在您的 alert_unsaved_changes.js 文件中添加上述代码。
希望这会有所帮助。
【讨论】:
你可以尝试添加alert('asd');未保存之前 = true;然后警报(未保存);这样您就会知道当数据更改时未保存的内容。 是的,它只是一个 javascript。你包含了 jquery 吗?? 是的 ..我已经包含了 jquery ......我刚刚签入了 firebug .. 我收到错误为“$ 未定义”..但是我给出了像 在母版页和其他页面中也是如此 如果你点击“保存”按钮,有没有办法让它不运行 这很棒。完美运行,但你能告诉我为什么它不能在 iPhone 上运行吗?我们必须使用其他功能吗?【参考方案2】:使用表单序列化的版本:
当 dom 准备好时执行这段代码:
// Store form state at page load
var initial_form_state = $('#myform').serialize();
// Store form state after form submit
$('#myform').submit(function()
initial_form_state = $('#myform').serialize();
);
// Check form changes before leaving the page and warn user if needed
$(window).bind('beforeunload', function(e)
var form_state = $('#myform').serialize();
if(initial_form_state != form_state)
var message = "You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?";
e.returnValue = message; // Cross-browser compatibility (src: MDN)
return message;
);
如果用户更改字段然后手动回滚,则不会显示警告
【讨论】:
这是一种适用于更复杂的自定义用户控件的方法。我自己也采用了这种方法:)【参考方案3】:change 事件在用户从输入中模糊时触发,而不是在输入的每个字符上。
如果您需要在每次更改某些内容时调用它(即使焦点仍在该输入字段中),您将不得不依靠 keyup 和一堆事件的组合来跟踪仅使用鼠标粘贴/剪切。
附: 我希望你知道你检测变化的方法不是最好的?如果用户输入一些文本,离开该字段,然后恢复更改,脚本仍会提醒他有关修改的文本。
【讨论】:
【参考方案4】:如果您的意思是带有文本框的 textarea,您不仅应该为输入注册事件,还应该为 textareas 注册事件。您可以为 isChange 使用 keyup,这样您就不必等待用户从该区域模糊。
$("input[type='text'], textarea").keyup(function ()
isChange = true;
)
【讨论】:
【参考方案5】:为什么不简单地将事件绑定到change
回调?
$(":input").change(function()
$(window).unbind('unload').bind('unload',function()
alert('unsaved changes on the page');
);
);
作为额外的奖励,您可以使用confirm
并选择触发更改事件的最后一个元素:
$(":input").change(function()
$(window).unbind('unload').bind('unload',(function(elem)
//elem holds reference to changed element
return function(e)
//get the event object:
e = e || window.event;
if (confirm('unsaved changes on the page\nDo you wish to save them first?'))
elem.focus();//select element
return false;//in jQuery this stops the event from completeing
($(this)));//passed elem here, I passed it as a jQ object, so elem.focus() works
//pass it as <this>, then you'll have to do $(elem).focus(); or write pure JS
);
如果您有一些保存按钮,请确保取消绑定卸载事件,但:
$('#save').click(function()
$(window).unbind('unload');
//rest of your code here
);
【讨论】:
【参考方案6】:这实际上只是@AlphaMale 答案的不同版本,但在几个方面有所改进:
# Message displayed to user. Depending on browser and if it is a turbolink,
# regular link or user-driven navigation this may or may not display.
msg = "This page is asking you to confirm that you want to leave - data you have entered may not be saved."
# Default state
unsaved = false
# Mark the page as having unsaved content
$(document).on 'change', 'form[method=post]:not([data-remote]) :input', -> unsaved = true
# A new page was loaded via Turbolinks, reset state
$(document).on 'page:change', -> setTimeout (-> unsaved = false), 10
# The user submitted the form (to save) so no need to ask them.
$(document).on 'submit', 'form[method=post]', ->
unsaved = false
return
# Confirm with user if they try to go elsewhere
$(window).bind 'beforeunload', -> return msg if unsaved
# If page about to change via Turbolinks also confirm with user
$(document).on 'page:before-change', (event) ->
event.preventDefault() if unsaved && !confirm msg
这在以下方面会更好:
恕我直言,它是咖啡脚本自动使它变得更好。 :) 它完全基于事件冒泡,因此会自动处理动态内容(@AlphaMale 的更新也有这个)。 它仅适用于 POST 表单,因为 GET 表单没有我们通常希望避免丢失的数据(即 GET 表单往往是搜索框和过滤条件)。 它不需要绑定到特定的按钮来执行保存。每当提交表单时,我们假定提交正在保存。 它与Turbolinks 兼容。如果您不需要,只需删除两个page:
事件绑定即可。
它的设计目的是让您只需将其与 JS 的其余部分一起包含在内,您的整个网站都会受到保护。
【讨论】:
【参考方案7】:我使用$('form').change
等函数来设置脏位变量。不适合捕获所有更改(根据之前的答案),但在我的应用中捕获了我感兴趣的所有内容。
【讨论】:
以上是关于提醒未保存的表单更改的主要内容,如果未能解决你的问题,请参考以下文章
在 Visual Studio 的设计视图中打开表单 (.cs) 会立即显示未保存的更改