2012-08-17 29 views
5

Tôi cố gắng để ghi đè lên các chức năng thành công vào sự kiện ajaxsend nhưng nó không làm việc đây là mã:làm thế nào để ghi đè lên các chức năng thành công qua sự kiện JQuery ajaxSend

$(document).ajaxSend(function(event,xhr,options){ 
     console.log('ajaxSend'); 
     var tempSuccess = options.success; 
     options.success = function(data, textStatus, jqXHR){ 
      console.log('start'); 
      tempSuccess(data, textStatus, jqXHR); 
      console.log('end'); 
     }; xhr.success = options.success;}); 

khi AJAX Tôi thấy 'ajax' trong giao diện điều khiển, nhưng sau khi thành công, tôi không thể thấy bắt đầu và kết thúc gỡ lỗi msges ..

Tôi làm gì sai?

+0

liên quan: http://stackoverflow.com/questions/293668/jquery-ajax-prevent-callback-from-running – pimvdb

+0

cảm ơn, nhưng nó không trả lời câu hỏi của tôi, ajaxComplete cháy sau khi trình duyệt nhận được phản hồi HTTP, tôi đang hỏi về ajaxSend sẽ kích hoạt trước yêu cầu HTTP – ciochPep

+0

Bạn nói đúng. Tôi đã chỉ vào câu trả lời mà nói rằng callbacks là ràng buộc để được chạy và rằng bạn không thể ngăn chặn điều đó. Cấp nó không chính xác câu hỏi của bạn; Tôi cũng thích một giải pháp. – pimvdb

Trả lời

-1

Bạn có thể sử dụng đóng cửa để thực hiện những gì bạn cần:

function closure(handler) { 
    return function(ev, xhr, options) { 
     console.log("start"); 
     handler(ev, xhr, options); 
     console.log("stop"); 
    } 
} 

$(document).ajaxSend(closure(function(ev, xhr, options) { 
    console.log("hello"); 
})); 
+0

Điều này không hoạt động như dự định vì nó không ghi đè lên chức năng gọi lại thành công! Chức năng "đóng" không có hiệu lực; 'console.log ('start/end')' cũng có thể được chuyển vào 'ajaxSend' ở đây.Về cơ bản, "giải pháp" của bạn chỉ là mã obfuscation ... – Aletheios

+0

Rõ ràng là tôi hiểu sai ý định của tác giả, xin lỗi vì điều đó. Đối với $ .get và $ .load, chúng sử dụng $ .ajax nội bộ như có thể thấy ở đây: https://github.com/jquery/jquery/blob/master/src/ajax.js – prot

6

gì bạn đang cố gắng để hoàn thành không thể được thực hiện với ajaxSend. Vấn đề là ajaxSend dường như hoạt động với một bản sao của các đối tượng xhroptions ban đầu, do đó các sửa đổi sẽ không có hiệu lực. Bạn có thể dễ dàng kiểm tra điều này với đoạn mã sau:

$(document).ajaxSend(function(event, xhr, options){ 
    delete options.success; 
    console.log(options.success); // undefined 
}); 
$.ajax({ 
    url: "test.html", 
    success: function() { console.log("this will be printed nevertheless"); } 
}); 


Vì vậy, bạn không thể sử dụng ajaxSend ghi đè lên callbacks thành công. Thay vào đó, bạn sẽ phải "hack" chức năng AJAX của jQuery:

// closure to prevent global access to this stuff 
(function(){ 
    // creates a new callback function that also executes the original callback 
    var SuccessCallback = function(origCallback){ 
     return function(data, textStatus, jqXHR) { 
      console.log("start"); 
      if (typeof origCallback === "function") { 
       origCallback(data, textStatus, jqXHR); 
      } 
      console.log("end"); 
     }; 
    }; 

    // store the original AJAX function in a variable before overwriting it 
    var jqAjax = $.ajax; 
    $.ajax = function(settings){ 
     // override the callback function, then execute the original AJAX function 
     settings.success = new SuccessCallback(settings.success); 
     jqAjax(settings); 
    }; 
})(); 

Bây giờ bạn chỉ có thể sử dụng $.ajax như thường lệ:

$.ajax({ 
    url: "test.html", 
    success: function() { 
     console.log("will be printed between 'start' and 'end'"); 
    } 
}); 

Theo như tôi biết, bất kỳ chức năng AJAX của jQuery (ví dụ như $.get() hoặc .load()) sử dụng nội bộ $.ajax, vì vậy điều này sẽ hoạt động với mọi yêu cầu AJAX được thực hiện thông qua jQuery (tôi chưa thử nghiệm điều này mặc dù ...).



Something như thế cũng sẽ làm việc với JavaScript "tinh khiết" bằng cách hack các XMLHttpRequest.prototype. Lưu ý rằng những điều sau đây sẽ không hoạt động trong IE, sử dụng ActiveXObject thay vì XMLHttpRequest.

(function(){ 
    // overwrite the "send" method, but keep the original implementation in a variable 
    var origSend = XMLHttpRequest.prototype.send; 
    XMLHttpRequest.prototype.send = function(data){ 
     // check if onreadystatechange property is set (which is used for callbacks) 
     if (typeof this.onreadystatechange === "function") { 
      // overwrite callback function 
      var origOnreadystatechange = this.onreadystatechange; 
      this.onreadystatechange = function(){ 
       if (this.readyState === 4) { 
        console.log("start"); 
       } 
       origOnreadystatechange(); 
       if (this.readyState === 4) { 
        console.log("end"); 
       } 
      }; 
     } 
     // execute the original "send" method 
     origSend.call(this, data); 
    }; 
})(); 

sử dụng (giống như một XMLHttpRequest bình thường):

var xhr = new XMLHttpRequest(); 
xhr.open("POST", "test.html", true); 
xhr.onreadystatechange = function(){ 
    if (xhr.readyState === 4) { 
     console.log("will be printed between 'start' and 'end'"); 
    } 
}; 
xhr.send(); 
+0

bạn sẽ làm gì cho các yêu cầu không phải jquery ajax? – ciochPep

+0

Xem ở trên, tôi đã chỉnh sửa câu trả lời của tôi ... Nhưng tôi đoán có nhiều hơn cho nó, vì vậy có lẽ bạn nên mở một câu hỏi riêng cho điều đó. – Aletheios

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