I am currently using PhantomJS for some doc's reports and looking in some examples i found this.
window.setTimeout(function () {
page.render(output);
console.log(output);
phantom.exit();
}, 200);
I wonder why using window.setTimeout?? It affect web rendering??
Thanks... Nick.
The page.open callback is invoked only when the page is loaded. This does not means that everything has been loaded in your page and the js has been fully executed.
In addition, the js on the web page may not be executed immediately, especially if the site uses MVC client frameworks like AngularJS or Ember.js : a lot of stuff is done after the page load event.
Using setTimeout give you a little delay to be sure that your page is fully rendered.
Sometimes 200ms is not enought and you have to increase the duration.
Another way is to use the waitfor.js example : waits until a test condition is true such as an element is visisble.
Related
I have a very weird problem in my webpage. On page load, my code calls some setTimeout() functions. They work fine when the page loads the first time. By 'work find' I mean the callback functions execute after a period of time as expected. BUT if I refresh the page, the setTimeout() function appears to execute BUT the callback functions do not.
I have verified this by simply console logging like so:
....
console.log('Step 1');
setTimeout(function() {
console.log('Executed');
...
}, 10);
....
On first page load the output is:
Step 1
Executed
On refreshing that page the output is:
Step 1
Can you provide any advice why this may happen? As murphy's law has it if I create a simple HTML and JS example of the problem it does not exhibit itself. But in my web application it does. I believe I have tracked down the issue to the setTimeout being executed but the callback not executing though. I just don't know why this problem would occur or how to fix it. Getting someone to point me in the right direction to explore solutions would be extremely helpful.
Relevant information:
The webpage uses no JS frameworks (React, etc.). Its uses JQuery, JQuery UI, and a rather large JQuery plugin I've made.
The bug can be reproduced on Chrome, Firefox and Edge (Safari not tested).
These days many webpages have custom Javascript to execute things on page load. They either modify page content or load external widgets.
My extension tries to read the DOM and insert some data in the pages. However in some cases where the page has its own Javascript, my extension executes before the page Javascript.
Due to that the page Javascript may overwrite my insertions or insert data which my extension cannot read. How can I wait to execute my extension until after the page Javascript functions have loaded/executed?
Maybe this will help, but it has some undesired side-effects:
$(function () {
setTimeout(function () {
alert("At last!");
}, 1000); // 1000 millis after page loaded and most probably all onload handlers have been run
});
The main side-effect is that it will be executed after 1000 millis so for that amount of time the user will see the unprocessed page and then your script will manipulate it. Under circumstances this may get ugly and be a detriment to the users' experience.
EDIT:
You may also try this. On the body's end (inside, but at last) add this script tag:
<script>
$(function () { alert("LAST!"); });
</script>
By the rules of script execution and the fact that jQuery honors the order in which onload handlers are added through the $(function () { ... }); idiom you can be pretty sure that your code is executed last. The problem is that any asynchronous execution, such as AJAX callback handlers, will be executed out-of-order (that is, asynchronously in respect to the window.onload handlers that form a chain of responsibility). To cope with that you need a pattern but it's probably overshoot.
I have some serious problem with getting asynchronously some js libs and executing them in $(window).load in IE
all works in other browsers of course
so the problem is, that I'm doing something like
<script type="text/javascript">
var scr1 = document.createElement('script');
scr1.type = 'text/javascript';
scr1.src = 'some_lib.js';
$('BODY').prepend(scr1);
</script>
Just before </body> and use $(window).load method in html above it to operate on some plugins in some_lib.js, but it all happens to fast in IE, probable because of that asynchronous lib including, and I get an error, that method is not available for the element.
Is there any chance of maybe modyfying $(window).load method so I still could use it in the same way for every browser ?
Any code that you have in the window.load() call must be placed in a function (called onLoad in this example).
Every time you have a script that you dynamically load, increment a counter. Also include something to decrement that counter...
src1.onload = function() { counter--; onLoad(); }
Then in 'onLoad' have the first line...
if (counter > 0) return;
That means that onLoad will fire at window.load and after every script is loaded, but will only execute when it's all loaded.
It's scrappy, but it will solve your problem.
You haven't really described the reason you need to load these libraries asynchronously. Third party libraries often have "on script load" functionality that you can define before the script is loaded. If you need to load multiple libraries before you can execute your code, you may have to either 1. fire up some code every time a library is loaded to test to see if all libraries required are loaded and then fire off you code 2. for every library, create a jQuery promise/deferred to get resolved when that library is loaded and use $.when(promises).done(function/code) to test and run the code whenever a particular set is loaded, or 3. rewrite to use RequireJS. If these libraries are YOUR code, well, you may have to add start up code to your libraries anyway; It might be a good time to learn RequireJS.
I wish I could recommend further, but learning the basics behind RequireJS has always been on my todo list, but it hasn't been done; I just know of people here successfully using it. If that seems like too much trouble, I'd consider some variant of option 2. If you don't know what jQuery would be used eh... you may be stuck with option 1 or 3.
Edit:
Of course, that's not to say that jQuery has got the only promise library, I just often recommend using promises in some form for these kind of things..
Archer's technique looks interesting, I just don't know how reliable it is (it might be quite reliable, I just would like to see proof/documentation). You could combine that with option 2 also, quite well, if you want to short-cut execution for some things while leaving others to be dealt asynchronously and if those script onload methods really work as expected.
I'd like to measure how long it takes to run the whole $().ready() scope in each of page.
For profiling specific functions I just set a new Date() variable at the beginning of the relevant part and then check how long it takes to get to the end of the relevant part.
The problem with measuring the whole $().ready scope is that it can sometimes run some of the code asynchronously and then I can not wait for it all to finish and see how long it has taken.
Is there any event which is fired once the page has completely finished running all $().ready code?
EDIT: Using Firebug or other client debuggers are not an option since I also need to collect this profiling information from website users for monitoring and graphing our web site's page load speeds
Thanks!
There will be no event fired because its virtually impossible for ready() to know when any asynchronous functions are done processing. Thus, you'll need to bake this functionality in yourself; you could use jQuery's custom events, or perhaps set a function to run on setInterval() that can introspect the environment and deduce whether or not everything else is done.
Swap out the jQuery ready function with a function that does your start and finish tracking, and calls the original method.
jQuery.ready = (function() {
var original = jQuery.ready;
return function() {
alert('starting profiler');
original();
alert('ending profiler');
};
})();
$(function() {
alert('this message will appear between the profiler messages above...');
});
Have you tried using Profiler in Firebug?
I have a function defined in AS3 that's gonna be called from client side via JavaScript. The AS3 functions simply print some value on SWF screen when it's called.
It works fine when I set an onclick event handler to a button and call the AS3 function. However I want to call this AS3 function as soon as the page loads. I am using jQuery in the project and I placed the call to the AS3 function inside $(document).ready(), but that gives me the following error in FF2 firebug:
getFlashMovie("my_movie_name").my_as3_function is not a function
Then, I tried calling the by setting an onLoad event handler on the , but that also does not work - produces the same error.
So, my question is, how do I call an AS3 function automatically once page loads? In my project, I need to pass some client side initialization information to the flash once page loads.
You'll need to have your flash call a function in the page to notify it that the Flash is loaded and initialized, then use that as your entrypoint.
In the flash:
ExternalInterface.call('flashReady');
In the page:
<script>
function flashReady() {
..
}
</script>
If you use swfObject to embed your SWF (probably a good idea anyway) then you can use its addDomLoadEvent() function which allows you to do something once the SWF is fully loaded
swfobject.addDomLoadEvent(function() {
$("#swfobject").get(0).inited('you are loaded!');
});
i am not trying to be a wiseguy here but do you test your work on a server?
external interface, addcallback dose not work on local filesystem, and eventually you may have to add:
flash.system.Security.allowDomain('http://localhost');
if you are running on local.
:P
The problem is that the Flash object is not initialized yet when the page finishes loading. It would probably be much safer to perform this initialization from within AS3. If you want to pass values from the HTML page, use flashVars.
I ran into this problem myself a couple of weeks ago. The solution is pretty simple :)
First, you need to put in your DOM a div
<div id="timewriter"><div>
You'll also be using the jQuery Timers plugin to time your loading. After this preparation the things will go very easy.
The following piece of code will go in your $(document).ready();
var movie = getFlashMovie('my_movie_name');
if(movie.PercentLoaded() != 100)
{
$("#timewriter").everyTime(100, function ()
{
if(movie.PercentLoaded() == 100)
{
$("#timewriter").stopTime();
//the movie is loaded, call here your functions; usually this happens if you don't use cache
}
});
}
else
{
//the movie is loaded, call here your functions; usually you get here if you use cache
}
Later edit: be careful that HTML page load doesn't mean the swf was loaded, that happens right after the web page load complete event. Also my solution is based on jQuery javascript library.
Answers by both tweakt and Bogdan are viable. Use tweakt's method if you have access to the Actionscript. Use Bogdan's if you don't. I was looking for an alternative besides polling (when you don't have access to the Actionscript) but I have been unsuccessful in finding one thus far. Events are mentioned here: http://www.adobe.com/support/flash/publishexport/scriptingwithflash/scriptingwithflash_03.html But noone seems to know how to use them.
For the sake of completion, you would also have to use import flash.external.*; to make everything work.
It seems like the collection of answers offered answers this closest to it's entirety.
As David Hanak said, the flash object cannot be accessed yet because it is initializing, though i disagree that we must rely on flashvars, though I love them.
Tweakt is right, but upon calling the function in the javascript, have that call the javascript function that calls back to your swf; This way we know flash is ready as it sent the first call.