现在web2.0/ajax大行其道,我们会经常碰到这种应用case:前端浏览器通过ajax发请求到后端,后端生成html代码返回,前端接收后将html代码插入一个div容器内。这个应用很普遍,一般情况下也不会有什么问题,特别是返回的是单纯的数据的情况下。但如果返回的html代码包含javascript函数或是css style定义,哪可能就会出现问题了。特别是在IE浏览器下(由此看出,IE浏览器真是垃圾!!真是WEB程序开发者的噩梦啊。),Javascript动态执行的问题很突出。相对来说,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里执行,okay,一切都没问题。html代码里的Javascript也能正确得以执行。但在IE浏览器里,很抱歉,一堆问题就来了。
首先,如果返回的html代码以<script开头,哪IE浏览器会直接忽略这些Javascript片断(很奇怪吧,你可以试试。)。而且,中间的Javascript代码根本得不到正确执行,还有就是采用<script src="test.js"/>这种方式引入Javascript函数,也无法成功。
所以,对IE浏览器,我们就需要采取一些特殊的解决方案。有一种解决方案,是强行在每个script tag中添加一个属性<script defer="true"......。Defer属性是指浏览器先load完所有html代码,然后去执行相应的Javascript函数。这种解决方案,一般情况下也能得到正确的结果。但笔者并不推荐,尽量少用defer属性。
以下是另一可行的解决方案,也经过了多种主流浏览器的测试。
__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属性,防止函数被执行两次
htmlContent = htmlContent .replace(/<script(.*)defer([^\s|^>]*)([^>]*)>/gi,'<script$1$3>');
}
try
{
// 先将新的节点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支持该方法去动态执行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节点append到DOM中,也就是一定要先落地。不然,在javascript执行顺序上会有些问题的。
好了,就到这吧。搞WEB开发,真是很烦啊!!!
分享到:
相关推荐
浅析JavaScript的安全性和执行效率.pdf
Javascript自执行匿名函数(function() { })()的原理浅析_.docx
javascript和其他编程语言相比比较随意,所以javascript代码中充满各种奇葩的写法,有时雾里看花; 当然,能理解各型各色的写法也是对javascript语言特性更进一步的深入理解。 JavaScript 函数语法 函数就是包裹在花...
下面小编就为大家带来一篇浅析javascript异步执行函数导致的变量变化问题解决思路。小编觉得挺不错的,现在分享给大家,也给大家做个参考
大家有没有想过,一段javascript脚本从载入浏览器到显示执行都经过了哪些流程,其执行次序又是如何。本篇博文将引出'javascript执行模型'的概念,并带领大家理解javascript在执行时的处理机制。
[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行] 当某一天,我们知道JavaScript要跟HTML结构实现分离后,就会改了一种写法: test [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行] 当我们工作越来越久后,有时候...
主要介绍了JavaScript异步加载浅析,本文讲解了脚本延迟执行、脚本的完全并行化、可编程的脚本加载等内容,需要的朋友可以参考下
JavaScript 采用词法作用域(lexical scoping),函数执行依赖的变量作用域是由函数定义的时候决定,而不是函数执行的时候决定,通过本文给大家介绍JavaScript作用域链、执行上下文与闭包相关知识,感兴趣的朋友一起...
大家应该都只奥javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面。网上关于JavaScript的变量声明提升问题的文章有很多,这篇文章将再次谈谈关于这...
匿名函数就是没有函数名的函数。这篇文章主要介绍了Javascript自执行匿名函数(function() { })()的原理浅析的相关资料,需要的朋友可以参考下
简单的说就是通过addJavascriptInterface给WebView加入一个JavaScript桥接接口,JavaScript通过调用这个接口可以直接操作本地的JAVA接口。该漏洞最早公布于CVE-2012-6636【1】,其描述了WebView中addJava
JavaScript的变量声明语句无论出现在何处,都会先于其他代码首先被执行。使用var关键词声明变量的作用域是当前的执行上下文,有可能是外围函数,或者,当变量声明在函数体之外时,则为全局变量。 定义在函数体外的都...
在实际编码中,我们经常会遇到Javascript代码异步执行的场景,比如ajax的调用、定时器的使用等,在这样的场景下也经常会出现这样那样匪夷所思的bug或者糟糕的代码片段,那么处理好你的Javascript异步代码成为了异步...
JavaScript是种脚本语言,它可以用来制作与网络无关的,与用户交互作用的复杂软件。它是一种基于对象(Object Based)和事件驱动(Event Driver)的编程语言。因而它本身提供了非常丰富的内部对象供设计人员使用。2....