Cách hiển thị các Bạn có chắc chắn muốn điều hướng khỏi trang này không? khi nào thay đổi cam kết?


267

Ở đây trong stackoverflow, nếu bạn bắt đầu thực hiện thay đổi thì bạn cố gắng điều hướng khỏi trang, một nút xác nhận javascript sẽ xuất hiện và hỏi: "Bạn có chắc chắn muốn điều hướng khỏi trang này không?" chảy máu blah bloo ...

Đã có ai thực hiện điều này trước đây chưa, làm cách nào để theo dõi những thay đổi đã được cam kết? Tôi tin rằng tôi có thể tự làm điều này, tôi đang cố gắng học hỏi các thực hành tốt từ các chuyên gia.

Tôi đã thử những cách sau nhưng vẫn không hiệu quả:

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

Bất cứ ai có thể gửi một ví dụ?


3
Để làm cho ví dụ của bạn thay đổi hàm thành: myFunction () {window.onb Beforeunload = "message"; } sau đó thay đổi đầu vào: <input type = 'text' onchange = 'myFunction ();'> </ input>
Keith

Câu trả lời:


367

Cập nhật (2017)

Các trình duyệt hiện đại hiện coi việc hiển thị một thông báo tùy chỉnh là một mối nguy hiểm bảo mật và do đó nó đã bị xóa khỏi tất cả chúng. Trình duyệt bây giờ chỉ hiển thị tin nhắn chung. Vì chúng ta không còn phải lo lắng về việc đặt tin nhắn, nên nó đơn giản như:

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

Đọc dưới đây để hỗ trợ trình duyệt cũ.

Cập nhật (2013)

Câu trả lời ban đầu phù hợp với IE6-8 và FX1-3.5 (đó là những gì chúng tôi đã nhắm mục tiêu trở lại vào năm 2009 khi nó được viết), nhưng hiện đã hết hạn và sẽ không hoạt động trong hầu hết các trình duyệt hiện tại - Tôi đã rời đi nó dưới đây để tham khảo.

Điều window.onbeforeunloadnày không được đối xử nhất quán bởi tất cả các trình duyệt. Nó phải là một tham chiếu hàm và không phải là một chuỗi (như câu trả lời ban đầu đã nêu) nhưng nó sẽ hoạt động trong các trình duyệt cũ hơn vì việc kiểm tra hầu hết trong số chúng dường như là có bất cứ thứ gì được gán cho onbeforeunload(bao gồm cả hàm trả về null).

Bạn đặt thành window.onbeforeunloadtham chiếu hàm, nhưng trong các trình duyệt cũ hơn, bạn phải đặt returnValuesự kiện thay vì chỉ trả về một chuỗi:

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

Bạn không thể confirmOnPageExitthực hiện kiểm tra và trả về null nếu bạn muốn người dùng tiếp tục mà không có tin nhắn. Bạn vẫn cần xóa sự kiện để bật và tắt sự kiện một cách đáng tin cậy:

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

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

Câu trả lời gốc (làm việc năm 2009)

Bật lên:

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

Để tắt nó:

window.onbeforeunload = null;

Hãy nhớ rằng đây không phải là một sự kiện bình thường - bạn không thể liên kết với nó theo cách tiêu chuẩn.

Để kiểm tra giá trị? Điều đó phụ thuộc vào khung xác nhận của bạn.

Trong jQuery, đây có thể là một cái gì đó giống như (ví dụ rất cơ bản):

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

4
Đó sẽ là một cái gì đó như: $ ('input: text'). Change (function () {window.onb Beforeunload = $ ('input: text [value! = ""]'). Length> 0? "Cảnh báo": null ;});
Keith

1
Đối với một kiểm tra đơn giản, hoặc bạn có thể thêm xác nhận phức tạp hơn vào mỗi thay đổi
Keith

1
Điều đáng chú ý là phương thức 'returnValue' là phương thức duy nhất được chỉ định trong tiêu chuẩn, do đó, không chỉ dành cho IE6-8, nó còn dành cho tất cả các trình duyệt tuân thủ tiêu chuẩn (trong trường hợp này không bao gồm Chrome, Safari và Opera).
rmcclellan

3
Để dừng cảnh báo về việc gửi biểu mẫu, tôi đã sử dụng $("#submit_button").click(function() { window.onbeforeunload = null; });. Ban đầu tôi đã sử dụng sự kiện onclick của nút, nhưng cũng như không đẹp, nó cũng không hoạt động với IE8.
Andy Beverley

1
@ AlikElzin-kilaka bạn không thể. Nếu bạn muốn thay đổi văn bản bật lên thì bạn cần tạo cửa sổ bật lên tùy chỉnh của riêng mình, nhưng điều đó không thể chặn window.onbeforeunloadsự kiện.
Keith

38

Các onbeforeunloadMicrosoft-ism là điều gần nhất chúng ta phải là một giải pháp tiêu chuẩn, nhưng lưu ý rằng trình duyệt hỗ trợ là không đồng đều; ví dụ, đối với Opera, nó chỉ hoạt động trong phiên bản 12 trở lên (vẫn ở phiên bản beta khi viết bài này).

Ngoài ra, để tương thích tối đa , bạn cần thực hiện nhiều hơn chỉ đơn giản là trả về một chuỗi, như được giải thích trên Mạng của Nhà phát triển Mozilla .

Ví dụ: Xác định hai chức năng sau để bật / tắt lời nhắc điều hướng (xem ví dụ MDN):

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

Sau đó, xác định một hình thức như thế này:

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

Bằng cách này, người dùng sẽ chỉ được cảnh báo về việc điều hướng đi nếu anh ta đã thay đổi vùng văn bản và sẽ không được nhắc khi anh ta thực sự gửi biểu mẫu.


1
Dựa trên trang web của Mozill, hầu hết các trình duyệt máy tính để bàn gần đây hiện hỗ trợ nó: developer.mozilla.org/en/DOM/window.onb
Beforeunload

Microsoft-ism là một thuật ngữ tuyệt vời.
Luke Taylor


18

Với JQuery , công cụ này khá dễ thực hiện. Vì bạn có thể liên kết với bộ.

Nó không đủ để thực hiện onb Beforeunload, bạn chỉ muốn kích hoạt điều hướng đi nếu ai đó bắt đầu chỉnh sửa nội dung.


2
Dường như không thể nhấn bài viết trên blog của @jonstjohn. Có lẽ anh ấy sẽ là một người bạn thân và chỉ cho chúng ta đi đúng hướng? : D
FLGMwt

14
=> 500 Lỗi nội bộ. Đó là lý do tại sao các liên kết không được chấp nhận trên SO. Downvote cho đến khi cố định.
Loïc

Trang web này không khả dụng
Mateusz

2
Mặc dù liên kết này có thể trả lời câu hỏi, tốt hơn là bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở nên không hợp lệ nếu trang được liên kết thay đổi.
Tây Ban Nha

2
Các liên kết ban đầu từ Jon St John đã bị hỏng, vì vậy tôi cập nhật nó vào Wayback Machine phiên bản của nó. Nội dung của liên kết có thể được tìm thấy được sao chép ở nhiều trang web khác, nhưng tôi đoán tốt hơn là nên "bảo tồn" trang mà Sam đã thêm
Alvaro Montoro

14

jquerys 'beforeunload' đã làm việc rất tốt cho tôi

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

Bind đã bị phản đối và một phiên bản mã mới hơn tương tự như vậy có thể được nhìn thấy trong câu trả lời này: stackoverflow.com/a/1889450/908677
Elijah Lofgren


11

Đây là một cách dễ dàng để trình bày thông báo nếu có bất kỳ dữ liệu nào được nhập vào biểu mẫu và không hiển thị thông báo nếu biểu mẫu được gửi:

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

Để mở rộng câu trả lời tuyệt vời của Keith :

Thông điệp cảnh báo tùy chỉnh

Để cho phép các thông báo cảnh báo tùy chỉnh, bạn có thể bọc nó trong một chức năng như thế này:

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

Sau đó, chỉ cần gọi chức năng đó với thông điệp tùy chỉnh của bạn:

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

Kích hoạt lại điều hướng

Để bật lại điều hướng, tất cả những gì bạn cần làm được đặt window.onbeforeunloadthành null. Nó đây, được bao bọc trong một chức năng nhỏ gọn có thể được gọi ở bất cứ đâu:

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

Sử dụng jQuery để liên kết điều này để tạo thành các phần tử

Nếu sử dụng jQuery, điều này có thể dễ dàng bị ràng buộc với tất cả các yếu tố của một hình thức như thế này:

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

Sau đó, để cho phép các hình thức được gửi:

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

Các hình thức sửa đổi động:

preventNavigation()enableNavigation()có thể bị ràng buộc với bất kỳ chức năng nào khác khi cần, chẳng hạn như tự động sửa đổi biểu mẫu hoặc nhấp vào nút gửi yêu cầu AJAX. Tôi đã làm điều này bằng cách thêm một yếu tố đầu vào ẩn vào biểu mẫu:

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

Sau đó, bất cứ khi nào tôi muốn ngăn người dùng điều hướng đi, tôi kích hoạt thay đổi trên đầu vào đó để đảm bảo rằng nó preventNavigation()được thực thi:

function somethingThatModifiesAFormDynamically() {

    // Do something that modifies a form

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

3

Ở đây thử nó hoạt động 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

Các tiêu chuẩn quốc gia mà khiến có thể được kiểm soát bằng cách hủy các beforeunload sự kiện hoặc thiết lập các giá trị trả về một giá trị null . Nó cũng nói rằng các tác giả nên sử dụng Event.preventDefault () thay vì returnValue và thông báo hiển thị cho người dùng không thể tùy chỉnh .

Kể từ 69.0.3497.92, Chrome chưa đạt tiêu chuẩn. Tuy nhiên, có một báo cáo lỗi được đệ trình và đang tiến hành đánh giá . Chrome yêu cầu returnValue phải được đặt bằng cách tham chiếu đến đối tượng sự kiện, không phải giá trị mà trình xử lý trả về.

Trách nhiệm của tác giả là theo dõi xem các thay đổi đã được thực hiện hay chưa; nó có thể được thực hiện với một biến hoặc bằng cách đảm bảo sự kiện chỉ được xử lý khi cần thiết.

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

Khi người dùng bắt đầu thay đổi biểu mẫu, cờ boolean sẽ được đặt. Nếu người dùng sau đó cố gắng điều hướng khỏi trang, bạn kiểm tra cờ đó trong sự kiện window.onunload . Nếu cờ được đặt, bạn hiển thị thông báo bằng cách trả lại dưới dạng chuỗi. Trả lại tin nhắn dưới dạng chuỗi sẽ bật lên hộp thoại xác nhận có chứa tin nhắn của bạn.

Nếu bạn đang sử dụng ajax để thực hiện các thay đổi, bạn có thể đặt cờ thành falsesau khi các thay đổi đã được cam kết (nghĩa là trong sự kiện thành công ajax).


1

Bạn có thể thêm một onchangesự kiện trên textarea (hoặc bất kỳ trường nào khác) đặt một biến trong JS. Khi người dùng cố gắng đóng trang (window.onunload), bạn kiểm tra giá trị của biến đó và hiển thị cảnh báo tương ứng.


1
Bạn không thể làm điều này - alertconfirmbị chặn trong window.onbeforeunloadwindow.onunload(ít nhất là trong phiên bản Chrome trên PC của tôi, nhưng có lẽ trong mọi trình duyệt đều hỗ trợ các trình xử lý đó).
Mark Amery

1

Dựa trên tất cả các câu trả lời trên chủ đề này, tôi đã viết đoạn mã sau và nó đã làm việc cho tôi.

Nếu bạn chỉ có một số thẻ đầu vào / textarea yêu cầu kiểm tra sự kiện onunload, bạn có thể gán các thuộc tính dữ liệu HTML5 như data-onunload="true"

ví dụ

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

và Javascript (jQuery) có thể trông như thế này:

$(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
Xem thêm "Vì một số lý do, các trình duyệt dựa trên Webkit không tuân theo thông số kỹ thuật cho hộp thoại" trong tài liệu trước khi tải của MDN .
Arjan

1

đây là html của tôi

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

Và đây là cách tôi đã làm một cái gì đó tương tự trong 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

Bạn có thể dễ dàng thực hiện bằng cách đặt ChangeFlag thành true, trên sự kiện onChange của TextArea . Sử dụng javascript để hiển thị hộp thoại xác nhận dựa trên giá trị ChangeFlag . Hủy biểu mẫu và điều hướng đến trang được yêu cầu nếu xác nhận trả về đúng, nếu không thì không có gì .



-1

Có một tham số "onunload" cho thẻ body bạn có thể gọi các hàm javascript từ đó. Nếu nó trả về false nó sẽ ngăn điều hướng đi.


13
May mắn thay, điều này không thực sự hoạt động. Nếu không, tôi ghét truy cập một trang có chứa <body onunload="return false;">.
Søren Løvborg
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.