Bagaimana cara menunjukkan "Apakah Anda yakin ingin bernavigasi dari halaman ini?" kapan perubahan dilakukan?

267

Di sini, di stackoverflow, jika Anda mulai melakukan perubahan maka Anda mencoba menavigasi menjauh dari halaman, tombol konfirmasi javascript muncul dan bertanya: "Apakah Anda yakin ingin menavigasi menjauh dari halaman ini?" blee bla bloo ...

Adakah yang pernah menerapkan ini sebelumnya, bagaimana cara melacak bahwa perubahan dilakukan? Saya percaya saya bisa melakukan ini sendiri, saya mencoba mempelajari praktik yang baik dari Anda para ahli.

Saya mencoba yang berikut tetapi masih tidak berhasil:

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

Adakah yang bisa memposting contoh?

Shimmy Weitzhandler
sumber
3
Untuk membuat contoh Anda berfungsi, ubah fungsi menjadi: myFunction () {window.onbeforeunload = "message"; } kemudian ubah input: <input type = 'text' onchange = 'myFunction ();'> </input>
Keith
Terkait: stackoverflow.com/q/821011/435605
AlikElzin-kilaka

Jawaban:

367

Pembaruan (2017)

Browser modern sekarang mempertimbangkan menampilkan pesan khusus sebagai bahaya keamanan dan karenanya telah dihapus dari semuanya. Browser sekarang hanya menampilkan pesan umum. Karena kita tidak perlu lagi khawatir tentang pengaturan pesan, itu sesederhana:

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

Baca di bawah untuk dukungan browser lawas.

Pembaruan (2013)

Jawaban asli cocok untuk IE6-8 dan FX1-3.5 (yang kami targetkan kembali pada tahun 2009 ketika ditulis), tetapi agak ketinggalan zaman sekarang dan tidak akan berfungsi di sebagian besar browser saat ini - saya telah meninggalkan di bawah ini untuk referensi.

Ini window.onbeforeunloadtidak diperlakukan secara konsisten oleh semua browser. Itu harus berupa referensi fungsi dan bukan string (seperti jawaban asli dinyatakan) tetapi itu akan berfungsi di browser yang lebih lama karena cek untuk sebagian besar dari mereka tampaknya apakah ada sesuatu yang ditugaskan onbeforeunload(termasuk fungsi yang mengembalikan null).

Anda mengatur window.onbeforeunloadke referensi fungsi, tetapi di browser lama Anda harus mengatur returnValueacara bukan hanya mengembalikan string:

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

Anda tidak dapat confirmOnPageExitmelakukan itu dengan memeriksa dan mengembalikan nol jika Anda ingin pengguna melanjutkan tanpa pesan. Anda masih harus menghapus acara untuk menyalakan dan mematikannya dengan andal:

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

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

Jawaban asli (bekerja pada 2009)

Untuk mengaktifkannya:

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

Untuk mematikannya:

window.onbeforeunload = null;

Ingatlah bahwa ini bukan peristiwa biasa - Anda tidak dapat mengikatnya dengan cara standar.

Untuk memeriksa nilai? Itu tergantung pada kerangka validasi Anda.

Di jQuery ini bisa berupa (contoh sangat mendasar):

$('input').change(function() {
    if( $(this).val() != "" )
        window.onbeforeunload = "Are you sure you want to leave?";
});
Keith
sumber
4
Itu akan menjadi sesuatu seperti: $ ('input: teks'). Ubah (fungsi () {window.onbeforeunload = $ ('input: text [value! = ""]'). Length> 0? "Peringatan": null ;});
Keith
1
Untuk pemeriksaan sederhana, atau Anda dapat menambahkan validasi yang lebih kompleks pada setiap perubahan
Keith
1
perlu dicatat bahwa metode 'returnValue' adalah satu-satunya metode yang ditentukan dalam standar, jadi ini bukan hanya untuk IE6-8, itu untuk semua browser yang sesuai standar (dalam hal ini tidak termasuk Chrome, Safari, dan Opera).
rmcclellan
3
Untuk menghentikan peringatan saat pengiriman formulir, saya menggunakan $("#submit_button").click(function() { window.onbeforeunload = null; });. Saya awalnya menggunakan acara onclick tombol, tetapi selain tidak sebaik, itu juga tidak bekerja dengan IE8.
Andy Beverley
1
@ AlikElzin-kilaka Anda tidak bisa. Jika Anda ingin mengubah teks sembulan maka Anda perlu membuat sembulan sendiri, tetapi itu tidak dapat memblokir window.onbeforeunloadacara tersebut.
Keith
38

Itu onbeforeunload Microsoft-isme adalah hal yang paling dekat kita harus larutan standar, tetapi menyadari bahwa dukungan browser tidak merata; misal untuk Opera, ia hanya berfungsi dalam versi 12 dan yang lebih baru (masih dalam versi beta saat penulisan ini).

Juga, untuk kompatibilitas maksimum , Anda perlu melakukan lebih dari sekadar mengembalikan string, seperti yang dijelaskan pada Jaringan Pengembang Mozilla .

Contoh: Tetapkan dua fungsi berikut untuk mengaktifkan / menonaktifkan prompt navigasi (lih. Contoh MDN):

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

Kemudian tentukan formulir seperti ini:

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

Dengan cara ini, pengguna hanya akan diperingatkan tentang menavigasi jika dia telah mengubah area teks, dan tidak akan diminta ketika dia benar-benar mengirimkan formulir.

Søren Løvborg
sumber
1
Berdasarkan situs Mozill, sebagian besar peramban desktop terkini mendukungnya: developer.mozilla.org/en/DOM/window.onbeforeunload
Hengjie
Microsoft-isme adalah istilah yang bagus.
Luke Taylor
18

Dengan JQuery , hal ini cukup mudah dilakukan. Karena Anda dapat mengikat ke set.

Tidak cukup untuk melakukan onbeforeunload, Anda hanya ingin memicu navigasi pergi jika seseorang mulai mengedit barang.

Sam Saffron
sumber
2
Sepertinya tidak bisa mengenai posting blog @jonstjohn. Mungkin dia akan menjadi teman dan mengarahkan kita ke arah yang benar? : D
FLGMwt
14
=> 500 Kesalahan internal. Itu sebabnya tautan tidak digunakan lagi di SO. Turun ke bawah sampai diperbaiki.
Loïc
Halaman web ini tidak tersedia
Mateusz
2
Meskipun tautan ini dapat menjawab pertanyaan, lebih baik untuk memasukkan bagian-bagian penting dari jawaban di sini dan memberikan tautan untuk referensi. Jawaban hanya tautan dapat menjadi tidak valid jika halaman tertaut berubah.
bwest
2
The link asli dari Jon St John rusak, jadi saya diperbarui ke Wayback Machine versi itu. Konten tautan dapat ditemukan disalin di banyak situs lain, tetapi saya kira lebih baik "mempertahankan" yang ditambahkan Sam
Alvaro Montoro
14

jquerys 'beforeunload' bekerja bagus untukku

$(window).bind('beforeunload', function(){
    if( $('input').val() !== '' ){
        return "It looks like you have input you haven't submitted."
    }
});
Devon Peticolas
sumber
Bind telah ditinggalkan dan versi kode yang lebih baru yang serupa dengan ini dapat dilihat dalam jawaban ini: stackoverflow.com/a/1889450/908677
Elijah Lofgren
12

untuk orang baru yang mencari solusi sederhana, coba saja Areyousure.js

lawphotog
sumber
11

Ini adalah cara mudah untuk menyajikan pesan jika ada data yang dimasukkan ke dalam formulir, dan tidak menunjukkan pesan jika formulir dikirimkan:

$(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;
    });
})
Carl G
sumber
8

Untuk memperluas jawaban Keith yang sudah luar biasa :

Pesan peringatan khusus

Untuk mengizinkan pesan peringatan khusus, Anda dapat membungkusnya dalam fungsi seperti ini:

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

Kemudian panggil fungsi itu dengan pesan khusus Anda:

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

Mengaktifkan navigasi lagi

Untuk mengaktifkan kembali navigasi, yang perlu Anda lakukan adalah menyetel window.onbeforeunloadke null. Ini dia, dibungkus dengan fungsi kecil yang rapi yang bisa dipanggil di mana saja:

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

Menggunakan jQuery untuk mengikat ini untuk membentuk elemen

Jika menggunakan jQuery, ini dapat dengan mudah terikat ke semua elemen formulir seperti ini:

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

Kemudian untuk memungkinkan formulir dikirimkan:

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

Bentuk yang dimodifikasi secara dinamis:

preventNavigation()dan enableNavigation()dapat terikat ke fungsi lain yang diperlukan, seperti memodifikasi formulir secara dinamis, atau mengklik tombol yang mengirimkan permintaan AJAX. Saya melakukan ini dengan menambahkan elemen input tersembunyi ke formulir:

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

Lalu kapan pun saya ingin mencegah pengguna menavigasi, saya memicu perubahan pada input itu untuk memastikan bahwa preventNavigation()dieksekusi:

function somethingThatModifiesAFormDynamically() {

    // Do something that modifies a form

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

Di sini coba ini berfungsi 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>
Braydon
sumber
3

The negara standar yang bisikan dapat dikontrol dengan membatalkan beforeunload acara atau pengaturan nilai kembali ke nilai non-null . Ini juga menyatakan bahwa penulis harus menggunakan Event.preventDefault () alih-alih returnValue, dan pesan yang ditampilkan kepada pengguna tidak dapat dikustomisasi .

Pada 69.0.3497.92, Chrome belum memenuhi standar. Namun, ada laporan bug yang diajukan, dan tinjauan sedang berlangsung. Chrome mengharuskan returnValue harus ditetapkan dengan merujuk ke objek acara, bukan nilai yang dikembalikan oleh pawang.

Adalah tanggung jawab penulis untuk melacak apakah perubahan telah dilakukan; itu bisa dilakukan dengan variabel atau dengan memastikan acara hanya ditangani bila perlu.

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

Trevor Karjanis
sumber
2

Saat pengguna mulai membuat perubahan pada formulir, bendera boolean akan ditetapkan. Jika pengguna kemudian mencoba menavigasi jauh dari halaman, Anda memeriksa tanda itu di window.onunload acara. Jika flag diatur, Anda menunjukkan pesan dengan mengembalikannya sebagai string. Mengembalikan pesan sebagai string akan memunculkan dialog konfirmasi yang berisi pesan Anda.

Jika Anda menggunakan ajax untuk melakukan perubahan, Anda dapat mengatur bendera falsesetelah perubahan dilakukan (yaitu dalam acara sukses ajax).

Kirtan
sumber
1

Anda bisa menambahkan onchangeacara di textarea (atau bidang lainnya) yang mengatur variabel dalam JS. Ketika pengguna mencoba untuk menutup halaman (window.onunload) Anda memeriksa nilai variabel itu dan menunjukkan peringatan yang sesuai.

Makram Saleh
sumber
1
Anda tidak dapat melakukan ini - alertdan confirmdiblokir selama window.onbeforeunloaddan window.onunload(paling tidak dalam versi Chrome di PC saya, tetapi mungkin juga di setiap browser yang mendukung penangan tersebut).
Mark Amery
1

Berdasarkan semua jawaban di utas ini, saya menulis kode berikut dan itu berhasil untuk saya.

Jika Anda hanya memiliki beberapa tag input / textarea yang memerlukan aktivitas onunload untuk diperiksa, Anda dapat menetapkan atribut data HTML5 sebagai data-onunload="true"

untuk mis.

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

dan Javascript (jQuery) dapat terlihat seperti ini:

$(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?";   
    };
});
Sagar Gala
sumber
2
Lihat juga "Untuk beberapa alasan, browser berbasis Webkit tidak mengikuti spesifikasi untuk kotak dialog" di dokumentasi sebelumunload MDN .
Arjan
1

ini html saya

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

Jadi ini adalah bagaimana saya melakukan sesuatu yang serupa di 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!");
}
}
Justin Stone
sumber
0

Hal ini dapat dengan mudah dilakukan dengan menetapkan ChangeFlag ke true, pada onChange acara Textarea . Gunakan javascript untuk menampilkan kotak dialog konfirmasi berdasarkan nilai ChangeFlag . Buang formulir dan navigasikan ke halaman yang diminta jika konfirmasi kembali benar, jika tidak lakukan apa-apa .

cukup keras
sumber
-1

Ada parameter "onunload" untuk tag tubuh Anda dapat memanggil fungsi javascript dari sana. Jika itu kembali palsu itu mencegah menavigasi.

stribika
sumber
13
Untungnya, ini tidak berhasil. Kalau tidak, saya tidak suka mengunjungi halaman yang berisi <body onunload="return false;">.
Søren Løvborg