Javascript动态执行问题浅析
生活随笔
收集整理的這篇文章主要介紹了
Javascript动态执行问题浅析
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
現(xiàn)在web2.0/ajax大行其道,我們會經(jīng)常碰到這種應用case:前端瀏覽器通過ajax發(fā)請求到后端,后端生成html代碼返回,前端接收后將html代碼插入一個div容器內。這個應用很普遍,一般情況下也不會有什么問題,特別是返回的是單純的數(shù)據(jù)的情況下。但如果返回的html代碼包含javascript函數(shù)或是css style定義,哪可能就會出現(xiàn)問題了。特別是在IE瀏覽器下(由此看出,IE瀏覽器真是垃圾!!真是WEB程序開發(fā)者的噩夢啊。),Javascript動態(tài)執(zhí)行的問題很突出。相對來說,Firefox支持的較好。?
下面是一段示例代碼:?
__cb_render : function( containerId, htmlContent )?
{?
??? var oDiv = document.getElementById( containerId );?
??? while( oDiv.childNodes.length > 0 )?
??? {?
??????? oDiv.removeChild( oDiv.firstChild );?
??? }?
??? try?
??? {?
??????? var container = document.createElement( "div" );?
??????? container.innerHTML = htmlContent;?
??????? oDiv.appendChild( container );?
??? }?
??? catch ( error )?
??? {?
??????? // ignore exception?
??? }?
}?
這段代碼很簡單,將soap返回的html代碼插入到頁面的一個Div容器里。在firefox里執(zhí)行,okay,一切都沒問題。html代碼里的Javascript也能正確得以執(zhí)行。但在IE瀏覽器里,很抱歉,一堆問題就來了。?
首先,如果返回的html代碼以<script開頭,哪IE瀏覽器會直接忽略這些Javascript片斷(很奇怪吧,你可以試試。)。而且,中間的Javascript代碼根本得不到正確執(zhí)行,還有就是采用<script src="test.js"/>這種方式引入Javascript函數(shù),也無法成功。?
所以,對IE瀏覽器,我們就需要采取一些特殊的解決方案。有一種解決方案,是強行在每個script tag中添加一個屬性<script defer="true"......。Defer屬性是指瀏覽器先load完所有html代碼,然后去執(zhí)行相應的Javascript函數(shù)。這種解決方案,一般情況下也能得到正確的結果。但筆者并不推薦,盡量少用defer屬性。?
以下是另一可行的解決方案,也經(jīng)過了多種主流瀏覽器的測試。?
__cb_render : function( containerId, htmlContent )?
{?
??? var oDiv = document.getElementById( containerId );?
??? while( oDiv.childNodes.length > 0 )?
??? {?
??????? oDiv.removeChild( oDiv.firstChild );?
??? }?
??? if( BrowserUtility.isIE( ) )?
??? {?
?????? // 在html代碼開頭添加一段空白代碼,主要是為了解決script放在開頭而被IE忽略的問題?
??????? htmlContent = '<span style="display: none"> </span>' + htmlContent;?
?????? // 去掉html代碼中script tag的defer屬性,防止函數(shù)被執(zhí)行兩次?
??????? htmlContent = htmlContent .replace(/<script(.*)defer([^\s|^>]*)([^>]*)>/gi,'<script$1$3>');?
??? }
??? try?
??? {?
??????? // 先將新的節(jié)點append到DOM中?
??????? var container = document.createElement( "div" );?
?????? container.innerHTML = htmlContent;?
?????? oDiv.appendChild( container );?
??? }?
??? catch ( error )?
??? {?
??????? // ignore exception?
??? }?
??? var scripts = container.getElementsByTagName( "script" );?
??? for( var i = 0; i < scripts.length; i++ )?
??? {?
??????? if( scripts[i].src )?
??????? {
??????????? // 添加script src到head中?
????????????? if( BrowserUtility.isIE( ) )?
??????????? {?
??????????????? var scriptObj = document.createElement( "script" );?
??????????????? scriptObj.setAttribute( "type", "text/javascript" );?
??????????????? scriptObj.setAttribute( "src", scripts[i].src );?
??????????????? var head = document.getElementsByTagName( "head" )[0];?
??????????????? if( head )?
??????????????????? head.appendChild( scriptObj );?
??????????? }
??????? }?
??????? else if ( scripts[i].innerHTML )?
??????? { ????
???????????? //? IE支持該方法去動態(tài)執(zhí)行javascript代碼?
???????????? if ( window.execScript )?
?????????????? window.execScript( scripts[i].innerHTML );?
??????? }?
??? }?
??? // 如果是safari或是KHTML瀏覽器,需要將html代碼中包含的css style代碼顯示的append到head中。?
??? if ( BrowserUtility.isSafari() || BrowserUtility.isKHTML() )?
??? {?
??????? var styles = container.getElementsByTagName("style");?
??????? for ( var i = 0; i < styles.length; i++ )?
??????? {?
??????????? var styleContent = styles[i].innerHTML;?
??????????? if ( styleContent )?
??????????? {?
??????????????? var element = document.createElement("style");?
??????????????? element.type = "text/css";?
??????????????? if ( element.styleSheet )?
??????????????? {?
??????????????????? element.styleSheet.cssText = styleContent;?
??????????????? }?
??????????????? else?
??????????????? {?
??????????????????? element.appendChild( document.createTextNode( styleContent ) );?
??????????????? }?
??????????????? var head = document.getElementsByTagName( "head" )[0];
??????????????? if( head )?
??????????????? {?
??????????????????? head.appendChild( element );?
??????????????? }????????
??????????? }?
??????? }?
??? }?
}?
以上代碼中,還有一點要注意的,就是一定先要將container節(jié)點append到DOM中,也就是一定要先落地。不然,在javascript執(zhí)行順序上會有些問題的。?
好了,就到這吧。搞WEB開發(fā),真是很煩啊!!!
下面是一段示例代碼:?
__cb_render : function( containerId, htmlContent )?
{?
??? var oDiv = document.getElementById( containerId );?
??? while( oDiv.childNodes.length > 0 )?
??? {?
??????? oDiv.removeChild( oDiv.firstChild );?
??? }?
??? try?
??? {?
??????? var container = document.createElement( "div" );?
??????? container.innerHTML = htmlContent;?
??????? oDiv.appendChild( container );?
??? }?
??? catch ( error )?
??? {?
??????? // ignore exception?
??? }?
}?
這段代碼很簡單,將soap返回的html代碼插入到頁面的一個Div容器里。在firefox里執(zhí)行,okay,一切都沒問題。html代碼里的Javascript也能正確得以執(zhí)行。但在IE瀏覽器里,很抱歉,一堆問題就來了。?
首先,如果返回的html代碼以<script開頭,哪IE瀏覽器會直接忽略這些Javascript片斷(很奇怪吧,你可以試試。)。而且,中間的Javascript代碼根本得不到正確執(zhí)行,還有就是采用<script src="test.js"/>這種方式引入Javascript函數(shù),也無法成功。?
所以,對IE瀏覽器,我們就需要采取一些特殊的解決方案。有一種解決方案,是強行在每個script tag中添加一個屬性<script defer="true"......。Defer屬性是指瀏覽器先load完所有html代碼,然后去執(zhí)行相應的Javascript函數(shù)。這種解決方案,一般情況下也能得到正確的結果。但筆者并不推薦,盡量少用defer屬性。?
以下是另一可行的解決方案,也經(jīng)過了多種主流瀏覽器的測試。?
__cb_render : function( containerId, htmlContent )?
{?
??? var oDiv = document.getElementById( containerId );?
??? while( oDiv.childNodes.length > 0 )?
??? {?
??????? oDiv.removeChild( oDiv.firstChild );?
??? }?
??? if( BrowserUtility.isIE( ) )?
??? {?
?????? // 在html代碼開頭添加一段空白代碼,主要是為了解決script放在開頭而被IE忽略的問題?
??????? htmlContent = '<span style="display: none"> </span>' + htmlContent;?
?????? // 去掉html代碼中script tag的defer屬性,防止函數(shù)被執(zhí)行兩次?
??????? htmlContent = htmlContent .replace(/<script(.*)defer([^\s|^>]*)([^>]*)>/gi,'<script$1$3>');?
??? }
??? try?
??? {?
??????? // 先將新的節(jié)點append到DOM中?
??????? var container = document.createElement( "div" );?
?????? container.innerHTML = htmlContent;?
?????? oDiv.appendChild( container );?
??? }?
??? catch ( error )?
??? {?
??????? // ignore exception?
??? }?
??? var scripts = container.getElementsByTagName( "script" );?
??? for( var i = 0; i < scripts.length; i++ )?
??? {?
??????? if( scripts[i].src )?
??????? {
??????????? // 添加script src到head中?
????????????? if( BrowserUtility.isIE( ) )?
??????????? {?
??????????????? var scriptObj = document.createElement( "script" );?
??????????????? scriptObj.setAttribute( "type", "text/javascript" );?
??????????????? scriptObj.setAttribute( "src", scripts[i].src );?
??????????????? var head = document.getElementsByTagName( "head" )[0];?
??????????????? if( head )?
??????????????????? head.appendChild( scriptObj );?
??????????? }
??????? }?
??????? else if ( scripts[i].innerHTML )?
??????? { ????
???????????? //? IE支持該方法去動態(tài)執(zhí)行javascript代碼?
???????????? if ( window.execScript )?
?????????????? window.execScript( scripts[i].innerHTML );?
??????? }?
??? }?
??? // 如果是safari或是KHTML瀏覽器,需要將html代碼中包含的css style代碼顯示的append到head中。?
??? if ( BrowserUtility.isSafari() || BrowserUtility.isKHTML() )?
??? {?
??????? var styles = container.getElementsByTagName("style");?
??????? for ( var i = 0; i < styles.length; i++ )?
??????? {?
??????????? var styleContent = styles[i].innerHTML;?
??????????? if ( styleContent )?
??????????? {?
??????????????? var element = document.createElement("style");?
??????????????? element.type = "text/css";?
??????????????? if ( element.styleSheet )?
??????????????? {?
??????????????????? element.styleSheet.cssText = styleContent;?
??????????????? }?
??????????????? else?
??????????????? {?
??????????????????? element.appendChild( document.createTextNode( styleContent ) );?
??????????????? }?
??????????????? var head = document.getElementsByTagName( "head" )[0];
??????????????? if( head )?
??????????????? {?
??????????????????? head.appendChild( element );?
??????????????? }????????
??????????? }?
??????? }?
??? }?
}?
以上代碼中,還有一點要注意的,就是一定先要將container節(jié)點append到DOM中,也就是一定要先落地。不然,在javascript執(zhí)行順序上會有些問題的。?
好了,就到這吧。搞WEB開發(fā),真是很煩啊!!!
轉載于:https://www.cnblogs.com/zzh/archive/2008/12/02/1345884.html
總結
以上是生活随笔為你收集整理的Javascript动态执行问题浅析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蓝桥杯第八届省赛JAVA真题----Ex
- 下一篇: DataGrid 功能实现收集(转)保留