PhantomJs wartet nicht automatisch auf das Ende aller ausstehenden Skripts. WebPage # onLoadFinished wird für das Onload-Ereignis aufgerufen.
Wie bei den meisten Skripten ist die Idee hier zu warten, bis "etwas" getan oder wahr ist. Ich empfehle Ihnen dringend, waitfor.js zu testen. Es ist wirklich wichtig, dieses Beispiel in PhantomJs zu verstehen.
Ich nehme an, Ihr Beispiel ist ein Beispiel, aber lassen Sie mich eine Antwort vorschlagen.
HTML-Seite
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
<title>Test</title>
</head>
<body id="body">
<script type="text/javascript">
//alert('hello');
$('body').addClass('before-dom-ready');
$(function() {
$('body').addClass('after-dom-ready');
var dfrd = $.Deferred(),
promise = dfrd.promise();
setTimeout(function() {
dfrd.resolve();
}, 5000);
promise.done(function() {
$('body').addClass('promise-executed');
$('body').text('Hello World !');
});
});
</script>
</body>
</html>
PhantomJS Script
var page = require('webpage').create();
var system = require('system');
function waitFor(testFx, onReady, timeOutMillis) {
var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 10000, //< Default Max Timout is 10s
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");
typeof (onReady) === "string" ? eval(onReady) : onReady();
clearInterval(interval);
//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
}
}
}, 500); //< repeat check every 500ms
};
if (system.args.length != 1) {
console.log('invalid call');
phantom.exit(1);
} else {
//adapt url to your context
page.open('http://localhost:9231/demo.html', function (status) {
if (status !== 'success') {
console.log('Unable to load the address!');
phantom.exit();
} else {
waitFor(
function() {
return page.evaluate(function() {
return $('body').hasClass('promise-executed');
}) > 0;
},
function() {
page.render('page.png');
phantom.exit();
}, 10000);
}
});
}
Grundsätzlich wird waitFor
alle 500 ms überprüfen, ob Körper eine Klasse 'promise-executed'
benannt hat.
Ist es möglich, Ihr vollständiges phantomJS-Skript (sowie den vollständigen Code aller anderen Dateien, von denen es abhängt) zu sehen. I.e. so können wir das Problem leicht reproduzieren. –
Zu welchem Zeitpunkt und wie überprüfen Sie, ob die Klasse 'promise-executed' hinzugefügt wurde oder nicht? Welche Art von Debugging haben Sie beispielsweise durchgeführt? Haben Sie versucht, einen 'console.log'-Aufruf nach dem' dfrd.resolve() 'zu platzieren? Hast du diesen Code in einem normalen Browser ausprobiert, mit anderen Worten, was lässt dich glauben, dass es ein PhantomJS-Problem ist? –