Ajax与iframe

    Ajax已经如日中天,很多Ajax的框架让我们已经能轻松享受Ajax技术的美妙。不过Ajax也有美中不足。如果我们使用jQuery的话,用Ajax进行一个异步的调用,我们会发现一个小问题,如果请求一个以GB2312编码的页面,更新后的结果就会是乱码。无论是在FF还是在IE上都是如此:

1 <script>
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倒是一个比较好的替代品,有经验的开发者都了解,把iframesrc属性指向另外一个URL就可以改变其中的内容,而且对编码并不敏感。但仍旧有一个问题就是iframe不能自动跟随内容的多少来调整其大小。

    在网上搜“iframe 自适应”可以搜到很多自动调整iframe大小来适应内容量的JavaScript代码。不过这些代码或多或少有一些跨浏览器问题。在IE上,基本上都是可行的。而在FF上有些代码就失去了效力了:

 1 function ResizeIFrame (id){
 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对象,就可以得到bodyinnerHTML!这样我们可以再加入一个div或者span标签,把body对象的innerHTML复制到divinnerHTML中。利用div的高度自适应,加上iframe的异步请求和编码不敏感的特性,就可以达到一个很好的效果。

JavaScript代码:

 1 function LoadContent(src, iframeID) {
 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的代码:

1 <href=”#” onclick=”LoadContent(‘URL’, ‘icontent’)”>Link Button</a>
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导入到主页面中。

posted on 2008-11-26 13:35  blacktear  阅读(11216)  评论(16编辑  收藏  举报