我已经尝试并测试了 – 成功的幻影17000示例.但是,我很难通过
phantomjs-node模块实现它,主要是因为page.evaluate在回调中被评估.
PhantomJS实现
page.open("http://twitter.com/#!/sencha",function () { waitFor(function() { // This here is easy to do as the evaluate method returns immediately return page.evaluate(function() { return $("#signin-dropdown").is(":visible"); }); },function() { console.log("The sign-in dialog should be visible now."); phantom.exit(); }); } });
然而,使用phantomjs-node,评估函数在回调中获取返回的数据:
page.evaluate( function(){ /* return thing */ },function callback(thing) { /* write code for thing */ } )
使用phantomjs-node,如何在元素可见后才能在页面上运行一个函数?
/** * Wait until the test condition is true or a timeout occurs. Useful for waiting * on a server response or for a ui change (fadeIn,etc.) to occur. * * @param testFx javascript condition that evaluates to a boolean,* it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or * as a callback function. * @param onReady what to do when testFx condition is fulfilled,* it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or * as a callback function. * @param timeOutMillis the max amount of time to wait. If not specified,3 sec is used. */ 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 } } },250); //< repeat check every 250ms };
提前致谢.
解决方法
在今天遇到这个问题,以为我会分享我的解决方案.
// custom helper function function wait(testFx,maxWait,start) { var start = start || new Date().getTime() if (new Date().getTime() - start < maxWait) { testFx(function(result) { if (result) { onReady() } else { setTimeout(function() { wait(testFx,start) },250) } }) } else { console.error('page timed out') ph.exit() } }
第一步是创建一个新的等待功能.它采用与原始waitFor功能相同的参数,但工作方式略有不同.而不是使用间隔,我们必须递归运行等待函数,从测试函数testFx的回调被触发.此外,请注意,您实际上不需要传入一个开始值,因为它会自动设置.
wait(function (cb) { return page.evaluate(function () // check if something is on the page (should return true/false) return something },cb) },function () { // onReady function // code },5000) // maxWait
在此示例中,我将testFx函数的回调设置为page.evaluate的回调,该值基于是否能够在页面上找到某个元素返回true / false值.或者,您可以为page.evaluate创建回调,然后从中触发testFx回调,如下所示:
wait(function (cb) { return page.evaluate(function () // check if something is on the page (should return true/false) return something },function(result) { var newResult = doSomethingCrazy(result) cb(newResult) } },5000) // maxWait