【问题标题】:Using $.ajaxStop() to determine when page is finished loading in CasperJS使用 $.ajaxStop() 在 CasperJS 中确定页面何时完成加载
【发布时间】:2015-06-22 17:20:45
【问题描述】:

到目前为止,在我用 CasperJS 编写的测试中,我一直在页面特定的元素上使用 waitForSelector() 来确定页面是否已完全加载(包括所有异步 ajax 请求)。我希望提出一种更标准的等待页面加载的方法,并想知道以下是否可行?

  1. 作为客户端脚本注入以下内容(include.js)

    $(document).ajaxStop(function() {
        // Do something
    })
    

根据jquery api对ajaxStop的描述:注册一个处理程序,当所有Ajax请求都完成时调用。

  1. 定义一个 casper.waitForLoad 函数,该函数在调用时会等待上述代码块中的“某事”

  2. 在测试的几个部分使用该函数。

还有关于 // Do Something 部分的任何提示也将不胜感激 :) 我正在考虑在 phantomJS 中使用 window.callPhantom 功能,但我读到它在 casperjs 中不受官方支持。

【问题讨论】:

  • 另外,是否可以在 phantom/casper 评估函数中等待回调以使用 jQuery 的 Deferred 对象解决?类似于: request = page.evaluate -> deferred = $.Deferred $.ajaxStop(deferred.resolve) return deferred.promise 如果语法不准确,请见谅

标签: javascript jquery ajax phantomjs casperjs


【解决方案1】:

我会在 include.js 中做这样的事情:

(function(){
    window._allAjaxRequestsHaveStopped = false;
    var interval;
    $(document).ajaxStop(function() {
        if (interval) {
            clearInterval(interval);
            interval = null;
        }
        interval = setTimeout(function(){
            window._allAjaxRequestsHaveStopped = true;
        }, 500);
    });
    $(document).ajaxStart(function() {
        window._allAjaxRequestsHaveStopped = false;
        if (interval) {
            clearInterval(interval);
            interval = null;
        }
    });
})();

这为window 对象设置了一个(希望是唯一的)变量,以后可以检索该变量。如果上一批结束后还有另一个请求,这也会等待更长的时间。

在 CasperJS 中,您可能会执行以下操作来等待请求状态的更改。这使用向casper 对象添加一个新函数,并在内部使用casper.waitFor() 来检查更改。

casper.waitForAjaxStop = function(then, onTimeout, timeout){
    return this.waitFor(function(){
        return this.evaluate(function(){
            return window._allAjaxRequestsHaveStopped;
        });
    }, then, onTimeout, timeout);
};

并像这样使用它:

casper.start(url).waitForAjaxStop().then(function(){
    // do something
}).run();

或者这个:

casper.start(url).thenClick(selector).waitForAjaxStop().then(function(){
    // do something
}).run();

【讨论】:

  • 谢谢!非常小的问题:我编写了一个 include.js,它设置了一个变量,但没有明确地将它放在窗口上下文中,并且我能够在后期使用 casper.evaluate() 很好地检索它。这些变量默认情况下是否在窗口范围内? AFAIK 没有超出窗口范围的全局范围。
  • 是的,他们是。在所有函数之外声明的变量在全局范围内,在浏览器中,这意味着在 window 对象中。
  • casperjs在哪里注入javascript?例如,在处理只重新渲染body内容的javascript构建的单页应用程序时,是否可以删除注入的javascript?
  • 是的,当然。 casper.evaluate(function(){ delete window.__utils__; delete window.callPhantom;}); 删除所有 PhantomJS 和 CasperJS 参与的痕迹,例如,如果页面想要检查它在哪个浏览器中执行。请注意,如果您这样做,大多数 CasperJS 函数将不再工作。
  • 啊但是不会自动删除吧?我正在尝试解决 ajaxStop / ajaxStart 有时不会被调用的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-08
  • 1970-01-01
  • 1970-01-01
  • 2012-06-15
相关资源
最近更新 更多