Как показать «Вы уверены, что хотите перейти от этой страницы?» когда изменения совершены? - PullRequest
243 голосов
/ 13 июля 2009

Здесь, в stackoverflow, если вы начали вносить изменения, то вы пытаетесь уйти со страницы, появляется кнопка подтверждения javascript и спрашивает: «Вы уверены, что хотите уйти с этой страницы?» бле бла бло ...

Кто-нибудь реализовывал это раньше, как я могу отследить, что изменения были зафиксированы? Я полагаю, что мог бы сделать это сам, я пытаюсь изучить передовой опыт у вас, экспертов.

Я попробовал следующее, но все равно не работает:

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

Может кто-нибудь выложить пример?

Ответы [ 17 ]

337 голосов
/ 13 июля 2009

Обновление (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 выполнял проверку и возвращал ноль, если вы хотите, чтобы пользователь продолжил работу без сообщения. Вам все еще нужно удалить событие, чтобы надежно включить и выключить его:

// 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?";
});
37 голосов
/ 13 июля 2009

Microsoft-ism onbeforeunload ближе всего к стандартному решению, но помните, что поддержка браузеров неравномерна; например для Opera это работает только в версии 12 и позже (все еще в бета-версии на момент написания этой статьи).

Кроме того, для максимальной совместимости вам нужно сделать больше, чем просто вернуть строку, как описано в Mozilla Developer Network .

Пример: Задайте следующие две функции для включения / отключения подсказки навигации (см. Пример 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>

Таким образом, пользователь будет предупрежден о выходе из системы только в том случае, если он изменил текстовую область, и не будет запрашиваться при фактической отправке формы.

19 голосов
/ 26 марта 2012

Чтобы сделать это в Chrome и Safari, вам нужно сделать это следующим образом

window.onbeforeunload = function(e) {
    return "Sure you want to leave?";
};

Ссылка: https://developer.mozilla.org/en/DOM/window.onbeforeunload

18 голосов
/ 13 июля 2009

С JQuery это довольно легко сделать. Так как вы можете привязать к наборам.

Этого недостаточно, чтобы выполнить предварительную загрузку, вы можете запускать навигацию только в том случае, если кто-то начал редактировать материал.

13 голосов
/ 11 июля 2012

jquerys 'beforeunload' отлично работает для меня

$(window).bind('beforeunload', function(){
    if( $('input').val() !== '' ){
        return "It looks like you have input you haven't submitted."
    }
});
11 голосов
/ 17 декабря 2013

для новых людей, которые ищут простое решение, просто попробуйте Areyousure.js

11 голосов
/ 03 марта 2013

Это простой способ представить сообщение, если в форму введены какие-либо данные, и не показывать сообщение, если форма отправлена:

$(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;
    });
})
7 голосов
/ 29 декабря 2014

Чтобы расширить на уже удивительный ответ Кита :

Пользовательские предупреждающие сообщения

Чтобы разрешить настраиваемые предупреждающие сообщения, вы можете заключить их в такую ​​функцию:

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.onbeforeunload в null. Вот она, заключенная в аккуратную маленькую функцию, которую можно вызывать где угодно:

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 голосов
/ 01 октября 2013

Вот попробуй это работает 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>
2 голосов
/ 13 июля 2009

Когда пользователь начинает вносить изменения в форму, устанавливается логический флаг. Если пользователь затем пытается отойти от страницы, вы проверяете этот флаг в событии window.onunload . Если флаг установлен, вы показываете сообщение, возвращая его в виде строки. При возврате сообщения в виде строки появится диалоговое окно подтверждения, содержащее ваше сообщение.

Если вы используете ajax для фиксации изменений, вы можете установить флаг на false после того, как изменения были зафиксированы (т.е. в событии успеха ajax).

...