Ngăn chặn một trang web điều hướng đi bằng JavaScript


129

Làm cách nào để ngăn chặn một trang web điều hướng đi bằng JavaScript?


Điều gì làm cho trang này điều hướng đi?
Niyaz

9
Theo câu hỏi, JavaScript làm cho nó điều hướng đi ...
Shog9


@ Shog9 nó có thể đóng tab làm cho nó điều hướng đi. Ngón trỏ của tôi đã tha ...
Bob Stein

Câu trả lời:


159

Việc sử dụng onunloadcho phép bạn hiển thị tin nhắn, nhưng sẽ không làm gián đoạn điều hướng (vì quá muộn). Tuy nhiên, việc sử dụng onbeforeunloadsẽ làm gián đoạn điều hướng:

window.onbeforeunload = function() {
  return "";
}

Lưu ý: Một chuỗi trống được trả về vì các trình duyệt mới hơn cung cấp một thông báo như "Mọi thay đổi chưa được lưu sẽ bị mất" không thể bị ghi đè.

Trong các trình duyệt cũ hơn, bạn có thể chỉ định thông báo sẽ hiển thị trong lời nhắc:

window.onbeforeunload = function() {
  return "Are you sure you want to navigate away?";
}

11
Trình duyệt sẽ hiển thị một dấu nhắc thích hợp. Đơn giản chỉ cần sử dụngwindow.onbeforeunload = function() { return ""; }
KIM Taegyoon

Nhưng điều đó là không đủ. Điều gì về các điều khiển bên trong biểu mẫu? Họ cũng kích hoạt điều này.
Fandango68

1
Các trình duyệt hiện đại không cho phép bạn hiển thị một thông báo tùy chỉnh trong lời nhắc, vì điều này đã bị lạm dụng bởi những kẻ lừa đảo và những thứ tương tự.
Flimm

Cảm ơn @Flimm, tôi đã cập nhật câu trả lời để nó chính xác cho các trình duyệt hiện tại.
Jimmie R. Houts

@FlimmI muốn cập nhật trạng thái trực tuyến của người dùng khi người dùng trực tuyến đóng tab trình duyệt hoặc trình duyệt. Tôi đã sử dụng mã trong giải pháp nhưng nó không hoạt động. Có giải pháp nào cho việc này không?
Nasimba

23

Không giống như các phương pháp khác được trình bày ở đây, đoạn mã này sẽ không khiến trình duyệt hiển thị cảnh báo hỏi người dùng nếu anh ta muốn rời đi; thay vào đó, nó khai thác tính chất sự kiện của DOM để chuyển hướng trở lại trang hiện tại (và do đó hủy điều hướng) trước khi trình duyệt có cơ hội dỡ nó khỏi bộ nhớ.

Vì nó hoạt động bằng cách điều hướng ngắn mạch trực tiếp, nên nó không thể được sử dụng để ngăn trang bị đóng; tuy nhiên, nó có thể được sử dụng để vô hiệu hóa khung hình.

(function () {
    var location = window.document.location;

    var preventNavigation = function () {
        var originalHashValue = location.hash;

        window.setTimeout(function () {
            location.hash = 'preventNavigation' + ~~ (9999 * Math.random());
            location.hash = originalHashValue;
        }, 0);
    };

    window.addEventListener('beforeunload', preventNavigation, false);
    window.addEventListener('unload', preventNavigation, false);
})();

Tuyên bố từ chối trách nhiệm: Bạn không bao giờ nên làm điều này. Nếu một trang có mã phá vỡ khung trên đó, vui lòng tôn trọng mong muốn của tác giả.


Làm thế nào hiển thị phương thức nếu người dùng muốn đóng trình duyệt (bấm vào đóng)? nó thật sao

15

Tôi đã kết thúc với phiên bản hơi khác này:

var dirty = false;
window.onbeforeunload = function() {
    return dirty ? "If you leave this page you will lose your unsaved changes." : null;
}

Ở những nơi khác, tôi đặt cờ bẩn thành đúng khi biểu mẫu bị bẩn (hoặc nếu không tôi muốn ngăn điều hướng đi). Điều này cho phép tôi dễ dàng kiểm soát xem người dùng có nhận được lời nhắc Xác nhận điều hướng hay không.

Với văn bản trong câu trả lời đã chọn, bạn sẽ thấy các lời nhắc thừa:

nhập mô tả hình ảnh ở đây


3
Trong IE nếu bẩn là sai, một chuỗi 'null' sẽ được hiển thị. Chỉ cần bọc nó trong một câu lệnh if. Xem: stackoverflow.com/questions/11793996/ Mạnh
Jacob van Lingen

Đồng ý @JacobvanLingen, đây sẽ là câu trả lời tốt nhất ở đây và về ba câu hỏi khác nếu nó kết thúc thay vì null. (1) đó là điều kiện (2) nó đề cập đến "bẩn" lý do hợp pháp phổ biến nhất để cản trở việc điều hướng và (3) nó có ảnh chụp màn hình. undefined
Bob Stein

Điều này sẽ hoạt động trên tất cả các trình duyệt nếu nó kết thúc với không xác định chứ không phải null?
Nguy hiểm

9

Tương đương theo cách hiện đại hơn và tương thích với trình duyệt, sử dụng API addEventListener hiện đại.

window.addEventListener('beforeunload', (event) => {
  // Cancel the event as stated by the standard.
  event.preventDefault();
  // Chrome requires returnValue to be set.
  event.returnValue = '';
});

Nguồn: https://developer.mozilla.org/en-US/docs/Web/Events/b Beforeunload


1
Nhớ viết hoa đúngevent.returnValue
Flimm

7

Trong ví dụ của Ayman bằng cách trả về false, bạn sẽ ngăn cửa sổ / tab trình duyệt đóng lại.

window.onunload = function () {
  alert('You are trying to leave.');
  return false;
}

2
Trừ khi trình duyệt là Opera, bỏ qua sự kiện onunload nếu tab / cửa sổ / chương trình đang bị đóng.
Powerlord

5

Tương đương với câu trả lời được chấp nhận trong jQuery 1.11:

$(window).on("beforeunload", function () {
    return "Please don't leave me!";
});

Ví dụ về JSFiddle

Câu trả lời của altCognito đã sử dụng unloadsự kiện xảy ra quá muộn để JavaScript hủy bỏ điều hướng.


3

Sử dụng onunload .

Đối với jQuery, tôi nghĩ rằng điều này hoạt động như vậy:

$(window).unload(function() { 
  alert("Unloading"); 
  return falseIfYouWantToButBeCareful();
});

Trả lại sai sẽ không hủy bỏ tải một cách đáng tiếc - unloadsự kiện sẽ kích hoạt khi người dùng rời khỏi trang, không giống như beforeunloadviệc bắn trước đó (và có thể bị hủy)
Jimbo

@altCognito: Bạn đã cho tôi ý tưởng hay với false IfYouWantToButBeCareful () Bây giờ tôi có thể tránh cửa sổ bật lên mặc định được cung cấp bởi IE hoặc FF. Nhưng đối với chrome thì nó không hoạt động. Nhìn vào nó.
dùng367134

3

Thông báo lỗi được đề xuất đó có thể nhân đôi thông báo lỗi mà trình duyệt đã hiển thị. Trong chrome, 2 thông báo lỗi tương tự được hiển thị lần lượt trong cùng một cửa sổ.

Trong chrome, văn bản được hiển thị sau thông báo tùy chỉnh là: "Bạn có chắc chắn muốn rời khỏi trang này?". Trong firefox, nó hoàn toàn không hiển thị thông báo lỗi tùy chỉnh của chúng tôi (nhưng vẫn hiển thị hộp thoại).

Một thông báo lỗi thích hợp hơn có thể là:

window.onbeforeunload = function() {
    return "If you leave this page, you will lose any unsaved changes.";
}

Hoặc kiểu stackoverflow: "Bạn đã bắt đầu viết hoặc chỉnh sửa bài đăng."


2

Nếu bạn đang bắt nút quay lại / chuyển tiếp của trình duyệt và không muốn điều hướng đi, bạn có thể sử dụng:

window.addEventListener('popstate', function() {
    if (window.location.origin !== 'http://example.com') {
        // Do something if not your domain
    } else if (window.location.href === 'http://example.com/sign-in/step-1') {
        window.history.go(2); // Skip the already-signed-in pages if the forward button was clicked
    } else if (window.location.href === 'http://example.com/sign-in/step-2') {
        window.history.go(-2); // Skip the already-signed-in pages if the back button was clicked
    } else {
        // Let it do its thing
    }
});

Mặt khác, bạn có thể sử dụng sự kiện tải trước, nhưng thông báo có thể hoặc không hoạt động trên nhiều trình duyệt và yêu cầu trả lại một cái gì đó buộc lời nhắc tích hợp.

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.