Làm cách nào để ngăn cảnh báo JavaScript phát sáng khi rời khỏi trang?


12

Rất nhiều trang có thông báo khi bạn rời khỏi chúng: nếu bạn đóng tab, điều hướng đi mà không lưu, v.v., có nhiều lý do tại sao một trang web sẽ cảnh báo / chặn bạn rời khỏi cho đến khi bạn xác nhận cảnh báo, ví dụ: "Bạn có chắc chắn muốn điều hướng khỏi trang này? ".

Điều này thường được thực hiện với onbeforeunloadvà / hoặc onunloadxử lý.

Đây là một ví dụ.

Có cách nào để tôi có thể ngăn các cảnh báo / sự kiện chặn người dùng được tạo bởi các trình xử lý đó không? Về cơ bản, tôi muốn để JS được kích hoạt và đặc biệt không cho phép những thứ ngăn tôi rời khỏi trang mà không có thêm một lần nhấp nào xảy ra.

onbeforeunloadonunloadxử lý vẫn nên bắn; họ không nên được phép làm những việc chặn người dùng. Điều đó có nghĩa là không có cảnh báo và không có hoạt động nào mất hơn vài giây.

Tôi đã tìm thấy một vài plugin chỉnh sửa / greasemonkey vá javascript cho các trang cụ thể và chơi với mã của chúng một chút để thử và làm cho chúng có thể áp dụng phổ biến hơn. Tuy nhiên, tôi hy vọng tìm thấy một giải pháp hoạt động trên bất kỳ trang nào cố gắng chặn lối thoát của người dùng.


Bạn có thể đăng một URL mà làm điều đó?
golimar

Đã chỉnh sửa, thêm ví dụ. Ngoài ra, tôi hiểu lý do tại sao hành vi này thường được mong muốn và rằng nó là cần thiết để ngăn ngừa mất dữ liệu do tai nạn trong nhiều trường hợp. Tôi vẫn muốn biết làm thế nào để ghi đè / vô hiệu hóa nó.
Zac B

Lưu ý: tất cả các câu trả lời hiện tại (có sửa đổi onbeforeunload) sẽ chỉ hoạt động cho các trang sử dụng onbeforeunload, không dành cho các trang sử dụng một trong các phương pháp khác để đính kèm các sự kiện.
Synetech

Câu trả lời:


7

Chà, điều đơn giản nhất để làm chỉ đơn giản là ghi đè trực tiếp tập lệnh trang và gán lại sự kiện null.

window.onbeforeunload = null;

Điều này sẽ hoạt động ở bất cứ đâu, trừ khi chúng thực sự độc hại và tiếp tục tự gán lại. Trong trường hợp như vậy, một vòng lặp để tiếp tục cài đặt nullcó thể sẽ hoạt động.

while(true) {
    if (window.onbeforeunload != null) {
        window.onbeforeunload = null;
    }
}

Bây giờ, được cảnh báo, một số trang sử dụng này cho tốt. Truy cập trang tải lên YouTube: Nếu bạn điều hướng trong khi tải lên, bạn có thể đã mất hàng giờ tiến bộ! Hoặc có lẽ một mẫu web bạn đang điền, mà bạn có thể không muốn điền lại, hoặc một tin nhắn (diễn đàn / email) mà bạn có thể không muốn gõ lại. Với tính năng này, bạn được bảo vệ.

Một vấn đề khác là bất kỳ trang nào sử dụng điều này cho một số mục đích phụ, như lưu dữ liệu bằng AJAX. Họ có thể sử dụng sự kiện này để kích hoạt hành động lưu và hy vọng rằng người dùng sẽ mất nhiều thời gian để nhấp vào nút để yêu cầu được thực hiện. Một lần nữa, điều này thường được thực hiện để cứu bạn khỏi chính bạn.

Nhưng, rõ ràng, tất cả chúng ta đều biết nhiều trang sử dụng điều này cho bệnh. Vì vậy, nếu bạn biết bất kỳ trang nào bạn muốn nó hoạt động, bạn luôn có thể có một hệ thống danh sách trắng. Thực sự không có cách nào để chặn hành động này, mà không chặn hoàn toàn window.onbeforeunload, và bất kỳ hành động nào (có thể tốt) mà nó có thể thực hiện.

Không có cách nào (không có kiến ​​thức trước về mã trang nhất định) để giữ các hành động tốt trong khi dừng hộp bật lên. Hộp này không phải là một alert(). Hộp được tạo bởi trình duyệt, như hành vi dự định của onbeforeunload. Người ta tạo ra nó bằng cách thực hiện bất kỳ chức năng nào họ gán để window.onbeforeunloadtrả về một chuỗi. Chuỗi đó sẽ được in trong cửa sổ bật lên.

window.onbeforeunload = function() {
    //Whatever
    return "WARNING! You have unsaved changes that may be lost!";
}

Do đó, bạn sẽ không thể chặn cửa sổ bật lên mà không xóa chức năng.

Ngoài ra, nếu bạn đã tìm ra cách, bất kỳ AJAX nào cũng sẽ thất bại. Cửa sổ bật lên cho yêu cầu thời gian để đi qua, nếu không có nó, dữ liệu có thể bị mất.

Đối với onunload, nó không thể chặn bạn với điều này. Vì nó kích hoạt sau khi tải trang. Nhưng để an toàn, bạn luôn có thể làm window.onunload = null;và cần được chăm sóc.


Đó là loại công việc, nhưng nếu người onbeforeunloadxử lý đã làm một cái gì đó quan trọng khác? Ví dụ: nếu yêu cầu AJAX ngắn gọn hoặc cam kết điều gì với bộ lưu trữ HTML5 cục bộ thì sao? Có cách nào để ngăn onbeforeunloadngười xử lý thực hiện các cuộc gọi nhất định (nghĩa là alert()) hoặc chạy lâu hơn một khoảng thời gian nhất định không? Đó là lý do tại sao tôi hỏi về một phần mở rộng thay vì chỉ là một tập lệnh kiểu greasemonkey: có vẻ như, để làm điều này đúng, sẽ phải có một cái gì đó thay đổi ở cấp độ công cụ JavaScript.
Zac B

1
Tôi đã thêm một số thông tin. Theo như thực sự sửa lỗi này ở cấp độ thấp hơn, tiện ích mở rộng không thực sự là cấp độ thấp hơn. Chúng có quyền cao hơn và một số API đặc biệt, nhưng chúng không có khả năng thay đổi các chức năng cốt lõi của trình duyệt. Tôi không chắc cách cắm FF có thể đi sâu đến đâu, tôi không có kinh nghiệm trong lĩnh vực đó. Rõ ràng, là nguồn mở, bạn có thể thực hiện những thay đổi đó. Nhưng đó là một chút xa để sửa chữa một cửa sổ bật lên.
zeel

Không làm việc cho tôi :(
Phúc Nguyên

0
    // ==/UserScript==

var th = document.getElementsByTagName('body')[0];
var s = document.createElement('script');
s.setAttribute('type','text/javascript');
s.innerHTML = "window.onbeforeunload = function() {}";
th.appendChild(s);

1
Tại sao bạn lại tạo ra một kịch bản như thế này?
Brad

3
@anywho. Nó có thể hữu ích nếu bạn cố gắng giải thích kịch bản của mình để giúp người khác biết họ đang làm gì. Điều này cũng sẽ cho phép bạn trả lời được nhiều người sử dụng vì một đoạn kịch bản cụ thể có thể được thay đổi theo cách cải thiện tập lệnh hoặc một đoạn có thể được sử dụng trong một tập lệnh hoàn toàn khác. Nó cũng là một ý tưởng tốt để giải thích bạn trả lời dù sao để giúp mọi người biết làm thế nào nó áp dụng cho câu hỏi của họ. Cảm ơn bạn đã gửi câu trả lời của bạn mặc dù.
David

0

Có một công cụ tuyệt vời có thể xử lý bất kỳ cửa sổ bật lên gây phiền nhiễu nào trên hệ thống Windows - ClickPack . Bạn có thể tải nó từ đây . Tôi đã kiểm tra nó và nó hoạt động với cảnh báo "Thay đổi bạn đã thực hiện có thể không được lưu" cho trang SharePoint.

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.