如何在PhantomJS中通过window.open(url,_blank)捕获新窗口? [英] How to catch new window opend by window.open(url, _blank) in PhantomJS?

查看:218
本文介绍了如何在PhantomJS中通过window.open(url,_blank)捕获新窗口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想查看PhantomJS是否我的脚本在点击时正确打开了一个新的窗口/标签。 open由js事件监听器触发,并通过 window.open(url,_ blank)打开。

I'd like to check with PhantomJS whether my script correctly opens a new window/tab on click. The open is triggerd by a js event listener and opened through window.open(url, "_blank").

我如何使用PhantomJS收听新窗口?

How can I listen for the new window with PhantomJS?

推荐答案

似乎有三种方法可以做到这一点:

There seem to be three ways to do this:

CasperJS通过使用 page.onPageCreated 。因此,当在页面中调用 window.open 时,会创建一个新页面并触发 page.onPageCreated 新创建的页面。

CasperJS solves this by using page.onPageCreated. So when window.open is called in the page, a new page is created and page.onPageCreated is triggered with the newly created page.

page.open(address, function (status) {
    if (status !== 'success') {
        console.log('Unable to load the address!');
        phantom.exit();
    } else {
        page.onPageCreated = function(newPage){
            newPage.onLoadFinished = function(){
                console.log(newPage.url);
                phantom.exit();
            };
        };
        page.evaluate(function(url){
            window.open(url+"?something=other", "_blank");
        }, address);
    }
})



pages



PhantomJS' page 有一个 页面 属性处理子页面。因此,当您打开新页面/选项卡时,将为该页面创建一个新的网页对象。您需要尝试在触发之前向页面添加 onLoadFinished 事件侦听器(无承诺)。当页面上下文中的 window.open 被调用且未知延迟时,它可能很难。

pages

PhantomJS' page has a pages property which handles of the child pages. So, when you open a new page/tab, a new webpage object is created for that page. You need to try to add an onLoadFinished event listener to the page before it fires (no promises). It can be hard and when the window.open is called with an unknown delay from the page context.

这个可以使用 waitFor 等待新页面出现并在加载页面之前附加事件处理程序。这是一个小调整的完整代码。重试间隔从250毫秒减少到50毫秒。

This can be fixed by using something like waitFor to wait for the new page to appear and attach the event handler before the page is loaded. Here is the complete code with a small adjustment. The retry interval is reduced to 50ms from 250ms.

var page = require('webpage').create();
var address = "http://example.com/";

function waitFor(testFx, onReady, timeOutMillis) {
    var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000, //< Default Max Timout is 3s
        start = new Date().getTime(),
        condition = false,
        interval = setInterval(function() {
            if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
                // If not time-out yet and condition not yet fulfilled
                condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
            } else {
                if(!condition) {
                    // If condition still not fulfilled (timeout but condition is 'false')
                    console.log("'waitFor()' timeout");
                    phantom.exit(1);
                } else {
                    // Condition fulfilled (timeout and/or condition is 'true')
                    console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
                    typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
                    clearInterval(interval); //< Stop this interval
                }
            }
        }, 50); //< repeat check every 50ms
};

page.open(address, function (status) {
    if (status !== 'success') {
        console.log('Unable to load the address!');
        phantom.exit();
    } else {
        console.log("p:", page.ownsPages, typeof page.pages, page.pages.length, page.pages);
        waitFor(function test(){
            return page.pages && page.pages[0];
        }, function ready(){
            page.pages[0].onLoadFinished = function(){
                console.log("p:", page.ownsPages, typeof page.pages, page.pages.length, page.pages);
                console.log("inner:", page.pages[0].url);
                phantom.exit();
            };
        });
        page.evaluate(function(url){
            window.open(url+"?something=other", "_blank");
        }, address);
    }
})



代理解决方案



window.open 函数可以是pr oxied并在页面上下文中打开页面后,可以在幻像上下文中注册事件处理程序,通过 window.callPhantom 发出信号,并在 onCallback

Proxy solution

The window.open function can be proxied and after the opening the page in the page context, an event handler can be registered in phantom context signaled through window.callPhantom and caught in onCallback.

page.onInitialized = function(){
    page.evaluate(function(){
        var _oldOpen = window.open;
        window.open = function(url, type){
            _oldOpen.call(window, url, type);
            window.callPhantom({type: "open"});
        };
    });
};
page.onCallback = function(data){
    // a little delay might be necessary
    if (data.type === "open" && page.pages.length > 0) {
        var newPage = page.pages[page.pages.length-1];
        newPage.onLoadFinished = function(){
            console.log(newPage.url);
            phantom.exit();
        };
    }
};
page.open(address, function (status) {
    if (status !== 'success') {
        console.log('Unable to load the address!');
        phantom.exit();
    } else {
        page.evaluate(function(url){
            window.open(url+"?something=other", "_blank");
        }, address);
    }
})

这篇关于如何在PhantomJS中通过window.open(url,_blank)捕获新窗口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆