在我的ASP.NET网络应用程序中,我正在尝试创建一种警告用户的通用方法,然后在使用jQuery进行更改时导航离开表单。非常标准的东西,但经过大量的搜索,我还没有找到一种有效的技术。
这就是我现在所拥有的:
addToPostBack = function(func) {
var old__doPostBack = __doPostBack;
if (typeof __doPostBack != 'function') {
__doPostBack = func;
} else {
__doPostBack = function() {
old__doPostBack();
func();
}
}
}
var isDirty = false;
$(document).ready(function() {
addToPostBack(function() {
alert("Postback detected.")
clearDirty();
});
$(':input').bind("change select keydown", setDirty);
window.onbeforeunload = function(e) {
var msg = "You have unsaved changes. "
if (isDirty == true) {
var e = e || window.event;
if (e) { e.returnValue = msg; }
return msg;
}
};
});
setDirty = function() {isDirty = true;}
clearDirty = function() {isDirty = false;}
这可以防止用户导航。问题是我在每个同页的回发中收到警告。我的表单上有很多东西可能会触发回发:
这些都不会引发警告,因为用户不会离开页面。我的代码试图劫持addToPostBack(more details on that in this question)以在发回之前清除isDirty位,但问题是IE onbeforeunload
在__doPostBack之前触发,显然是因为IE在点击链接时立即触发onbeforeunload( as described here)。
当然,我可以连接每个控件以清除isDirty位,但我更喜欢在表单级别上运行的解决方案,并且不需要触及可能触发回发的每个控件。
有没有人有一种在ASP.NET中工作的方法,并且不涉及连接每个可能导致回发的控件?
答案 0 :(得分:8)
我在Googling寻找在MVC中做同样事情的解决方案时遇到过这篇文章。这个解决方案改编自上面的Herb,似乎效果很好。由于没有关于此的MVC特定内容,因此对于PHP,Classic ASP或使用HTML和JQuery的任何其他类型的应用程序来说,它应该也能正常工作。
var isDirty = false;
$(document).ready(function () {
$(':input').bind("change select keydown", setDirty);
$('form').submit(clearDirty);
window.onbeforeunload = function (e) {
var msg = "You have unsaved changes. "
if (isDirty == true) {
var e = e || window.event;
if (e) { e.returnValue = msg; }
return msg;
}
};
});
setDirty = function () { isDirty = true; }
clearDirty = function () { isDirty = false; }
答案 1 :(得分:2)
您总是可以创建一个具有自定义OnLoad / OnUnload方法的onheirited页面类,该方法可以立即执行javascript。
然后,您不必在控件特定级别处理它,而是在表单/页面级别处理它。
答案 2 :(得分:2)
有趣,但是......你为什么不用jQuery做所有事情?
var defaultSubmitControl = false;
var dirty = false;
$(document).ready(function( ) {
$('form').submit(function( ) { dirty = false });
$(window).unload(function( ) {
if ( dirty && confirm('Save?') ) {
__doPastBack(defaultSubmitControl || $('form :submit[id]').get(0).id, '');
}
});
});
···
dirty = true;
···
现在,如果仍然导致相同的问题(unload
之前触发submit
),您可以尝试使用其他事件树,而不是调用{{1}直接你做...
__doPostBack
我没有尝试过这个问题,而且我认为这可能是解决问题的方法。
答案 3 :(得分:1)
通过基本跟踪鼠标位置来实现此功能。请记住,您仍然可以获得Y值的正值(因此我的<50行代码),但只要您的提交按钮超过100像素,就可以了。
这是我添加的Javascript,用于跟踪鼠标更改并捕获onbeforeunload事件:
<script language="JavaScript1.2">
<!--
// Detect if the browser is IE or not.
// If it is not IE, we assume that the browser is NS.
var IE = document.all?true:false
// If NS -- that is, !IE -- then set up for mouse capture
if (!IE) document.captureEvents(Event.MOUSEMOVE)
// Set-up to use getMouseXY function onMouseMove
document.onmousemove = getMouseXY;
// Temporary variables to hold mouse x-y pos.s
var tempX = 0
var tempY = 0
// Main function to retrieve mouse x-y pos.s
function getMouseXY(e) {
if (IE) { // grab the x-y pos.s if browser is IE
tempX = event.clientX + document.body.scrollLeft
tempY = event.clientY + document.body.scrollTop
} else { // grab the x-y pos.s if browser is NS
tempX = e.pageX
tempY = e.pageY
}
// catch possible negative values in NS4
if (tempX < 0){tempX = 0}
if (tempY < 0){tempY = 0}
// show the position values in the form named Show
// in the text fields named MouseX and MouseY
document.Show.MouseX.value = tempX
document.Show.MouseY.value = tempY
return true
}
//-->
</script>
<script type="text/javascript">
window.onbeforeunload = HandleOnClose;
function HandleOnClose(e) {
var posY = 0;
var elem = document.getElementsByName('MouseY');
if (elem[0]) {
posY = elem[0].value;
}
if (posY < 50) { // Your form "submit" buttons will hopefully be more than 100 pixels down due to movement
return "You have not selected an option, are you sure you want to close?";
}
}
</script>
然后只需将以下表单添加到您的页面上:
<form name="Show">
<input type="hidden" name="MouseX" value="0" size="4">
<input type="hidden" name="MouseY" value="0" style="display:block" size="0">
</form>
就是这样!它可以使用一点清理(删除MouseX等),但这在我现有的ASP.net 3.5应用程序中工作,并认为我会发布以帮助任何人。适用于IE 7和Firefox 3.6,尚未尝试使用Chrome。
答案 4 :(得分:0)
我也在照顾这个,但到目前为止我发现的是一个使用所有 html控件而不是asp.net web控件的解决方案,你有没有想到这个?
<script type="text/javascript">
$(document).ready(function () {
$("form").dirty_form();
$("#btnCancel").dirty_stopper();
});
</script>