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.
Related
I am sure I don't fully understand this problem, but it seems that we are seeing strange behavior on IE9 on my project, somehow related to out-of-order execution of JavaScript that has been injected via calls to document.write, e.g.:
document.write('<scr'+'ipt type="text/javascript" src="'+file1+'"></src'+'ipt>');
document.write('<scr'+'ipt type="text/javascript" src="'+file2+'"></src'+'ipt>');
document.write('<scr'+'ipt type="text/javascript" src="'+file3+'"></src'+'ipt>');
My limited Google research suggests that IE9 will execute scripts injected in this manner in a different order from other browsers (notably, Firefox and Chrome). Is there a better way to achieve what we're going for here, which will ensure the same execution order by all browsers?
I take that back: we don't really care about all browsers, just Chrome and IE9.
Use a script loader (like the one I wrote: LABjs), which will normalize all the different quirks of loading across the various browsers. And bonus: it doesn't use that god-awful document.write(). LABjs will let you load all your scripts asynchronously (in parallel), but make sure they execute in the proper order. Sounds like basically exactly what you want.
I guess you could chain the onload event of one to start the load of another:
var newJS= document.createElement('script');
newJS.onload=function() {alert("done")} //or call next load function
newJS.src="..."
document.body.appendChild(newJS)
So the advantage of writing script tags this way is that they are loaded asynchronously. I don't know about browser nuances about exactly how this is done but I would have thought they would be executed when they're downloaded, in no specific order. Similar to the behaviour of the HTML5 async attribute.
There's another HTML5 attribute defer which instead makes scripts execute in order, but in a non blocking way. You could try adding that into your generated <script> tags. IE9 partially honours it.
I have made a little script, exactly for this purpose:
https://github.com/mudroljub/js-async-loader
In short, it loads all your scripts asynchronously, and then executes them consequently. It looks something like this:
for (var lib in libs) {
loadAsync(lib);
}
And you don't need document.write();
I'm using a framework which features auto-connecting to server on page load. I can disable it by passing options arguments, but the line that confuses me is this:
You can prevent this initial socket from connecting automatically by disabling io.sails.autoConnect before the first cycle of the event loop elapses.
My questions are:
When does the first cycle of the event loop elapses?
Is this behaviour the same across ALL modern (IE9+) browsers?
I have a bunch of scripts (in <body>) loading between the lib and my entry file. Does this affect when the first cycle elapses? EDIT: Yes, it does.
How can I ensure my code runs before the first cycle elapses?
Is this kind of implementation of auto-connect considered good practice?
The documentation for the source file is a little more explicit; it says "This can be disabled or configured by setting io.socket.options within the first cycle of the event loop."
Basically what's happening is that there exists within the library a setTimeout(fn, 0) call, which is idiomatic for starting a parallel process. However, in the JS standards it's explicitly stated that JS is single-threaded: in other words, even though setTimeout and setInterval are asynchronous they are not actually parallel in the sense that any of their code will be executing simultaneously with any other code. So they wait until the current function is over before they execute. This queueing mechanism is known as the JavaScript event loop.
I believe that what you are asked to do by the script author is to modify the source to include the relevant change, perhaps at the bottom of the file for your convenience.
It is also likely that a similar effect will be achieved by putting a <script> tag underneath the one that loads the given JS. This has not been explicitly standardized by HTML 4, but may be implicitly standardized in the new HTML 5 spec (it's a complicated interaction between different parts of the specs).
In terms of HTML5, it looks like the current specs say that there is a afterscriptexecute event and a load event which occur immediately after any remote script is loaded (or, if it's an inline script, the load event is scheduled as a task -- I am not sure when those occur). So you might be able to guarantee it without modifying the script by instead doing:
<script>
function do_not_autoload() { /* ... */ }
</script>
<script onload="do_not_autoload()" src="./path/to/sails.io.js"></script>
but I'm not sure what the compatibility table for script#onload is going to look like.
I made you a jsfiddle which can be used to grab a 'fingerprint' for different browsers to get an idea of what evaluation orders are out there in the wild. The * is the document.body.onload event. On my system it produces:
Firefox 32.0.3 : cafdbe*
Chrome 37.0.2062 : cafd*be
IE 11.0.9600 : cafd*be
In other words,
How to know which Javascript (.js) executed a GET or Ajax call using Firebug or Google Chrome Plugin?
For example, a request for a image or html file executed by a Javascript, how to know which Javascript on the page executed that
Update:
I have to (shamefully) admit that the original below was wrong. Due to the nature of the js execution flow this works at the first execution time:
console.log($("script").last().attr("class")); //or whatever
That, however, is not good enough, as illustrated by a call on a timeout. We need to keep the reference to the script element, this can be achieved by wrapping script contents into a closure and creating a variable to store the jQuery reference:
(function(){
var $scriptElement = $("script").last();
console.log($scriptElement.attr("class")); //or whatever
})();
Now, I have to disclaim that with the markup as above it is unlikely to be practical unless you come up with a better way to store the script element reference... this pretty much became a rather bad example of what could be done but really shouldn't :(
Unless you have to get the reference in-code, you would be much better off looking at the console output, it actually tells you where the output originated from, with the line# and everything:
Original:
Not sure how applicable this would be to external js (script tag with a src), but for inline scripts you could do something like this w/jQuery:
$(this).closest("script");//gets you reference to the script element
I'm assuming it would just a matter of getting its src attribute! Let us know if it works.
console.log($(this).closest("script").attr("src"));
In chrome you can break on any xhr request. This will only set breakpoints for AJAX calls though.
First of all I am new to javascript so this question might be stupid.
I have a requirement where i would provide a js script to other websites to include in their webpages.
Now my question is should I use jquery or plain javascript.Will/Can jquery effect the rest of the functionality of the site.
Plus what is the benefit I will get using jquery over plain javascript.
My requirement is to get all images of the website and do some processing on the images on these websites.
Thanks in Advance.
I would say, if the processing does not involve jQuery then do not use it.
You need to deal with the following issues if you include it
failure to load (for network reasons)
conflict with other versions locally loaded
conflict with other libraries locally loaded
All issues have workarounds/solutions but you have to implement each an everyone of those.
If you just need to find all images in page, then you can use the .getElementsByTagName() method
var imagelist = document.getElementsByTagName('img');
and just do the processing on that..
You might need of-course to attach your code at the load event to be sure that whatever your code does, the DOM is ready to accept it..
for modern browsers that would be .addEventListener(), while for IE it would be .attchEvent()
your script could be something like this
(function(){ // wrap in a self-invoking function to avoid global name-space pollution
// attach to the load event so out code runs once the page has loaded
if (window.addEventListener) { // modern
window.addEventListener('load', imageProcessor, false);
}
else if (window.attachEvent) { // IE
window.attachEvent('onload', imageProcessor );
}
function imageProcessor(){
// get all images
var imagelist = document.getElementsByTagName('img');
// loop the list of images to do something with each image
for (var img = 0; img < imagelist.length; img++)
{
var currentImage = imagelist[img];
// do processing on the currentImage which hold a reference to the image
}
}
})(); // do the self-invoking
demo: http://jsfiddle.net/gaby/nXPzk/
this would be much more easier to achieve with jQuery, mostly because you want to be able to distribute your script to any browser(and jQuery is a cross-browser library), but it does have it's downsides.
If it's your own project, your own page, you know exactly what and when to load/execute, but if you're giving your script to other folks, you have to think of 3 problems at least:
different libraries conflicts
This can be resolved using jquery's noConflict method, but I've seen it fail in some circumstances
same library conflicts
Say that the user already has loaded version X of jQuery. You oblige him to load version Y too, and besides the fact that this would be very inefficient, it may cause conflicts between different jQuery versions.
There are workarounds for this( to check if jQuery exists and load it asynchroniously if it doesn't) but the code gets a bit more complicated.
code size
When i think of a third party piece of code, I'm thinking...hmm a few kb to load to be able to run a function, but if you want to use jQuery, you may be forcing the one who uses your script to load a whole library just for your one functionality instead of a 1-2 kb (needles to say what the implications are if the user has a slow connection)
Having both the ups and downs in mind, it really depends on what are you doing, so, as Gaby aka G. Petrioli said, " if the processing does not involve jQuery then do not use it".
JQuery is much more convenient than plain javascript. You don't have to worry about cross-browser compatibility (e.g. IE vs. Firefox vs. Chrome). I would recommend this over javascript unless you are want to handle that yourself :)
You can load in the Jquery library, but that might be a little heavy than what you're looking for. Also, you will need to fetch the library from a server, which adds another point of failure (however, if you host this on your own server, then you will have more control).
TLDR: JQuery is convenient. If you have access to it, then you should use it.
I'm developing a site in javascript and jquery. Sometimes when I refresh I just get different random errors in firebug. What's the deal?
edit: I'm getting errors like a variable isn't defined, when clearly it is and working, and when i refresh again, the error is gone..
using Firefox V3.5.5 Firebug V.1.5.3 and I'm primarily working with jQuery 1.4.2
OK. While it's more or less impossible to give a reasonable solution to such a general question, I'll just add my 2 cents' worth:
One possible source of "undefined variable" errors comes from including several scripts, which may or may not always load and execute in the same order. If you define a variable in one script (let's call that script declare.js) and use it in another (let's say use.js), and use.js is executed before declare.js, then you will get such an error. If the scripts execute the other way around, everything will appear fine.
If you're interested in this very topic, have a look at e.g. Steve Souders' book Even faster web sites, published by O'Reilly. More specifically, look at the chapter about non-blocking script loading.
Most common cause is that you're trying to execute Javascript before the DOM is loaded and thus before all HTML elements are available in the DOM tree, which in turn may cause that simple calls like document.getElementById(id) and jQuery's $(selector) may return undefined elements. That it sometimes works is pure coincidence and a matter of timing.
You need to ensure that any Javascript/jQuery code which is supposed to be executed during page load and relies on the availability of the elements in the DOM tree, also really get executed after the DOM is loaded. In plain vanilla JS you can do so:
window.onload = function() {
document.getElementById(someId);
}
and in jQuery:
$(document).ready(function() {
$(someSelector);
});