Jas*_*han 12 javascript node.js phantomjs
我已经尝试并测试了 - 成功 - phantomjs示例waitFor.但是,我很难通过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();
});
}
});
Run Code Online (Sandbox Code Playgroud)
但是,使用phantomjs-node,evaluate函数会在回调中返回返回的数据:
page.evaluate(
function(){ /* return thing */ },
function callback(thing) { /* write code for thing */ }
)
Run Code Online (Sandbox Code Playgroud)
使用phantomjs-node,如何在元素可见后才能在页面上运行函数?
为了防止上面的链接死了,这里是waitFor函数的实现
/**
* 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
};
Run Code Online (Sandbox Code Playgroud)
提前致谢.
ame*_*sol 11
今天遇到这个问题,以为我会分享我的解决方案.
// custom helper function
function wait(testFx, onReady, 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, onReady, maxWait, start)
}, 250)
}
})
} else {
console.error('page timed out')
ph.exit()
}
}
Run Code Online (Sandbox Code Playgroud)
第一步是创建一个新wait功能.它采用与原始waitFor函数相同的参数,但工作方式略有不同.在触发wait测试函数的回调之后,我们必须以递归方式运行函数,而不是使用间隔testFx.另外,请注意,您实际上不需要为其传递值start,因为它会自动设置.
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
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我将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)
}
}, function () { // onReady function
// code
}, 5000) // maxWait
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8096 次 |
| 最近记录: |