代码之家  ›  专栏  ›  技术社区  ›  Joel

浏览器忙时获取

  •  5
  • Joel  · 技术社区  · 14 年前

    我正在尝试找到一种方法,如果浏览器当前正忙于使用JavaScript的话。如果当前页面正在加载某个东西(通过Ajax或普通页面加载),或者使用GreaseMonkey脚本,或者通过一些JavaScript API(这将是最好的解决方案,但从我所看到的情况来看,这是最好的解决方案),我正在寻找一个Firefox扩展来注入布尔值或其他东西。,不存在这种情况)。

    我想知道最好的方法是什么。我一直在寻找火狐插件/油脂猴子制作这样的教程,找不到任何东西。有没有人能给我一些提示或资源,或者更好的解决方法?

    谢谢

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

    3 回复  |  直到 14 年前
        1
  •  3
  •   Alex    14 年前

    jQuery 这是一个很好的用于DOM操作和执行Ajax调用的JavaScript框架,提供了两个很好的钩子,用于确定Ajax调用何时进行:

    $.ajaxStart() $.ajaxStop()

    这两个钩子都接受一个处理程序函数,当Ajax调用即将开始时,以及当所有Ajax调用都分别停止时,将调用该函数。这些函数可以绑定到页面上的任何元素。您可以在 .ajaxstart()美元 处理程序为true,并在 .ajaxstop()美元 处理程序。

    然后可以检查布尔标志并确定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() 当然,您将发送更改每个请求的名称。然后运行一个 设置间隔() 每x毫秒运行一次,并检查 orequests . 如果等于零,则不会发生请求;如果大于零,则仍会发生请求。如果没有请求发生,您可以通过 clearInterval() 或者继续运行。

    设置间隔可能如下所示:

    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)
    }); 
    
        2
  •  3
  •   Joel    14 年前

    这就是我想我最终会做的。这个解决方案类似于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();
    }
    
        3
  •  0
  •   mattbasta    14 年前

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

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

    浏览器本身没有被阻塞,所以页面是否“忙”还不清楚。而且,这甚至还没有开始触及到网络工作者和Chrome中的代码。

    你将很难做到这一点,即使你做到了,也很可能无法达到你所期望的效果。不过,祝你好运。