Ajax已经如日中天,很多Ajax的框架让我们已经能轻松享受Ajax技术的美妙。不过Ajax也有美中不足。如果我们使用jQuery的话,用Ajax进行一个异步的调用,我们会发现一个小问题,如果请求一个以GB2312编码的页面,更新后的结果就会是乱码。无论是在FF还是在IE上都是如此:
2 $.get(“URL”, function (data) {
3 $(“#content”).html(data);
4 });
5 </ script >
6 < div id =”content” />
其原因在于jQuery的Ajax只支持UTF-8编码。当我们传入GB2312编码时,在解码的过程中会出现问题。不过这对于动态页面来说,非常容易解决,在输出页面内容时转换成UTF-8编码即可。不过如果请求的是一个静态页面,或者是别人的页面,那么我们就没有太好的办法来使用Ajax了。
不过iframe倒是一个比较好的替代品,有经验的开发者都了解,把iframe的src属性指向另外一个URL就可以改变其中的内容,而且对编码并不敏感。但仍旧有一个问题就是iframe不能自动跟随内容的多少来调整其大小。
在网上搜“iframe 自适应”可以搜到很多自动调整iframe大小来适应内容量的JavaScript代码。不过这些代码或多或少有一些跨浏览器问题。在IE上,基本上都是可行的。而在FF上有些代码就失去了效力了:
2 var iframe = document.getElementById(id); // iframe id
3 if (document.getElementById){
4 if (iframe && ! window.opera){
5 if (iframe.contentDocument && iframe.contentDocument.body.scrollHeight){
6 iframe.height = iframe.contentDocument.body.scrollHeight;
7 } else if (iframe.Document && iframe.Document.body.scrollHeight){
8 iframe.height = iframe.Document.body.scrollHeight;
9 }
10 }
11 }
12 }
上面这段代码在IE上是没有问题的,而在FF3上就会出现问题:scrollHeight经常返回0,似乎FF3并不对iframe的内容计算其实际高度。不过如果你的用户只用IE,那么将就一下也算可以。如果你想做得更完美一些的话,这种“自适应”方法却有问题。
不过从上面的代码中,我们可以发现一点:既然可以得到iframe内容的body对象,就可以得到body的innerHTML!这样我们可以再加入一个div或者span标签,把body对象的innerHTML复制到div的innerHTML中。利用div的高度自适应,加上iframe的异步请求和编码不敏感的特性,就可以达到一个很好的效果。
JavaScript代码:
2 var content = document.getElementById(iframeID);
3 content.setAttribute( ' src ' , src);
4 }
5
6 function swipContent(src, to) {
7 document.getElementById(to).innerHTML = getIFrameContent(src);
8 }
9
10 function getIFrameContent(id){
11 var bobo = document.getElementById(id); // iframe id
12 if (document.getElementById){
13 if (bobo && ! window.opera){
14 if (bobo.contentDocument){
15 return bobo.contentDocument.body.innerHTML;
16 } else if (bobo.Document){
17 return bobo.Document.body.innerHTML;
18 }
19 }
20 }
21 }
HTML的代码:
2 < iframe id =”icontent” width ="600" height ="0" scrolling ="auto" frameborder ="0"
3 onload ="swipContent('icontent', 'dest')" ></ iframe >
4 < div id =”dest” />
随着UTF-8编码的逐渐流行,这种“绕圈子”的方法的用武之地就逐渐变少了。而随着找到解决方法的这一连串的过程至少给了我一个启示:有时候换个思路就好多了。如果在寻找iframe的高度自适应功能上,仅仅只盯住scrollHeight就会花费更多的时间而且找不到好的办法。而跳出iframe,换一种思路:把iframe当作一个Ajax引擎来实现异步调用的功能,就是另一片天地了。
在最后,也顺便说说,这种方法的问题:如果在iframe请求的页面中使用了主页面中未定义的CSS样式,那么上面这个移花接木的方法就会出现显示问题。至于解决方法,就是把iframe中的页面的CSS导入到主页面中。