2010-11-20 35 views
5

Tôi đang cố gắng tìm cách tải xuống nếu trình duyệt hiện đang bận từ JavaScript. Tôi đang xem xét việc tạo một phần mở rộng của Firefox để chèn một giá trị Boolean hoặc một cái gì đó nếu trang hiện tại đang tải một thứ gì đó (hoặc thông qua ajax hoặc tải trang bình thường), hoặc tương tự với tập lệnh Greasemonkey hoặc thông qua một số API JavaScript (điều này sẽ là giải pháp tốt nhất, nhưng từ những gì tôi có thể thấy, không có loại nào tồn tại).Nếu trình duyệt đang bận

Tôi đã tự hỏi cách tốt nhất để làm điều này là gì. Tôi đã tìm kiếm các hướng dẫn Firefox Addon/Greasemonkey để làm một cái gì đó như thế này và không thể tìm thấy bất cứ điều gì. Có ai có bất kỳ lời khuyên hoặc nguồn lực mà họ có thể chỉ cho tôi hướng tới hoặc giải pháp tốt hơn để giải quyết này?

Cảm ơn

Chỉnh sửa: và do bận rộn, tôi chỉ cần biết liệu trình duyệt đang gửi hoặc nhận dữ liệu từ máy chủ.

Trả lời

2

Đây là những gì tôi nghĩ tôi sẽ làm. Giải pháp này giống như giải pháp được Alex đề xuất với các sự kiện Jquery, ngoại trừ việc nó sử dụng XMLHttpRequest (Bao gồm cả Jquery):

var runningAjaxCount = 0; 

var oldSend = XMLHttpRequest.prototype.send; 
XMLHttpRequest.prototype.send = function() { 
    oldOnReady = this.onreadystatechange; 
    this.onreadystatechange = function() { 
     oldOnReady.call(this); 
     if(this.readyState == XMLHttpRequest.DONE) { 
      ajaxStopped(); 
     } 
    } 
    ajaxStarted(); 
    oldSend.apply(this, arguments); 
} 

function ajaxStarted() { 
    runningAjaxCount++; 
} 

function ajaxStopped() { 
    runningAjaxCount--; 
} 

function isCallingAjax() { 
    return runningAjaxCount > 0; 
} 

function isBrowserBusy() { 
    return document.readyState != "complete" && isCallingAjax(); 
} 
+0

Tôi nghĩ rằng tôi muốn bình luận và nói rằng 3 năm sau, chúng tôi vẫn đang sử dụng cách tiếp cận cơ bản này và nó hoạt động tuyệt vời! – Joel

+0

Điều này thực sự tuyệt vời! Cảm ơn! Thực sự hữu ích cho một số thử nghiệm tự động/cạo trang web. – Evers

4

jQuery, một khuôn khổ javascript tuyệt vời cho thao tác DOM và thực hiện các cuộc gọi ajax, cung cấp hai móc lớn để xác định khi cuộc gọi ajax là cơ bản dở dang:

$.ajaxStart()$.ajaxStop()

Cả hai móc mất một hàm điều khiển sẽ được gọi khi một cuộc gọi ajax sắp bắt đầu, và khi tất cả các cuộc gọi ajax đã ngừng, tương ứng. Các chức năng này có thể được liên kết với bất kỳ phần tử nào trên trang. Bạn có thể đặt giá trị boolean chung trong trình xử lý $.ajaxStart() của bạn thành true và đặt trở lại false trong trình xử lý $.ajaxStop() của bạn.

Sau đó, bạn có thể kiểm tra cờ boolean đó và xác định xem có đang thực hiện các cuộc gọi ajax hay không.

cái gì đó dọc những dòng này:

$(document).ajaxStart(function() { 
    window.ajaxBusy = true; 
}); 

$(document).ajaxStop(function() { 
    window.ajaxBusy = false; 
}); 

Theo như xác định khi trình duyệt đang tải trang hiện tại, bạn có thể kiểm tra document.readyState. Nó trả về một chuỗi "loading" trong khi tài liệu đang tải và một chuỗi là "complete" khi nó đã được tải. Bạn có thể liên kết một trình xử lý với document.onreadystatechange và đặt một boolean toàn cầu sẽ cho biết liệu tài liệu đó vẫn đang tải hay không.

Something như thế này:

document.onreadystatechange = function() { 
    switch (document.readyState) { 
     case "loading": 
      window.documentLoading = true; 
      break; 
     case "complete": 
      window.documentLoading = false; 
      break; 
     default: 
      window.documentLoading = false; 
    } 
} 

EDIT:

Dường như $.ajaxStart()$.ajaxStop() KHÔNG làm việc cho các cuộc gọi ajax gọi mà không cần jQuery. Tất cả các đối tượng XMLhttprequest có một sự kiện được gọi là readystatechange mà bạn có thể đính kèm một trình xử lý. Bạn có thể sử dụng chức năng này để xác định có thực hiện cuộc gọi riêng lẻ hay không. Bạn có thể đẩy tất cả các tham chiếu đến các cuộc gọi chưa thực hiện lên một mảng và trong một kiểm tra độ dài của mảng đó theo số setInterval(). Nếu nó> 1, có các cuộc gọi ajax đứng. Đó là một cách tiếp cận thô lỗ, và chỉ có một cách để có được nó. Có lẽ có nhiều cách khác để làm điều này. Nhưng đây là cách tiếp cận chung:

// declare array to hold references to outstanding requets 
window.orequets = []; 

var req = XMLHttpRequest(); 
// open the request and send it here.... 
// then attach a handler to `onreadystatechange` 
req.onreadystatechange = function() { 
    if (req.readyState != 4 || req.readyState != 3) { 
     // req is still in progress 
     orequests.push(req); 
     window.reqPos = orequests.length -1 
    } else { 
     window.orequests = orequests.slice(reqPos, reqPos + 1); 
    } 
} 

Làm như trên cho mỗi XMLHttpRequest() bạn sẽ gửi, tất nhiên thay đổi tên yêu cầu cho mỗi người. Sau đó chạy một số setInterval() chạy mỗi x số mili giây và kiểm tra thuộc tính độ dài của orequests. Nếu nó bằng 0, không có yêu cầu nào xảy ra, nếu nó lớn hơn 0, yêu cầu vẫn đang xảy ra.Nếu không có yêu cầu nào xảy ra, bạn có thể xóa khoảng thời gian qua clearInterval() hoặc tiếp tục chạy.

setInterval của bạn có thể trông giống như thế này:

var ajaxInterval = setInterval(function() { 
    if (orequests.length > 0) { 
     // ajax calls are in progress 
     window.xttpBusy = true; 
    } else { 
     // ajax calls have ceased 
     window.xttpBusy = false; 
     // you could call clearInterval(ajaxInterval) here but I don't know if that's your intention 
    }, 
    3000 // run every 3 seconds. (You can decide how often you want to run it) 
}); 
+0

OP hỏi làm thế nào để thực hiện việc này từ tiện ích mở rộng của Firefox chứ không phải từ web trang sử dụng jQuery. – PleaseStand

+1

Tôi đọc qua các tài liệu jquery trên hai phương pháp đó và họ nhìn vào chỗ cho những gì tôi đang tìm kiếm. Tôi vẫn có một câu hỏi: liệu những sự kiện đó chỉ liên kết với các cuộc gọi Jquery Ajax? Hoặc với bất kỳ cuộc gọi Ajax JavaScript nào? – Joel

+0

@idealmachine, tôi thực sự đã yêu cầu bất kỳ giải pháp nào bao gồm thư viện firefox hoặc JavaScript. – Joel

0

Trình duyệt về mặt kỹ thuật là không bao giờ "bận rộn". Kinh doanh là một thuật ngữ rất chủ quan. Giả sử rằng luồng chính đang thực hiện một vòng lặp while đơn giản để chặn thực thi. Điều này có thể được coi là bận rộn, nhưng nếu bạn có một cái gì đó như thế này:

function busy() {setTimeout(busy, 0);do_something();} 
busy(); 

Trình duyệt không bị chặn (mỗi lần), cho dù trang có "bận" không rõ ràng. Ngoài ra, điều đó thậm chí không bắt đầu chạm vào nhân viên web và mã trong chrome.

Bạn sẽ khó ép để thực hiện việc này và thậm chí nếu bạn làm như vậy, nó có thể sẽ không hoạt động như bạn mong đợi. Chúc may mắn, dù sao đi nữa.

+0

Tôi thực sự muốn mạng bận. Tôi cần phải biết nếu thebrowser đang gửi hoặc ghi dữ liệu. Tôi sẽ cập nhật bài viết của mình để làm rõ. Cảm ơn. – Joel

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