警报未保存的表单更改

时间:2012-08-07 10:46:11

标签: javascript jquery

我想在主文件中编写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()不起作用?

7 个答案:

答案 0 :(得分:95)

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

未找到$的编辑:

此错误只能由以下三种原因之一引起:

  
      
  1. 您的JavaScript文件未正确加载到您的页面中
  2.   
  3. 你有一个拙劣的jQuery版本。这可能是因为有人编辑了核心文件,或者插件可能覆盖了$   变量
  4.   
  5. 在页面完全加载之前,您已经运行了JavaScript,因此,在jQuery完全加载之前。
  6.   

确保所有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文件中添加以上代码。

希望这有帮助。

答案 1 :(得分:11)

使用表单序列化的版本:

当dom准备就绪时执行此代码:

<folder name="Folder1">
    <shortcut url="http://A.com" name="A" />
    <shortcut url="http://B.com" name="B" />
    <folder name="1.1">
        <shortcut url="http://C.com" name="C" />
    </folder>
    <folder name="Folder1.2">
        <shortcut url="http://D.com" name="D" />
    </folder>
</folder>
<folder name="Folder2">
    ...
</folder>

如果用户更改字段然后手动回滚,则不会显示警告

答案 2 :(得分:2)

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

更改事件。

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

P.S。 我希望你知道你检测变化的方法不是最好的方法吗?如果用户输入了一些文本,请离开该字段然后恢复更改,脚本仍然会提醒他有关修改后的文本。

答案 3 :(得分:2)

如果您的意思是带有文本框的textarea,您不仅要注册输入,还要注册textareas。您可以将keyup用于isChange,这样就不会等待用户在此区域模糊。

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

答案 4 :(得分:1)

为什么不简单地将事件绑定到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
});

答案 5 :(得分:1)

这实际上只是@ 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

这在以下方面更好:

  • 恕我直言,恕我直言,coffeescript自动变得更好。 :)
  • 它完全基于事件冒泡,因此动态内容会自动处理(@ AlphaMale的更新也有此功能)。
  • 它仅在POST表单上运行,因为GET表单没有我们通常希望避免丢失的数据(即GET表单往往是搜索框和过滤条件)。
  • 不需要绑定到执行保存的特定按钮。无论何时提交表单,我们都认为提交是保存的。
  • Turbolinks兼容。如果您不需要,只需删除两个page:事件绑定。
  • 它的设计使您可以将其与JS的其余部分一起包含,并且您的整个网站都将受到保护。

答案 6 :(得分:0)

我使用$('form').change等函数来设置脏位变量。不适合捕捉所有更改(按照之前的答案),但在我的应用中捕捉到我感兴趣的所有内容。