Page 1/2 of the code inserted to the innerHTML script

Source: Internet
Author: User
Tags comment tag html comment

In ajax programming, we often need to assign the page content obtained by xmlhttp to a container (such as div, span, or td) through innerHTML, but there is a problem here, that is, if the page content we will assign to innerHTML contains scripts, these scripts, whether external scripts or internal scripts, may not be executed (1. This problem may be insignificant or even negligible in some cases, but sometimes it is very serious, and it is likely that our program will not get the expected results. Therefore, we need to solve this problem.

If you have read MSDN, you will find that not all scripts inserted into innerHTML cannot be executed. If the script tag of this script contains the defer attribute, IE will correctly execute these scripts. Unfortunately, Moziila, Firefox, and Opera do not use this set. No matter whether the script tag has the defer attribute set, these browsers will not execute scripts inserted into innerHTML like IE.

But no matter whether the script is executed or not, we can be certain that these scripts are indeed inserted into innerHTML. If you don't believe them, you can use alert to check them out. However, if you are alert, you may also find an exception, that is, if the script starts with the innerHTML content, the IE browser will ignore this script, moziila, Firefox, and Opera do not.

Now, the problem analysis is almost done. Let's take a look at how to solve it.

The solution is actually very simple. It is to extract all the scripts inserted into innerHTML and execute them one by one. However, we need to solve the above two problems first.

First, let's look at the first question. How can we avoid repeated execution of scripts with the defer attribute in innerHTML in IE. This is easy. You only need to determine whether the browser is IE and then check whether the script to be executed has the defer attribute. It should be noted that when determining the IE browser, we need to avoid being recognized and spoofed by the opera Browser. In the subsequent code, we will see how it works.

Next, let's look at the problem that IE ignores the script starting with innerHTML, which is also easy to solve. You only need to append a piece of content that is not a script at the beginning of the content to be inserted into innerHTML. However, do not try to append a label with null content, or use spaces, carriage return, or line breaks. This will not work, and the script at the beginning will still be ignored. Do not try to append the script. Although this can make the script at the beginning no longer be ignored, it will still affect the display of the original content. Although you may not think it is obvious, for the picky user, this may be intolerable. Therefore, in order to ensure that the added content can not only prevent the start script from being ignored, but also avoid adverse effects, we will add the following content:

<Span style = "display: none"> hack ie </span>
Although the content above has a certain length, it is not displayed, and the inserted label does not have an id or name, therefore, it does not conflict with the id or name of some labels in the original content. However, it should be noted that you should determine whether the content is IE or not, and then decide not to add the content, because some other browsers may not support display: none (for example, Opera Mini). If you add this code, the final display effect will be affected.

Next let's take a look at how to extract the script and execute it.

It is easy to retrieve the script. You only need to use the getElementsByTagName method of the object where innerHTML is located. This method works for almost all container labels. After the scripts are taken out, we need to determine whether they are external scripts or internal scripts.

First, let's look at the external script. If it is an external script, we chose this method, that is, first create a copy object for this external script, and set its defer attribute to true (this is to allow the IE browser to execute it correctly), and then insert the copy object to the head using the appendChild method. Here you may ask, why is it not inserted into the object where innerHTML is located? Isn't it better to insert it into the object where innerHTML is located? If you try it, you will know that if you insert it into the object where innerHTML is located, there will be no problem in IE browser, but there will be some problems in Mozilla/Firefox and Opera browsers. The problem is that if you do this on Firefox, the browser will stop responding (this is the test result on Firefox 1.5, and it is unknown if other versions have this problem), while on Opera, the script is inexplicably executed twice (this is the test result on Opera 8.5, and it is unknown whether the problem occurs in other versions of Opera ). To avoid these problems, I chose to insert them into the head.

Let's look at the internal script. We can directly obtain the content of the internal script using the text attribute of the script object. Here we use the text attribute of the script object instead of the innerHTML attribute because in the Opera browser, the innerHTML attribute of the script object is empty. Only the text attribute can be used to obtain the script content. Run the internal script and run eval directly. However, the script may be included in the HTML comment tag. Therefore, we need to remove the comment tag first, otherwise an error will occur in IE.

The above analysis looks perfect, but there is still a problem, one is document. write and document. the writeln problem. In Blueidea, bound0 provides an idea to replace the default document. write and document. the writeln method, however, uses string replacement. Therefore, it is only valid for internal scripts and cannot be used for external scripts. Therefore, I thought of a more general method, that is, directly replacing the document. write and document. re-define writeln, so that no matter whether the internal script or external script is executed, it is our own document. write and document. writeln. However, there are also some side effects, that is, these two functions cannot be used in the current page as before, but these two functions will not be used after the page is loaded, so the side effects of redefining them are very small. However, we still cannot guarantee document. write or document. the content output by writeln is displayed in the most appropriate position. It only attaches the content to the container where the content is placed.

Another problem is caused by eval. One is the scope problem of hutia on Blueidea, and the other is that if the internal script executed by eval is used, the internal script will be executed before the external script is loaded. To solve these two problems, you can use window. the setTimeout function allows every script to be executed after a delay of a period. The external script delay can be set to a long time to ensure full loading, while the internal script can be set to a short time, because the execution time of a script is usually very short, this ensures that the scope is not changed, it can basically ensure that the script execution sequence will not change (this method may not necessarily be 100% effective to ensure the execution sequence. If the network is very busy, external Scripts may not be loaded in the set time, but at least it is much better than directly using eval ).

-----------
(1) Note: Here, we use the qualifier "possible", because the script will be executed in one case and you will see this situation in the following article.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.