Kha*_*han 314 javascript forms
我的应用程序中有一些表单.
如何以这样的方式保护表单:如果有人导航或关闭浏览器选项卡,应提示他们确认他们确实要保留未保存数据的表单?
Cod*_*ter 527
您可以通过处理beforeunload事件并返回非空字符串来执行此操作:
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.';
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});
Run Code Online (Sandbox Code Playgroud)
这种方法的问题是提交表单也会触发卸载事件.通过添加您提交表单的标志,可以轻松修复此问题:
var formSubmitting = false;
var setFormSubmitting = function() { formSubmitting = true; };
window.onload = function() {
window.addEventListener("beforeunload", function (e) {
if (formSubmitting) {
return undefined;
}
var confirmationMessage = 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.';
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});
};
Run Code Online (Sandbox Code Playgroud)
然后在提交时调用setter:
<form method="post" onsubmit="setFormSubmitting()">
<input type="submit" />
</form>
Run Code Online (Sandbox Code Playgroud)
但请继续阅读......
当用户未在表单上更改任何内容时,您也不希望显示此消息.一种解决方案是将beforeunload事件与"脏"标志结合使用,只有当它真正相关时才触发提示.
var isDirty = function() { return false; }
window.onload = function() {
window.addEventListener("beforeunload", function (e) {
if (formSubmitting || !isDirty()) {
return undefined;
}
var confirmationMessage = 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.';
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});
};
Run Code Online (Sandbox Code Playgroud)
现在实现该isDirty方法,有各种方法.
您可以使用jQuery和表单序列化,但这种方法有一些缺陷.首先,你必须改变代码以适用于任何形式($("form").each()将要做),但最大的问题是jQuery serialize()只能在命名的非禁用元素上工作,因此更改任何禁用或未命名的元素将不会触发脏标志.有一些解决方法,比如只读控制而不是启用,序列化,然后再次禁用控件.
所以事件似乎要走了.你可以尝试听按键.此事件有一些问题:
该change事件也不会触发从JavaScript代码设置的值,因此也不适用于虚拟输入.
绑定input事件给所有inputS(和textareaS和selectS)您的网页上是行不通的旧版浏览器上,像所有的事件处理上面提到的解决方案,不支持撤销.当用户更改文本框然后撤消该文本框,或者选中并取消选中复选框时,该表单仍被视为脏.
当你想要实现更多的行为时,比如忽略某些元素,你还需要做更多的工作.
因此,在您考虑实施这些解决方案和所有必需的解决方法之前,要意识到您正在重新发明轮子并且您很容易遇到其他人已经为您解决的问题.
如果您的应用程序已经使用了jQuery,那么您也可以使用经过测试,维护的代码而不是自己编写代码,并使用第三方库来实现所有这些.jQuery你确定吗?插件效果很好,请参阅他们的演示页面.这很简单:
<script src="jquery.are-you-sure.js"></script>
<script>
$(function() {
$('#myForm').areYouSure(
{
message: 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.'
}
);
});
</script>
Run Code Online (Sandbox Code Playgroud)
请注意,Firefox 4在此对话框中不支持自定义消息.截至上个月,Chrome 51正在推出,其中也会删除自定义消息.
本网站的其他地方也存在一些替代方案,但我认为这样的对话很清楚:
你想离开这个网站吗?
您所做的更改可能无法保存.
Leave Stay
Pau*_*ley 75
查看JavaScript onbeforeunload事件.它是Microsoft引入的非标准JavaScript,但它适用于大多数浏览器,其onbeforeunload文档中包含更多信息和示例.
Was*_* A. 34
通过jquery
$('#form').data('serialize',$('#form').serialize()); // On load save form current state
$(window).bind('beforeunload', function(e){
if($('#form').serialize()!=$('#form').data('serialize'))return true;
else e=null; // i.e; if form state change show warning box, else don't show it.
});
Run Code Online (Sandbox Code Playgroud)
您可以使用Google JQuery Form Serialize功能,这将收集所有表单输入并将其保存在数组中.我想这个解释就够了:)
Eli*_*rey 12
通用解决方案,无需自动检测所有输入修改的配置,包括可满足的元素:
"use strict";
(() => {
const modified_inputs = new Set;
const defaultValue = "defaultValue";
// store default values
addEventListener("beforeinput", (evt) => {
const target = evt.target;
if (!(defaultValue in target || defaultValue in target.dataset)) {
target.dataset[defaultValue] = ("" + (target.value || target.textContent)).trim();
}
});
// detect input modifications
addEventListener("input", (evt) => {
const target = evt.target;
let original;
if (defaultValue in target) {
original = target[defaultValue];
} else {
original = target.dataset[defaultValue];
}
if (original !== ("" + (target.value || target.textContent)).trim()) {
if (!modified_inputs.has(target)) {
modified_inputs.add(target);
}
} else if (modified_inputs.has(target)) {
modified_inputs.delete(target);
}
});
addEventListener("beforeunload", (evt) => {
if (modified_inputs.size) {
const unsaved_changes_warning = "Changes you made may not be saved.";
evt.returnValue = unsaved_changes_warning;
return unsaved_changes_warning;
}
});
})();
Run Code Online (Sandbox Code Playgroud)
Eer*_*ist 10
建立在Wasim A的基础之上.使用序列化的绝佳主意.问题是在提交表单时也显示了警告.这已在此处修复.
var isSubmitting = false
$(document).ready(function () {
$('form').submit(function(){
isSubmitting = true
})
$('form').data('initial-state', $('form').serialize());
$(window).on('beforeunload', function() {
if (!isSubmitting && $('form').serialize() != $('form').data('initial-state')){
return 'You have unsaved changes which will not be saved.'
}
});
})
Run Code Online (Sandbox Code Playgroud)
它已在Chrome和IE 11中测试过.
基于之前的答案,并从堆栈溢出的各个位置拼凑在一起,这是我想出的解决方案,当你真正想要提交你的更改时:
window.thisPage = window.thisPage || {};
window.thisPage.isDirty = false;
window.thisPage.closeEditorWarning = function (event) {
if (window.thisPage.isDirty)
return 'It looks like you have been editing something' +
' - if you leave before saving, then your changes will be lost.'
else
return undefined;
};
$("form").on('keyup', 'textarea', // You can use input[type=text] here as well.
function () {
window.thisPage.isDirty = true;
});
$("form").submit(function () {
QC.thisPage.isDirty = false;
});
window.onbeforeunload = window.thisPage.closeEditorWarning;
Run Code Online (Sandbox Code Playgroud)
值得注意的是IE11似乎要求closeEditorWarning函数返回undefined它不显示警报.
以下单行为我工作.
window.onbeforeunload = s => modified ? "" : null;
Run Code Online (Sandbox Code Playgroud)
根据应用程序的状态设置modified为true或false.
小智 5
您可以使用 serialize() 通过序列化表单值来创建 URL 编码的文本字符串,并在卸载之前检查表单是否已更改
$(document).ready(function(){
var form = $('#some-form'),
original = form.serialize()
form.submit(function(){
window.onbeforeunload = null
})
window.onbeforeunload = function(){
if (form.serialize() != original)
return 'Are you sure you want to leave?'
}
})
Run Code Online (Sandbox Code Playgroud)
请参阅此链接https://coderwall.com/p/gny70a/alert-when-leaving-page-with-unsaved-form 由 Vladimir Sidorenko 撰写
| 归档时间: |
|
| 查看次数: |
232158 次 |
| 最近记录: |