1. Introduction
At the end of my article "how to use the same HTML clip-continued on multiple pages", I mentioned the features of JavaScript sequential execution. Although modern browsers can download JavaScript in parallel (Some browsers), their execution is still carried out in the order of introduction considering the JavaScript dependency.
To better test this process, I wrote a simple HTTP handler page service. ashx, which can accept two parameters:
1. file: the server path of the file to be returned.
2. delay: return the HTTP request after a certain delay (in milliseconds ).
A typical page, such as./service. ashx? File = js/jquery-ui.js & delay = 2000, indicating a 2 second delay before returning the js/jquery-ui.js file on the server.
The key code of service. ashx is as follows:
Copy codeThe Code is as follows: public void ProcessRequest (HttpContext context)
{
Int delay = 0;
If (! String. IsNullOrEmpty (context. Request ["delay"])
{
Delay = Convert. ToInt32 (context. Request ["delay"]);
}
If (delay> 0)
{
System. Threading. Thread. Sleep (1000 );
}
String filePath = context. Request ["file"]. ToString ();
String fileContent = String. Empty;
Using (StreamReader sr = new StreamReader (context. Server. MapPath (filePath )))
{
FileContent = sr. ReadToEnd ();
}
If (filePath. EndsWith (". js "))
{
Context. Response. ContentType = "application/x-javascript ";
}
Else
{
Context. Response. ContentType = "text/plain ";
}
Context. Response. Write (fileContent );
}
2. Directly import javascript(test1.htm) through the scripttag)
First, we will analyze how JavaScript is introduced in sequence in the Copy codeThe Code is as follows: <Head>
<Title> </title>
<Script src = "./js/jquery-1.4.4.js"
Type = "text/javascript"> </script>
<Script src = "./service. ashx? File = js/jquery-ui.js & delay = 2000"
Type = "text/javascript"> </script>
<Script>
Alert (typeof (jQuery. ui ));
</Script>
</Head>
<Body>
</Body>
</Html>
We will test this example in various browsers:
Test1.htm
Use the script tag to directly introduce JavaScript
Firefox 3.6 |
|
IE 8 |
|
Chrome 10 |
|
Safari 4 |
|
Opera 11 |
|
We can see that the behavior of various mainstream browsers is consistent. Although jQueryUI returns after a delay of 2 seconds on the server, the introduced inline JavaScript still waits for 2 seconds until the previously introduced JavaScript is executed. This is also a well-known feature of JavaScript sequential execution.
3. Use the javascript‑scripttag (test3.htm)
We first define an addScript function to introduce external or Inline JavaScript. The source code of the test3.htm page is as follows:Copy codeThe Code is as follows: <Head>
<Title> </title>
<Script src = "./js/jquery-1.4.4.js" type = "text/javascript"> </script>
<Script>
Function addScript (url, inline ){
Var head = document. getElementsByTagName ("head") [0];
Var script = document. createElement ('script ');
Script. type = 'text/javascript ';
If (inline ){
Script. text = url;
} Else {
Script. src = url;
}
Head. appendChild (script );
}
$ (Function (){
AddScript ('./service. ashx? File = js/jquery-ui.js & delay = 2000 ');
AddScript ('alert (typeof (jQuery. ui); ', true );
});
</Script>
</Head>
<Body>
<Div id = "container">
</Div>
</Body>
</Html>
We will test this example in various browsers:
Test3.htm
Add a <script> tag using JavaScript
Firefox 3.6 |
|
IE 8 |
|
Chrome 10 |
|
Safari 4 |
|
Opera 11 |
|
It can be seen that when JavaScript is used to introduce external or Inline JavaScript after DOM loading, Firefox and Opera behave the same way, ensuring that the execution sequence of JavaScript is consistent with the import sequence. However, IE8, Chrome, and Safari cannot guarantee the execution sequence.
Although various browsers have different execution sequences, the biggest advantage of this case is that multiple JavaScript files can be downloaded in parallel, Which is consistent across all browsers. Of course, this is not the topic of this article. You can use Google for more details.
Two solutions are provided below to solve the inconsistency of various browsers:
4. solution 1: how to ensure the execution sequence when adding script labels dynamically
Sometimes the page logic requires us to dynamically execute JavaScript using the above method, so how to ensure the execution order in all browsers (currently only Firefox and Opera ensure the execution order ).
In fact, the solution is very simple. Just add a complete callback function for function execution. The following test4.htm provides a specific solution:Copy codeThe Code is as follows: <Head>
<Title> </title>
<Script src = "./js/jquery-1.4.4.js" type = "text/javascript"> </script>
<Script>
Function addScript (url, inline, callback ){
Var head = document. getElementsByTagName ("head") [0];
Var script = document. createElement ('script ');
Script. type = 'text/javascript ';
If (inline ){
Script. text = url;
} Else {
Script. src = url;
Script. onload = script. onreadystatechange = function (){
If (! Script. readyState | script. readyState = 'loaded' | script. readyState = 'complete '){
If (callback ){
Callback ();
}
Script. onload = script. onreadystatechange = null;
};
};
}
Head. appendChild (script );
If (inline & callback ){
Callback ();
}
}
$ (Function (){
AddScript ('./service. ashx? File = js/jquery-ui.js & delay = 2000 ', false, function (){
AddScript ('alert (typeof (jQuery. ui); ', true );
});
});
</Script>
</Head>
<Body>
<Div id = "container">
</Div>
</Body>
</Html>
In this case, all browsers have the same behavior:
Test4.htm
Solve the sequence problem of dynamically adding JavaScript through the callback function
Firefox 3.6 |
|
IE 8 |
|
Chrome 10 |
|
Safari 4 |
|
Opera 11 |
|
5. solution 2: Use jQuery's html function to dynamically add JavaScript
Labels:Copy codeThe Code is as follows: <Head>
<Title> </title>
<Script src = "js/jquery-1.4.4.js" type = "text/javascript"> </script>
<Script>
$ (Function (){
Certificate ('{container'{.html ('<script src = "./service. ashx? File = js/jquery-ui.js & delay = 2000 "type =" text \/javascript "> <\/script> '+' <script> alert (typeof (jQuery. ui); <\/script> ');
});
</Script>
</Head>
<Body>
<Div id = "container">
</Div>
</Body>
</Html>
In this case, the behavior in each browser is consistent:
Test2.htm
Solve the Problem of dynamically adding JavaScript sequence through jQuery's html Function
Firefox 3.6 |
|
IE 8 |
|
Chrome 10 |
|
Safari 4 |
|
Opera 11 |
|
6. Postscript
Why can jQuery's html functions Ensure the dynamic loading of JavaScript Execution sequence?
We know that updating DOM nodes through simple. innerHTML won't allow JavaScript Execution. We can simply change the source code of this example:
$ ('# Iner') [0]. innerHTML = '<script src = "./service. ashx? File = js/jquery-ui.js & delay = 2000 "type =" text \/javascript "> <\/script> '+' <script> alert (typeof (jQuery. ui); <\/script> ';
In this case, jQueryUI does not load at all.
So what if jQuery does? In the next article, we will trace the source code of jQuery. For more information, see: how to ensure the execution sequence of JavaScript-jquery.html deep analysis.