2009-02-11 35 views
21

Tôi có điều khiển lưới dựa trên AJAX.Tôi có thể ngăn chặn window.onbeforeunload không được gọi khi thực hiện cuộc gọi AJAX

Chúng tôi móc vào sự kiện window.onbeforeunload để kiểm tra xem chúng có dữ liệu chưa được lưu hay không và nếu hiển thị chúng với thông báo "Bạn có chắc chắn muốn điều hướng ... bạn có dữ liệu chưa được lưu ...".

Tất cả điều này đều tốt.

Nhưng cuộc gọi AJAX cũng kích hoạt window.onbeforeunload và vì vậy nếu lưới có dữ liệu chưa được lưu và chúng tôi thực hiện cuộc gọi AJAX (chẳng hạn như xóa một hàng trong một lưới khác), người dùng nhận được thông báo "Bạn có chắc chắn muốn điều hướng không ... bạn có dữ liệu chưa được lưu ... "tin nhắn không tốt.

Có thể chặn sự kiện onbeforeunload cho cuộc gọi AJAX không? Hoặc có thể phát hiện rằng một cuộc gọi cuộc gọi AJAX? Nếu không chúng tôi sẽ phải hack!

Cảm ơn

Trả lời

2

Điều này thực sự lạ, bạn có chắc chắn cuộc gọi Ajax của bạn không tải liên kết mới không?

Hãy chắc chắn bạn đọc đặc điểm kỹ thuật có liên quan này: onbeforeunload spec

Xem nếu cuộc gọi Ajax có thể gây ra bất kỳ hành động được liệt kê trong Để gọi bảng.

+0

Cảm ơn. Đọc spec và nó tham khảo "document.write" trong "To invoke". Điều đó chắc chắn xảy ra một bó với thư viện lưới chúng tôi đang sử dụng. – Paul

0

Nếu bạn đang nói về postbacks một phần ASP.NET AJAX, sau đó tôi gặp phải hành vi này ngày hôm nay quá, làm điều tương tự. (Nếu bạn không, bỏ qua bài viết của tôi hoàn toàn.)

Theo kinh nghiệm của tôi cho đến nay, nó có vẻ như nếu postback một phần của bạn được kích hoạt bởi một đầu vào, nó sẽ không bắn onbeforeunload trong một postback một phần , nhưng nếu đăng lại một phần được kích hoạt bởi một liên kết siêu liên kết, nó sẽ hiển thị. Có vẻ như trình duyệt giả sử bạn đang điều hướng đi nếu bạn nhấp vào bất kỳ thứ gì trong thẻ neo (chỉ được thử nghiệm trong IE và FireFox nhưng vâng).

Trang có trường ẩn nhất định đã là thứ tôi đang sử dụng để xác định phía máy khách hay không khi hiển thị cảnh báo điều hướng, vì vậy tôi có thể khắc phục điều này rất đơn giản bằng cách thêm kiểm tra giá trị của trường ẩn đối với điều kiện if onbeforeunload của tôi và hooking vào trình xử lý BeginRequest và EndRequest của PageRequestManager để đặt giá trị. Điều đó có hiệu quả vô hiệu hóa cảnh báo trong một phần postbacks. Bạn có thể thêm logic phức tạp hơn ở đây nếu có nhiều thứ cụ thể hơn mà bạn muốn kiểm tra.

Đây là mẫu mã thực sự được đơn giản hóa. (. Xin lỗi nếu tôi pared và kiểm duyệt tới điểm mà nó không hoạt động nhưng nó sẽ cho bạn một ý tưởng)

window.onbeforeunload = checkNavigateAway; 

Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(onBeginRequest); 
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(onEndRequest); 

function onBeginRequest(sender, args) { 
    var navigateAwayFlag = $("input[id*='navigateAwayValue']"); 
    if (navigateAwayFlag.length > 0) { 
     navigateAwayFlag[0].value = "false"; 
    } 
} 

function onEndRequest(sender, args) { 
    var navigateAwayFlag = $("input[id*='navigateAwayValue']"); 
    if (navigateAwayFlag.length > 0) { 
     navigateAwayFlag[0].value = "true"; 
    } 
} 

function checkNavigateAway() { 
    var navigateAwayFlag = $("input[id*='navigateAwayValue']"); 
    if (navigateAwayFlag.length > 0 && navigateAwayFlag[0].value == "true") 
    { 
     return "Warning Text"; 
    } 
} 

Sửa: Tin xấu. Ở trên dường như không hoạt động trong IE6. Dường như nó kích hoạt các sự kiện theo thứ tự khác với Firefox, do đó onbeforeunload phát sinh trước AJAX beginRequest ... Có thể phải tìm cách thay đổi giá trị của cờ thông qua nhấp chuột siêu liên kết trước khi onbeforeunload kích hoạt.

5

tôi đã làm một cái gì đó như thế này:

bên trong thẻ cơ thể:

var allowConfirm = true; 

    window.onbeforeunload = confirmExit; 
    function confirmExit() 
    { 
    if(allowConfirm) 
     return "Are you sure you want to navigate away from this page?"; 
    else 
     allowConfirm = true; 
    } 

Khi tôi Logout, tôi gọi kịch bản này:

allowConfirm = false; return window.location.href;

+0

Điều này làm việc cho tôi. Các liên kết Lưu và Hủy của tôi thực hiện các cuộc gọi đến trình xử lý ashx và điều đó buộc phải tải xuống và tôi không muốn cửa sổ bật lên xuất hiện khi lưu hoặc hủy trang. – Ray

30

Nếu bạn muốn kích hoạt postback của bạn bằng một siêu liên kết, có một cách giải quyết đơn giản: Thay vì

<a href="javascript:submitFunction();">Submit</a>

hoặc

<a href="javascript:;" onclick="submitFunction();">Submit</a>

chỉ cần sử dụng mã này:

<a href="#" onclick="submitFunction();">Submit</a>

Dường như IE kích hoạt sự kiện onbeforeunload nếu nội dung của thuộc tính href của siêu liên kết không phải là trang hiện tại (mà ký tự sắc nét chỉ ra).

+0

Điều này ngăn chặn sự kiện onbeforeunload được kích hoạt. – dhinesh

+4

Nếu bạn thực hiện href "###" thay vì "#", một lợi ích bổ sung là trình duyệt sẽ không chuyển sang đầu trang. –

+1

Đây là một giải pháp tuyệt vời, tuy nhiên tôi đang sử dụng asp: linkButtons trong bộ lặp để tôi không có được sự lựa chọn về cách định dạng href. Chúng được cấu trúc như sau ... bất kỳ ý tưởng cho cấu hình này? xóa Cảm ơn – hardba11

0

này thực sự hoạt động:

OnClientClick="eval(this.href);return false" 
2

Trong trường hợp của IE6 hoặc href bạn có thể treo các chức năng postback. ví dụ: nếu chức năng postback là WebForm_DoPostBackWithOptions và sử dụng jquery, thêm mã này dưới đây để mã trên

var DoPostBackWithOptionsHook = null; 

$(document).ready(function(){ 
    DoPostBackWithOptionsHook = WebForm_DoPostBackWithOptions; 
    WebForm_DoPostBackWithOptions = WebForm_DoPostBackWithOptionsHook; 
} 

function WebForm_DoPostBackWithOptionsHook(options) { 
    var navigateAwayFlag = $("input[id*='navigateAwayValue']"); 
     if (navigateAwayFlag.length > 0) { 
      navigateAwayFlag[0].value = "false"; } 

    return DoPostBackWithOptionsHook(options) 
} 
0

Một workaround cho vấn đề này là để gọi submitFunction() trên nhấp chuột trường hợp thẻ siêu liên kết sử dụng jquery và loại bỏ các href thuộc tính từ siêu kết nối.

0

điều đó là không thể, không có cách nào để tìm hiểu xem nút làm mới của trình duyệt đã được nhấn hay chưa.

0

Không sử dụng AJAX, nhưng vẫn muốn ngăn trang thoát với các thay đổi chưa được lưu. Tôi đã thử hầu hết các đề xuất trước, kể cả navigationAway. Không có ai trong số họ làm việc với IE 8. NavigateAway luôn trả về độ dài 0.

Tôi đã tìm thấy một blog về giải pháp sử dụng lớp như ID trong thẻ và sau đó đặt Boolean dựa trên đó. Tôi đã thử điều đó, nhưng nó không hoạt động vì .NET khi nó xuất ra HTML được gói thẻ đầu vào trong một thẻ span với lớp được khai báo trong nó. Giải pháp cuối cùng của tôi là đặt từ Bỏ qua trong tên ID của thẻ. Ngoài ra, để ngăn chặn onbeforeunload được gọi trước khi nhấp chuột bị mắc kẹt bởi mã đặt Boolean, người ta phải sử dụng, chẳng hạn như asp: Button hoặc asp: Input. Cuối cùng, lực asp (của VS IDE không) tên bắt đầu là kiểu điều khiển; ID = "Button_Save". Sử dụng thẻ asp: cũng ngăn không cho onbeforeunload được gọi hai lần.

<script type="text/javascript" language="javascript"> 
var stuffchanged = false 
var ignorenavigate = false 

    $(document).ready(function() { 


    //Detect whether the event source has "nonavigate" class specified 
    $("a,input,img,checkbox,button").click(function() { 
     var str = $(this).attr("ID"); 
     ignorenavigate = str.search("Ignore") > 0; 
    }); 

}); 

window.onbeforeunload = confirmExit; 
function confirmExit() { 
    if (stuffchanged && !ignorenavigate) { 
     return "You have attempted to leave this page with unsaved changes. If you have made any changes to the fields without " + 
    "clicking the Save button, your changes will be lost. Are you sure you want to exit this page?"; 
    } 

} 

    function textchanged() { 
    stuffchanged = true; 
    } 

Các vấn đề liên quan