Як показати "Ви впевнені, що хочете перейти з цієї сторінки?" коли відбулися зміни?


267

Тут у stackoverflow, якщо ви почали вносити зміни, то ви намагаєтесь перейти зі сторінки, з’являється кнопка підтвердження javascript і запитує: "Ви впевнені, що хочете перейти від цієї сторінки?" blee bla bla 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"; } потім змінити вхід: <type type = 'text' onchange = 'myFunction ();'> </input>
Keith

Відповіді:


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зробити це, щоб перевірити та повернути нуль, якщо ви бажаєте, щоб користувач продовжував без повідомлення. Потрібно видалити подію, щоб надійно включати та вимикати:

// 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? "Попередження": null ;});
Кіт

1
Для простої перевірки, або ви можете додати більш складну перевірку щодо кожної зміни
Кіт,

1
варто відзначити, що метод returnValue - єдиний метод, зазначений у стандарті, тому це стосується не лише IE6-8, але й усіх браузерів, що відповідають стандартам (у цьому випадку не включаються Chrome, Safari та Opera).
rmcclellan

3
Щоб зупинити попередження про надсилання форми, я використав $("#submit_button").click(function() { window.onbeforeunload = null; });. Я спочатку використовував подію onclick кнопки, але, як це не так добре, він також не працював з IE8.
Енді Беверлі

1
@ AlikElzin-kilaka ви не можете. Якщо ви хочете змінити спливаючий текст, тоді вам потрібно створити власне користувацьке спливаюче вікно, але це не може блокувати window.onbeforeunloadподію.
Кіт

38

onbeforeunloadMicrosoft-Ізмаїл ближче за все ми повинні стандартне рішення, але майте в виду , що підтримка браузера нерівномірно; наприклад, для Opera вона працює лише у версії 12 та пізнішої версії (як і раніше в бета-версії).

Крім того, для максимальної сумісності вам потрібно зробити більше, ніж просто повернути рядок, як пояснено в Мережі розробників 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/uk/DOM/window.onbeforeunload
Hengjie

Microsoft-ism - чудовий термін.
Люк Тейлор


18

З JQuery це легко зробити. Так як ви можете прив’язати до множин.

Цього НЕ достатньо, щоб виконати завантаження, ви хочете лише запустити навігацію, якщо хтось почав редагувати матеріали.


2
Здається, не потрапило до публікацій блогу @jonstjohn. Може, він стане товаришем і вкаже нас у правильному напрямку? : D
FLGMwt

14
=> 500 Внутрішня помилка. Ось чому застарілі посилання на SO. Захищено до фіксації.
Loïc

Ця веб-сторінка недоступна
Матеуш

2
Хоча це посилання може відповісти на питання, краще включити сюди суттєві частини відповіді та надати посилання для довідки. Відповіді лише на посилання можуть стати недійсними, якщо пов’язана сторінка зміниться.
bwest

2
Оригінальна посилання від Jon St John був зламаний, тому я оновив його на Вайбак Machine варіант. Вміст посилання можна знайти скопійовано на багатьох інших сайтах, але, мабуть, краще було «зберегти» той, який додав Сем
Альваро Монторо

14

jquerys 'beforeunload' відмінно працював для мене

$(window).bind('beforeunload', function(){
    if( $('input').val() !== '' ){
        return "It looks like you have input you haven't submitted."
    }
});

Прив'язка застаріла, і новішу версію коду, подібного до цього, можна побачити у цій відповіді: stackoverflow.com/a/1889450/908677
Ілля Лофгрен


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

Щоб розширити вже дивовижну відповідь Кіта :

Спеціальні попереджувальні повідомлення

Щоб дозволити користувацькі попереджувальні повідомлення, ви можете перетворити їх у таку функцію:

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

Ось спробуйте це працює 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 події або встановивши значення, що повертається значення ненульового . У ньому також зазначено, що автори повинні використовувати 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подію до текстової області (або будь-якого іншого поля), яка встановлює змінну в JS. Коли користувач намагається закрити сторінку (window.onunload), ви перевіряєте значення цієї змінної та показуєте попередження відповідно.


1
Ви не можете цього зробити - alertі confirmзаблоковані під час window.onbeforeunloadі window.onunload(принаймні, у версії Chrome на моєму ПК, але, ймовірно, також у кожному браузері, який коли-небудь підтримує ці обробники).
Марк Амері

1

На основі всіх відповідей на цю тему я написав наступний код, і він працював на мене.

Якщо у вас є лише деякі теги вводу / textarea, які потребують перевірки події завантаження, ви можете призначити 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
Дивіться також «З різних причин, Webkit-браузери не дотримуються специфікації для діалогового вікна» в MDN в beforeunload документації .
Ар'ян

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

Це можна легко зробити, встановивши ChangeFlag на true, на onChange події TextArea . Використовуйте javascript, щоб показати діалогове вікно підтвердження на основі значення ChangeFlag . Відмовтеся від форми та перейдіть на запитувану сторінку, якщо підтвердження повертає істину, інакше нічого не робити .



-1

Існує параметр "onunload" для тегу body, звідки ви можете викликати функції javascript. Якщо він повернеться помилковим, він перешкоджає переміщенню.


13
На щастя, це насправді не працює. Інакше мені б не хотілося відвідувати сторінку, що містить <body onunload="return false;">.
Søren Løvborg
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.