click - 在继续之前,如何等待phantomjs中的click()事件加载?

标签 click phantomjs pageload

Phantomjs具有这两个非常方便的回调onLoadStartedonLoadFinished,它们使您可以在页面加载时暂停执行。但是我一直在搜索,如果您click()提交按钮或超链接,我找不到对应的内容。发生了类似的页面加载,但是我猜没有为该事件调用onLoadStarted,因为没有明确的page.open()发生。我正在尝试找出在发生这种负载时挂起执行的干净方法。

一种解决方案显然是嵌套的setTimeout,但是我想避免这种情况,因为它很hacky,并且依赖于反复试验,而不是可靠且更可靠的测试或等待事件。

我错过了此类页面加载的特定回调吗?或者也许有某种通用的代码模式可以处理这种事情?

编辑:

我仍然没有弄清楚如何使其暂停。这是当我调用onLoadStarted()命令时不调用click()函数的代码:

var loadInProgress = false;

page.onLoadStarted = function() {
  loadInProgress = true;
  console.log("load started");
};

page.onLoadFinished = function() {
  loadInProgress = false;
  console.log("load finished");
};

page.open(loginPage.url, function (status) {
    if (status !== 'success') {
        console.log('Unable to access network');
        fs.write(filePath + errorState, 1, 'w');
        phantom.exit();
    } else {
        page.evaluate(function (loginPage, credentials) {
            console.log('inside loginPage evaluate function...\n')
            document.querySelector('input[id=' + loginPage.userId + ']').value = credentials.username;
            document.querySelector('input[id=' + loginPage.passId + ']').value = credentials.password;      
            document.querySelector('input[id=' + loginPage.submitId + ']').click();
            //var aTags = document.getElementsByTagName('a')
            //aTags[1].click();
        }, loginPage, credentials);

        page.render(renderPath + 'postLogin.png');
        console.log('rendered post-login');


我再次检查了ID是否正确。 page.render()将显示该信息已提交,但仅当我将其放入setTimeout()时才会显示,否则它将立即呈现它,并且我只会在页面重定向之前看到输入的凭据。也许我想念其他东西吗?

最佳答案

我认为onLoadStartedonLoadFinished函数是您所需的一切。以以下脚本为例:

var page = require('webpage').create();

page.onResourceReceived = function(response) {
    if (response.stage !== "end") return;
    console.log('Response (#' + response.id + ', stage "' + response.stage + '"): ' + response.url);
};
page.onResourceRequested = function(requestData, networkRequest) {
    console.log('Request (#' + requestData.id + '): ' + requestData.url);
};
page.onUrlChanged = function(targetUrl) {
    console.log('New URL: ' + targetUrl);
};
page.onLoadFinished = function(status) {
    console.log('Load Finished: ' + status);
};
page.onLoadStarted = function() {
    console.log('Load Started');
};
page.onNavigationRequested = function(url, type, willNavigate, main) {
    console.log('Trying to navigate to: ' + url);
};

page.open("http://example.com", function(status){
    page.evaluate(function(){
        // click
        var e = document.createEvent('MouseEvents');
        e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        document.querySelector("a").dispatchEvent(e);
    });
    setTimeout(function(){
        phantom.exit();
    }, 10000);
});


它打印

Trying to navigate to: http://example.com/
Request (#1): http://example.com/
Load Started
New URL: http://example.com/
Response (#1, stage "end"): http://example.com/
Load Finished: success
Trying to navigate to: http://www.iana.org/domains/example
Request (#2): http://www.iana.org/domains/example
Load Started
Trying to navigate to: http://www.iana.org/domains/reserved
Request (#3): http://www.iana.org/domains/reserved
Response (#2, stage "end"): http://www.iana.org/domains/example
New URL: http://www.iana.org/domains/reserved
Request (#4): http://www.iana.org/_css/2013.1/screen.css
Request (#5): http://www.iana.org/_js/2013.1/jquery.js
Request (#6): http://www.iana.org/_js/2013.1/iana.js
Response (#3, stage "end"): http://www.iana.org/domains/reserved
Response (#6, stage "end"): http://www.iana.org/_js/2013.1/iana.js
Response (#4, stage "end"): http://www.iana.org/_css/2013.1/screen.css
Response (#5, stage "end"): http://www.iana.org/_js/2013.1/jquery.js
Request (#7): http://www.iana.org/_img/2013.1/iana-logo-header.svg
Request (#8): http://www.iana.org/_img/2013.1/icann-logo.svg
Response (#8, stage "end"): http://www.iana.org/_img/2013.1/icann-logo.svg
Response (#7, stage "end"): http://www.iana.org/_img/2013.1/iana-logo-header.svg
Request (#9): http://www.iana.org/_css/2013.1/print.css
Response (#9, stage "end"): http://www.iana.org/_css/2013.1/print.css
Load Finished: success

It shows that clicking a link emits the LoadStarted event once and NavigationRequested event twice, because there is a redirect. The trick is to add the event handlers before doing the action:

var page = require('webpage').create();

page.open("http://example.com", function(status){
    page.onLoadFinished = function(status) {
        console.log('Load Finished: ' + status);
        page.render("test37_next_page.png");
        phantom.exit();
    };
    page.onLoadStarted = function() {
        console.log('Load Started');
    };

    page.evaluate(function(){
        var e = document.createEvent('MouseEvents');
        e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        document.querySelector("a").dispatchEvent(e);
    });
});


如果您需要做这些事情,也许是时候尝试其他类似CasperJS的事情了。它运行在PhantomJS之上,但是具有用于浏览网页的更好的API。

关于click - 在继续之前,如何等待phantomjs中的click()事件加载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26270852/

相关文章:

javascript - 如何克隆 ui-sref

javascript - 在页面中创建按钮并单击另一个按钮

node.js - 如何循环遍历链接并为 PhantomJS 中的每个站点执行 jQuery javascript

html - 检测页面加载*后*禁用 Javascript

ember.js - Ember.js 的模板加载延迟

javascript - jQuery 使用 for 循环触发事件 n 次

javascript - jQuery 侧边栏两次单击不会再次加载脚本

javascript - Phantomjs打不开网页

javascript - Selenium WebDriver + PhantomJS + Python - 执行脚本和处理对话框

javascript - 推特按钮脚本同步加载,需要异步加载