如何显示“您确定要离开此页面吗?” 何时提交更改?


267

在stackoverflow中,如果您开始进行更改,然后尝试离开该页面,则会显示一个javascript确认按钮,并询问:“确定要离开此页面吗?” blee blah bloo ...

以前有人实施过此功能,如何跟踪所做的更改?我相信我自己可以做到,我正在尝试向您的专家学习良好做法。

我尝试了以下操作,但仍然无法正常工作:

<html>
<body>
    <p>Close the page to trigger the onunload event.</p>
    <script type="text/javascript">
        var changes = false;        
        window.onbeforeunload = function() {
            if (changes)
            {
                var message = "Are you sure you want to navigate away from this page?\n\nYou have started writing or editing a post.\n\nPress OK to continue or Cancel to stay on the current page.";
                if (confirm(message)) return true;
                else return false;
            }
        }
    </script>

    <input type='text' onchange='changes=true;'> </input>
</body>
</html>

有人可以举一个例子吗?


3
为了使示例工作正常,请将函数更改为:myFunction(){window.onbeforeunload =“ message”; },然后更改输入:<input type ='text'onchange ='myFunction();'> </ input>
Keith

Answers:


367

更新(2017)

现在,现代浏览器认为将自定义消息显示为安全隐患,因此已将从所有消息中删除。现在,浏览器仅显示常规消息。由于我们不再需要担心设置消息的问题,因此非常简单:

// Enable navigation prompt
window.onbeforeunload = function() {
    return true;
};
// Remove navigation prompt
window.onbeforeunload = null;

阅读以下内容以获取旧版浏览器支持。

更新(2013)

原始答案适用于IE6-8和FX1-3.5(这是我们在2009年编写时所针对的目标),但现在已经过时了,在大多数当前的浏览器中都无法使用-我已经离开了下面以供参考。

window.onbeforeunload所有浏览器都没有一致的处理。它应该是函数引用,而不是字符串(如原始答案所述),但它将在较旧的浏览器中工作,因为对大多数浏览器的检查似乎是是否已分配了任何内容onbeforeunload(包括返回的函数null)。

您设置window.onbeforeunload为函数引用,但是在较旧的浏览器中,您必须设置returnValue事件的,而不仅仅是返回字符串:

var confirmOnPageExit = function (e) 
{
    // If we haven't been passed the event get the window.event
    e = e || window.event;

    var message = 'Any text will block the navigation and display a prompt';

    // For IE6-8 and Firefox prior to version 4
    if (e) 
    {
        e.returnValue = message;
    }

    // For Chrome, Safari, IE8+ and Opera 12+
    return message;
};

confirmOnPageExit如果您希望用户在没有消息的情况下继续操作,则无法进行检查并返回null。您仍然需要删除事件以可靠地打开和关闭该事件:

// Turn it on - assign the function that returns the string
window.onbeforeunload = confirmOnPageExit;

// Turn it off - remove the function entirely
window.onbeforeunload = null;

原始答案(2009年工作)

打开它:

window.onbeforeunload = "Are you sure you want to leave?";

要将其关闭:

window.onbeforeunload = null;

请记住,这不是正常事件-您无法以标准方式绑定到该事件。

要检查值?这取决于您的验证框架。

在jQuery中,可能类似于(非常基本的示例):

$('input').change(function() {
    if( $(this).val() != "" )
        window.onbeforeunload = "Are you sure you want to leave?";
});

4
就像是这样:$('input:text')。change(function(){window.onbeforeunload = $('input:text [value!=“”]')。length> 0?“ warning”:null ;});
基思

1
对于简单的检查,或者您可以为每个更改添加更复杂的验证
Keith,2009年

1
值得注意的是,“ returnValue”方法是标准中指定的唯一方法,因此它不仅适用于IE6-8,而且适用于所有符合标准的浏览器(在这种情况下,不包括Chrome,Safari和Opera)。
rmcclellan 2014年

3
为了停止表单提交的警报,我使用了$("#submit_button").click(function() { window.onbeforeunload = null; });。我最初使用的是按钮的onclick事件,但不尽如人意,它也不适用于IE8。
安迪·贝弗利

1
@ AlikElzin-kilaka,你不能。如果要更改弹出文本,则需要创建自己的自定义弹出窗口,但这不能阻止window.onbeforeunload事件。
基思

38

onbeforeunload微软主义是我们要一个标准的解决方案,但要知道,浏览器支持参差不齐最接近; 例如,对于Opera,它仅在版本12和更高版本中有效(在撰写本文时仍为Beta)。

另外,为了获得最大的兼容性,您需要做的不仅仅是返回字符串,还需要做更多的事情,如Mozilla开发人员网络上所述。

示例:定义以下两个用于启用/禁用导航提示的功能(请参见MDN示例):

function enableBeforeUnload() {
    window.onbeforeunload = function (e) {
        return "Discard changes?";
    };
}
function disableBeforeUnload() {
    window.onbeforeunload = null;
}

然后定义如下形式:

<form method="POST" action="" onsubmit="disableBeforeUnload();">
    <textarea name="text"
              onchange="enableBeforeUnload();"
              onkeyup="enableBeforeUnload();">
    </textarea>
    <button type="submit">Save</button>
</form>

这样,仅当用户更改了文本区域时,才会警告用户导航,并且在实际提交表单时不会提示用户。


1
基于Mozill的网站,现在最新的桌面浏览器都支持该网站:developer.mozilla.org/en/DOM/window.onbeforeunload
Hengjie

微软主义是一个伟大的名词。
卢克·泰勒


18

使用JQuery,这东西很容易做到。既然可以绑定到集合。

它不足以完成onbeforeunload,您只想在有人开始编辑内容时触发导航。


2
似乎无法访问@jonstjohn的博客文章。也许他会成为好朋友,并向我们指出正确的方向?:D
FLGMwt 2014年

14
=> 500内部错误。这就是为什么SO不推荐使用链接的原因。降低票数直到修正。
卢瓦克

该网页不可用
Mateusz

2
尽管此链接可以回答问题,但最好在此处包括答案的基本部分,并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会无效。
2015年

2
Jon St John原始链接已损坏,因此我将其更新为Wayback Machine版本。链接的内容可以在许多其他网站上找到,但我想最好“保留”山姆添加的内容
Alvaro Montoro



11

如果在表单中输入了任何数据,这是一种显示消息的简单方法,如果提交了表单,则不显示消息:

$(function () {
    $("input, textarea, select").on("input change", function() {
        window.onbeforeunload = window.onbeforeunload || function (e) {
            return "You have unsaved changes.  Do you want to leave this page and lose your changes?";
        };
    });
    $("form").on("submit", function() {
        window.onbeforeunload = null;
    });
})

8

扩展Keith已经很惊人的答案

自定义警告消息

要允许自定义警告消息,可以将其包装为以下函数:

function preventNavigation(message) {
    var confirmOnPageExit = function (e) {
        // If we haven't been passed the event get the window.event
        e = e || window.event;

        // For IE6-8 and Firefox prior to version 4
        if (e)
        {
            e.returnValue = message;
        }

        // For Chrome, Safari, IE8+ and Opera 12+
        return message;
    };
    window.onbeforeunload = confirmOnPageExit;
}

然后,使用您的自定义消息调用该函数:

preventNavigation("Baby, please don't go!!!");

再次启用导航

要重新启用导航,只需将设置window.onbeforeunloadnull。它包装在一个整洁的小函数中,可以在任何地方调用:

function enableNavigation() {
    window.onbeforeunload = null;
}

使用jQuery将其绑定到表单元素

如果使用jQuery,则可以轻松地将其绑定到表单的所有元素,如下所示:

$("#yourForm :input").change(function() {
    preventNavigation("You have not saved the form. Any \
        changes will be lost if you leave this page.");
});

然后允许提交表格:

$("#yourForm").on("submit", function(event) {
    enableNavigation();
});

动态修改的表单:

preventNavigation()并且enableNavigation()可以根据需要绑定到任何其他功能,例如动态修改表单或单击发送AJAX请求的按钮。我是通过向表单添加一个隐藏的输入元素来实现的:

<input id="dummy_input" type="hidden" />

然后,每当我想阻止用户导航时,都会触发该输入的更改以确保已preventNavigation()执行:

function somethingThatModifiesAFormDynamically() {

    // Do something that modifies a form

    // ...
    $("#dummy_input").trigger("change");
    // ...
}

3

在这里尝试一下,它可以工作100%

<html>
<body>
<script>
var warning = true;
window.onbeforeunload = function() {  
  if (warning) {  
    return "You have made changes on this page that you have not yet confirmed. If you navigate away from this page you will lose your unsaved changes";  
    }  
}

$('form').submit(function() {
   window.onbeforeunload = null;
});
</script>
</body>
</html>

3

标准指出,可以通过取消beforeunload事件或将返回值设置为非null值来控制提示。它还指出作者应该使用Event.preventDefault()而不是returnValue,并且显示给用户的消息不是可定制的

截至69.0.3497.92,Chrome浏览器尚未达到标准。但是,提交了一个错误报告,并且正在进行审查。Chrome要求通过引用事件对象而不是处理程序返回的值来设置returnValue。

跟踪是否已进行更改是作者的责任;可以使用变量来完成,也可以通过确保仅在必要时处理事件来完成。

window.addEventListener('beforeunload', function (e) {
    // Cancel the event as stated by the standard.
    e.preventDefault();
    // Chrome requires returnValue to be set.
    e.returnValue = '';
});
    
window.location = 'about:blank';


2

当用户开始更改表单时,将设置一个布尔标志。如果用户随后尝试离开该页面,请在window.onunload事件中检查该标志。如果设置了标志,则通过将其作为字符串返回来显示消息。以字符串形式返回消息将弹出一个确认对话框,其中包含您的消息。

如果您正在使用ajax提交更改,则可以在提交更改false后(即在ajax成功事件中)将标志设置为。


1

您可以onchange在textarea(或任何其他字段)上添加一个在JS中设置变量的事件。当用户尝试关闭页面(window.onunload)时,您检查该变量的值并相应显示警报。


1
你不能做到这一点- alert并且confirm在被封锁window.onbeforeunload,并window.onunload(在Chrome中的我的电脑上的版本至少是,但也可能在每一个浏览器曾经支持这些处理器)。
Mark Amery

1

基于此线程的所有答案,我编写了以下代码,它对我有用。

如果只有一些输入/文本区域标记需要检查onunload事件,则可以将HTML5数据属性分配为 data-onunload="true"

例如

<input type="text" data-onunload="true" />
<textarea data-onunload="true"></textarea>

并且Javascript(jQuery)可以如下所示:

$(document).ready(function(){
    window.onbeforeunload = function(e) {
        var returnFlag = false;
        $('textarea, input').each(function(){
            if($(this).attr('data-onunload') == 'true' && $(this).val() != '')
                returnFlag = true;
        });

        if(returnFlag)
            return "Sure you want to leave?";   
    };
});

2
另请参见MDN的beforeunload文档中的“由于某些原因,基于Webkit的浏览器不遵循对话框的规范”
Arjan

1

这是我的html

<!DOCTYPE HMTL>
<meta charset="UTF-8">
<html>
<head>
<title>Home</title>
<script type="text/javascript" src="script.js"></script>
</head>

 <body onload="myFunction()">
    <h1 id="belong">
        Welcome To My Home
    </h1>
    <p>
        <a id="replaceME" onclick="myFunction2(event)" href="https://www.ccis.edu">I am a student at Columbia College of Missouri.</a>
    </p>
</body>

所以这就是我在javaScript中做类似的事情的方式

var myGlobalNameHolder ="";

function myFunction(){
var myString = prompt("Enter a name", "Name Goes Here");
    myGlobalNameHolder = myString;
    if (myString != null) {
        document.getElementById("replaceME").innerHTML =
        "Hello " + myString + ". Welcome to my site";

        document.getElementById("belong").innerHTML =
        "A place you belong";
    }   
}

// create a function to pass our event too
function myFunction2(event) {   
// variable to make our event short and sweet
var x=window.onbeforeunload;
// logic to make the confirm and alert boxes
if (confirm("Are you sure you want to leave my page?") == true) {
    x = alert("Thank you " + myGlobalNameHolder + " for visiting!");
}
}

0

通过在TextArea的onChange事件上将ChangeFlag设置为true,可以轻松完成此操作。使用javascript显示基于ChangeFlag值的确认对话框。如果确认返回true,则丢弃表单并导航到请求的页面,否则执行no-thing



-1

body标签有一个“ onunload”参数,您可以从那里调用javascript函数。如果返回false,则将阻止导航。


13
幸运的是,这实际上是行不通的。否则,我不希望访问包含的页面<body onunload="return false;">
索伦Løvborg
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.