ASP.NET,jQuery,脏表单和window.onbeforeunload

在我的ASP.NET Web应用程序中,我正在尝试创建一种警告用户的通用方法,然后在使用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;} 

这有助于警告用户导航。 问题是我在每个同页的回发中收到警告。 我的表单上有很多东西可能会触发回发:

  1. 页面上有“保存”,“取消”和“删除”链接按钮
  2. 页面上可能还有其他链接按钮,它们在同一页面上执行服务器端function
  3. 可能有其他控件使用autopostback = true,它们也附加了服务器端函数,但不会导致用户离开页面。

这些都不会引发警告,因为用户不会离开页面。 我的代码试图劫持addToPostBack( 在这个问题中有更多细节 )在发回之前清除isDirty位,但问题是IE onbeforeunload在__doPostBack之前触发,显然是因为IE在点击链接时立即触发onb​​eforeunload(如上所述) 在这里 )。

当然,我可以连接每个控件以清除isDirty位,但我更喜欢在表单级别上运行的解决方案,并且不需要我触摸可能触发回发的每个控件。

有没有人有一个在ASP.NET中工作的方法,并不涉及连接可能导致回发的每个控件?

我在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; } 

您总是可以创建一个具有自定义OnLoad / OnUnload方法的onheirited页面类,该方法可以立即执行javascript。

然后,您不必在控件特定级别处理它,而是在表单/页面级别处理它。

有趣,但是…为什么不用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; ··· 

现在,如果仍然导致相同的问题(在submitunload触发),你可以尝试不同的事件树 ,所以不要直接调用__doPostBack ,而是……

 setTimeout(function( ) { __doPastBack(defaultSubmitControl || $('form :submit[id]').get(0).id, ''); }, 1); // I think using 0 (zero) works too 

我没有尝试过这个,而且它是我的头脑,但我认为这可能是一种解决方法。

通过基本跟踪鼠标位置来实现此function。 请记住,您仍然可以获得Y值的正值(因此我的<50行代码),但只要您的提交按钮超过100像素,您应该没问题。

这是我添加的Javascript,用于跟踪鼠标更改并捕获onbeforeunload事件:

    

然后只需将以下表单添加到您的页面:

  

就是这样! 它可以使用一点清理(删除MouseX等),但这在我现有的ASP.net 3.5应用程序中工作,并认为我会发布以帮助任何人。 适用于IE 7和Firefox 3.6,还没有尝试过Chrome。

我也在照顾这个,但到目前为止我发现的是一个使用所有html控件而不是asp.net web控件的解决方案,你有没有想过这个?