I'm writing a script which generates png images from every page of my frontend. I'm using angular for the UI and capturing the pages with phantom.
The view take a while until angular finish rendering it so I have to wait a little before capturing:
var page = require('webpage').create();
page.open('http://localhost:9000/', function () {
window.setTimeout(function () {
page.render('snapshot.png');
phantom.exit();
}, 2000);
});
I wonder if there is a better way to achieve this. I found angular can emit an event when the page is fully rendered:
$scope.$on('$viewContentLoaded', function () {
// do something
});
And found a way for communicate to phantom with onCallback
so I could write something like:
$scope.$on('$viewContentLoaded', function () {
window.callPhantom({ hello: 'world' });
});
Then in other place in phantom script:
page.onCallback = function() {
page.render('snapshot.png');
phantom.exit();
};
But I'm lost in how to inject the angular $viewContentLoaded
handle from the phantom script.
I don't know if evaluate
/evalueateAsyn
are the way to go ...
page.evaluateAsync(function () {
$scope.$on('$viewContentLoaded', function () {
window.callPhantom({ hello: 'world' });
});
});
Maybe I could access the right $scope
in some way.
Any ideas?
The associated PhantomJS API is onCallback
; you can find the API doc on the wiki.
// in angular
$scope.$on('$viewContentLoaded', function () {
window.callPhantom();
});
// in the phantomjs script
var page = require('webpage').create();
page.onCallback = function() {
page.render('snapshot.png');
phantom.exit();
};
page.open('http://localhost:9000/');
You can get access to the $rootScope
by accessing the injector; for example, if you're using the ng-app
directive, you can find the element with the directive and call .injector().get("$rootScope")
on it. However, I'm not sure if the $viewContentLoaded
event will already have fired by then.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With