Câu trả lời ngắn gọn:
Bạn có thể làm điều này bằng cách xử lý beforeunload
sự kiện và trả về một chuỗi không null :
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.';
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});
Vấn đề với cách tiếp cận này là việc gửi biểu mẫu cũng đang kích hoạt sự kiện dỡ tải . Điều này được khắc phục dễ dàng bằng cách thêm cờ bạn đang gửi biểu mẫu:
var formSubmitting = false;
var setFormSubmitting = function() { formSubmitting = true; };
window.onload = function() {
window.addEventListener("beforeunload", function (e) {
if (formSubmitting) {
return undefined;
}
var confirmationMessage = 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.';
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});
};
Sau đó gọi setter khi gửi:
<form method="post" onsubmit="setFormSubmitting()">
<input type="submit" />
</form>
Nhưng hãy đọc tiếp ...
Câu trả lời dài, đúng:
Bạn cũng không muốn hiển thị thông báo này khi người dùng không thay đổi bất cứ điều gì trên biểu mẫu của bạn . Một giải pháp là sử dụng beforeunload
sự kiện kết hợp với cờ "bẩn", chỉ kích hoạt lời nhắc nếu nó thực sự có liên quan.
var isDirty = function() { return false; }
window.onload = function() {
window.addEventListener("beforeunload", function (e) {
if (formSubmitting || !isDirty()) {
return undefined;
}
var confirmationMessage = 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.';
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});
};
Bây giờ để thực hiện isDirty
phương pháp, có nhiều cách tiếp cận khác nhau.
Bạn có thể sử dụng jQuery và hình thành tuần tự hóa , nhưng cách tiếp cận này có một số sai sót. Trước tiên, bạn phải thay đổi mã để hoạt động trên bất kỳ hình thức nào ( $("form").each()
sẽ làm), nhưng vấn đề lớn nhất là jQuery serialize()
sẽ chỉ hoạt động trên các phần tử có tên, không bị vô hiệu hóa, do đó, việc thay đổi bất kỳ phần tử bị vô hiệu hóa hoặc không tên nào sẽ không kích hoạt cờ bẩn. Có cách giải quyết cho vấn đề đó , như làm cho các điều khiển chỉ đọc thay vì bật, tuần tự hóa và sau đó vô hiệu hóa lại các điều khiển.
Vì vậy, các sự kiện dường như con đường để đi. Bạn có thể thử nghe nhấn phím . Sự kiện này có một vài vấn đề:
- Không kích hoạt các hộp kiểm, nút radio hoặc các yếu tố khác đang được thay đổi thông qua đầu vào chuột.
- Sẽ kích hoạt cho các phím nhấn không liên quan như Ctrlphím.
- Không kích hoạt các giá trị được đặt thông qua mã JavaScript.
- Không kích hoạt cắt hoặc dán văn bản thông qua các menu ngữ cảnh.
- Không hoạt động đối với các đầu vào ảo như bộ tạo ngày hoặc hộp làm đẹp hộp kiểm / radiobutton để lưu giá trị của chúng trong một đầu vào ẩn thông qua JavaScript.
Sự change
kiện cũng không kích hoạt các giá trị được đặt từ mã JavaScript , do đó cũng sẽ không hoạt động đối với các đầu vào ảo.
Liên kết input
sự kiện với tất cả input
(và textarea
s và select
s) trên trang của bạn sẽ không hoạt động trên các trình duyệt cũ hơn và, giống như tất cả các giải pháp xử lý sự kiện được đề cập ở trên, không hỗ trợ hoàn tác. Khi người dùng thay đổi hộp văn bản và sau đó hoàn tác, hoặc kiểm tra và bỏ chọn hộp kiểm, biểu mẫu vẫn bị coi là bẩn.
Và khi bạn muốn thực hiện nhiều hành vi hơn, như bỏ qua các yếu tố nhất định, bạn sẽ còn nhiều việc phải làm.
Đừng phát minh lại bánh xe:
Vì vậy, trước khi bạn nghĩ về việc thực hiện các giải pháp đó và tất cả các giải pháp cần thiết, hãy nhận ra rằng bạn đang phát minh lại bánh xe và bạn có xu hướng gặp phải các vấn đề mà người khác đã giải quyết cho bạn.
Nếu ứng dụng của bạn đã sử dụng jQuery, bạn cũng có thể sử dụng mã được kiểm tra, bảo trì thay vì tự cuộn và sử dụng thư viện phần thứ ba cho tất cả những điều này. Bạn có chắc không? Plugin hoạt động tuyệt vời, xem trang demo của họ . Nó đơn giản như thế này:
<script src="jquery.are-you-sure.js"></script>
<script>
$(function() {
$('#myForm').areYouSure(
{
message: 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.'
}
);
});
</script>
Tin nhắn tùy chỉnh không được hỗ trợ ở mọi nơi
Xin lưu ý rằng Firefox 4 không hỗ trợ các thông báo tùy chỉnh trong hộp thoại này. Kể từ tháng 4 năm 2016, Chrome 51 đang được triển khai trong đó các thông báo tùy chỉnh cũng đang bị xóa .
Một số lựa chọn thay thế tồn tại ở nơi khác trên trang web này, nhưng tôi nghĩ một hộp thoại như thế này là đủ rõ ràng:
Bạn có muốn rời khỏi trang web này?
Những thay đổi bạn thực hiện có thể không được lưu.
Leave Stay