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


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.