获取浏览器是否正忙

时间:2010-11-20 06:58:52

标签: javascript firefox firefox-addon greasemonkey

如果浏览器目前忙于使用JavaScript,我正试图找到一种方法。我正在寻找一个Firefox扩展来注入一个布尔值,如果当前页面正在加载某些东西(通过ajax或只是正常的页面加载),或者与Greasemonkey脚本相同,或者通过一些JavaScript API(这会是最好的解决方案,但从我所看到的,没有任何类型存在)。

我想知道最好的办法是什么。我一直在寻找Firefox Addon / Greasemonkey教程来制作这样的东西,却找不到任何东西。有没有人有他们可以指出的任何提示或资源或更好的解决方案?

由于

编辑:忙碌时,我大多只需要知道浏览器是从服务器发送还是接收数据。

3 个答案:

答案 0 :(得分:3)

jQuery,一个用于DOM操作和执行ajax调用的优秀javascript框架,提供了两个很好的钩子来确定ajax调用何时正在进行中:

$.ajaxStart()$.ajaxStop()

这两个钩子都采用一个处理函数,当ajax调用即将开始时,以及当所有ajax调用分别停止时,将调用该函数。这些函数可以绑定到页面上的任何元素。您可以将$.ajaxStart()处理程序中的全局布尔值设置为true,并在$.ajaxStop()处理程序中将其设置为false。

然后,您可以检查该布尔标志并确定是否正在进行ajax调用。

这些方面的东西:

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

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

至于确定浏览器何时加载当前页面,您可以检查 document.readyState。它在文档加载时返回一个"loading"字符串,并在加载后返回一个"complete"字符串。您可以将处理程序绑定到document.onreadystatechange并设置一个全局布尔值,以指示文档是否仍在加载。

这样的事情:

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

编辑:

$.ajaxStart()$.ajaxStop()似乎不适用于没有jQuery调用的ajax调用。所有XMLhttprequest对象都有一个名为readystatechange的事件,您可以将处理程序附加到该事件。您可以利用此功能来确定是否完成了单个呼叫。您可以将所有对未完成调用的引用推送到数组,并在setInterval()中检查该数组的长度。如果它> 1,有站出来的ajax电话。这是一个粗略的方法,只有一种方法来实现它。可能还有其他方法可以做到这一点。但这是一般方法:

// 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);
    }
}

对于您要发送的每个XMLHttpRequest()执行上述操作,当然更改每个{1}}的请求名称。然后运行每{x}毫秒运行的setInterval(),并检查orequests的长度属性。如果它等于零,则不发生任何请求,如果它大于零,则仍然发生请求。如果没有发生请求,您可以通过clearInterval()清除间隔或保持其运行。

您的setInterval可能如下所示:

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)
}); 

答案 1 :(得分:3)

以下是我认为我最终会做的事情。这个解决方案就像Alex在Jquery事件中建议的那样,除了它适用于任何使用XMLHttpRequest(包括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();
}

答案 2 :(得分:0)

浏览器技术上并不“忙”。商业是一个非常主观的术语。假设主线程正在执行一个阻止执行的简单while循环。这可能被认为很忙,但如果你有这样的事情怎么办:

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

浏览器没有被阻止(本身),因此页面是否“忙”是非常不清楚的。此外,这甚至没有开始触及网络工作者和Chrome中的代码。

你会很难做到这一点,即使你这样做,它也可能不会像你期望的那样发挥作用。祝你好运。