Javascript 对表单中未保存的更改发出警报

Javascript 对表单中未保存的更改发出警报,javascript,jquery,Javascript,Jquery,我想在主文件中编写Jquery代码,这样,若用户更改了页面并且有任何未保存的更改,那个么用户应该得到警告。 我从中得到了一个答案: 然而,在大多数解决方案中,我必须在所有页面上编写代码。我希望它只写在一个地方,这样每个人都不必担心写在他们的模块。我的代码如下: <script type="text/javascript"> var isChange; $(document).ready(function () { $("input[type='text

我想在主文件中编写Jquery代码,这样,若用户更改了页面并且有任何未保存的更改,那个么用户应该得到警告。 我从中得到了一个答案:

然而,在大多数解决方案中,我必须在所有页面上编写代码。我希望它只写在一个地方,这样每个人都不必担心写在他们的模块。我的代码如下:

<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>

var-isChange;
$(文档).ready(函数(){
$(“输入[type='text']”)。更改(函数(){
isChange=true;
})
});
$(窗口)。卸载(函数(){
如果(iChange){
警报('调用了.unload()的处理程序');
}
});
但每次我在文本框中进行更改时,都不会触发change()事件

代码中可能有什么错误

编辑: 我将.change()更改为.click,它将被触发。我使用的是jquery 1.4.1..是因为jquery版本的缘故,change()不起作用吗?

一旦用户输入模糊,而不是输入的每个字符,就会触发change事件

如果您需要在每次更改某个内容时调用它(即使焦点仍在该输入字段中),那么您必须依靠keyup和一系列事件的组合来仅使用鼠标跟踪粘贴/剪切

附言。
我希望你意识到你检测变化的方法不是最好的?如果用户输入一些文本,离开该字段,然后恢复更改,脚本仍会提醒他修改的文本。

如果您是指文本框中的文本区域,则您不仅应该为输入注册事件,还应该为文本区域注册事件。您可以使用keyup进行iChange,这样就不用等待用户从该区域模糊

$("input[type='text'], textarea").keyup(function () {
    isChange = true;
})

这就是我正在使用的,将所有这些代码放在一个单独的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;
未找到$EDIT:

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版本。这可能是因为有人编辑了核心文件,或者插件可能已经覆盖了核心文件$ 变数
  • 在页面完全加载之前以及jQuery完全加载之前,您已经运行了JavaScript
  • 确保所有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文件中添加上述代码


    希望这有帮助。

    为什么不简单地将事件绑定到
    更改
    回调

    $(":input").change(function()
    {
        $(window).unbind('unload').bind('unload',function()
        {
            alert('unsaved changes on the page');
        });
    });
    
    作为额外奖励,您可以使用
    确认
    并选择触发更改事件的最后一个元素:

    $(":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
    });
    

    这实际上只是@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
    
    这在以下方面更好:

    • 这是咖啡脚本,IMHO会自动让它变得更好。:)
    • 它完全基于事件冒泡,因此动态内容会自动处理(@AlphaMale的更新也有此功能)
    • 它只在POST表单上运行,因为GET表单没有我们通常希望避免丢失的数据(即GET表单往往是搜索框和筛选条件)
    • 它不需要绑定到执行保存的特定按钮。无论何时提交表单,我们都假定提交正在保存
    • 它是兼容的。如果不需要,只需删除两个
      页面:
      事件绑定
    • 它的设计目的是让你可以将它包含在你的JS中,你的整个网站都会受到保护

    使用表单序列化的版本:

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

    如果用户更改字段,然后手动回滚,则不会显示警告。我使用
    $('form')。更改
    等功能设置脏位变量。不适合捕获我的应用程序中的所有更改(根据前面的答案),但捕获我感兴趣的所有内容。

    所有输入字段都是静态的还是一些是动态添加到表单中的(或由ajax加载)?但是在大多数解决方案中,我必须在所有页面上编写代码。为什么不使用外部脚本文件?@Raminson是对的,编写一个外部js文件并将其包含在页面中。非jquery版本:您可以尝试添加警报('asd');未保存前=真;然后报警(未保存);所以,当数据被更改时,您将了解未保存的内容。是的,它是这样的,它只是一个javascript。你包括jquery了吗?是的..我包括了jquery…我刚刚登记了firebug。。我得到的错误是“$not defined”。然而,我已经给出了母版页和其他页面中的参考。如果您单击“保存”按钮,是否有方法使其不运行这很好。很好用,但是你能告诉我为什么它不能在iPhone上使用吗?我们必须使用不同的函数吗?这是一个与更复杂的自定义用户控件一起工作的函数。我自己也采取了这种做法:)