项目接近尾声了,今天客户发过来一些Bug要求修改,80%的都是关于UI的,其中有一项是要求
iframe自适应不能有滚动条。结合网上的代码很容易就实现了在Ie下比较完美,其中就利用了
一个table的onresize事件。我们是做企业应用的经理要求我们IE下能够运行就可以了,加上
进度卡的紧所以没敢耽搁没有做兼容性方面的尝试。平时写惯了兼容程序很讨厌这种IEOnly的
东西所以回来后自己有写了一下。虽然平时很痛恨IE的各种离奇的Bug但这个onresize确真的蛮
实用的。好了自己先来一段,大家有什么好的想法请回复
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>模拟OnResize</title>
<style type="text/css">
.divTest{
width:30%;
height:300px;
border:1px solid #339966;
float:left;
margin-left:20px;
}
</style>
<script type="text/javascript">function $(sId){
return document.getElementById(sId);
}function sizeAdd(nChange){
var oDiv=$("div1");
oDiv.style.width=parseInt(oDiv.offsetWidth)+nChange+"px"
}function handleResize(e){
var evt=e||event;
var srcEl=evt.target||evt.srcElement;

srcEl.innerHTML=Math.random();
}
/*-------------------------------------------////
*浏览器不支持onresize则进行扫描
*/
(function(){
if(document.all){
return;
}

window.onload=function(){
window.setInterval(function(){
var tag,tags=document.body.getElementsByTagName("*");
var resizeSet,oldW,oldH,newW,newH;
var _this,_event;

for(var i=0,len=tags.length;i<len;i++){
tag=tags[i];
resizeSet=tag.getAttribute("onresize");

if(resizeSet){
oldW=tag.getAttribute("oldW");
oldH=tag.getAttribute("oldH");
newW=parseInt(tag.offsetWidth);
newH=parseInt(tag.offsetHeight);

if(oldW &&oldH&&((oldW!=newW)||(oldH!=newH))){
try{
_this=tag;
_event={
srcElement:tag,
target:tag
};
resizeSet=resizeSet.replace(/(this|event)(?!=\w+)/g,"_$1");
eval(resizeSet);
}catch(e){}
}

tag.setAttribute("oldW",newW);
tag.setAttribute("oldH",newH);
}
}

},200);
};
})();
</script>
</head>
<body><input type="button" value="+" onclick="sizeAdd(20,20)"/>
<input type="button" value="-" onclick="sizeAdd(-20,-20)"/><br/>
<div id="div1" class="divTest" onresize="this.innerHTML=Math.random();">
</div><div id="div2" class="divTest" onresize="handleResize(event);">
</div></body>
</html>

解决方案 »

  1.   

    其他浏览器大部分都支持对窗口resize事件的支持,所以在窗口resize的时候调整相关的元素应该就好了吧
      

  2.   

    好多时候利用窗口的onresize是不够的。onresize只是在窗口尺寸改变时才发生,但有时候我们需要根据
    窗口内容的变化来做一些事情,比如使iframe自适应等等。从下面的例子你可以看到window.onresize的一些
    局限
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>无标题文档</title>
    <script type="text/javascript">
    function showDiv(){
    var oDiv=document.getElementById("div1");
    oDiv.style.display=oDiv.style.display=="none"
                      ?"":"none";   
    }window.onresize=function(){
    alert(1);
    }
    </script>
    </head>
    <body>
    <input type="button" value="显示" onclick="showDiv()"/>
    <div id="div1" style="width:100%;height:900px;border:1px solid #339966;display:none"></div>
    </body>
    </html>
      

  3.   

    都是客户的“合理”要求吧,呵呵,感觉在网页上用onresize和onscroll之类的不好
      

  4.   

    这个需求还是非常合理的,滚动条套滚动条是不能容忍的。onresize onscroll都会
    很频繁的触发,确实应该少用,但存在就有存在的道理
      

  5.   

    楼主例子里的需求没有碰到过,不过说到iframe高度自适应,传统的onload因为ajax的出现,iframe内的页面会因为非onload的情况下发生高度的改变,已经不太适用了,所以我的项目中只好用个interval来定时改变iframe的高度。
    function fitFrmHeight(o){
    try{
    var oWin = o.name ? window.frames[o.name] : o.contentWindow;
    if(MSIE) if(oWin.document.readyState == 'complete') o.style.height = oWin.document.body.scrollHeight+'px';
    if(Moz) o.style.height = oWin.document.documentElement.offsetHeight+'px';
    if(Opera) o.style.height = oWin.document.documentElement.scrollHeight+'px';
    if(Safari) o.style.height = oWin.document.documentElement.scrollHeight+'px';
    }catch(e){}
    }window.setInterval(function(){
    for(var i=0; i<Menu.Groups.length; i++){
    if(Menu.Groups[i].oDiv.style.display != 'none'){
    fitFrmHeight(Menu.Groups[i].oDiv.firstChild);
    break;
    }
    }
    }, 200);不用担心效率问题和CPU占用问题,经过测试在各种浏览器下CPU占用基本感觉不到。
      

  6.   

    还是跟我上面说的一样,内容变化是客户操作造成的,这里你进行了AJAX更新,那么在AJAX状态变化到4,也就是新内容下载完毕的时候,你就知道内容要变化了,为什么不在这里调整iframe高度呢?虽然对于现在的计算机来说一般可能感觉不到,但是当应用复杂了之后还是会很明显的,特别是大规模应用JS的情况下。
      

  7.   

    在每个调用AJAX的地方都进行一次高度计算,是否有点别扭的感觉?
      

  8.   

    我的意思不是把一份代码copy/paste得到处都是啊。计算高度的代码可以做成一个函数,每次进行完可能改变高度的AJAX操作,都调一下就好了。就算次数多,也是无法避免的。总比每200ms调用一次来得划算吧?
    而且如果你的应用达到一定规模,通常对AJAX操作也是会有一层封装的,那么在你封装AJAX的地方调用一下高度调整函数就好了。个人来说我一般会在封装的地方顺便提供一个事件驱动机制,提供一系列诸如onInit, onLoading, onSuccess, onFailure之类的事件,如果哪个AJAX需要调整高度,就自己订阅相关的事件去调用调整函数。这样可以控制得更精确,减少不必要的操作。
    最后对于iframe个人是比较反感的,很多UI设计师都推荐尽量少用。当然如LZ所说,存在的就是有道理的(高中班主任也经常这么说,好怀旧啊~~)。总之少用吧。
      

  9.   

    楼主就别费心了w3c里标明其他浏览器支持onresize事件
    http://www.w3school.com.cn/htmldom/dom_obj_event.asp
      

  10.   

    window.onresize大家都会用,可以现在需要处理的是div table这些元素的onresize事件
      

  11.   

    还是定时指定一次iframe的高度好,方便点,有些像onmouseover事件,ajax等要做到每一次都触发调整窗口的事件代码会很难看.定时是在客户端完成的,对客户端用户来说是基本感觉不到的
      

  12.   

    to 15楼,
    反正造成这些东西尺寸变化的是用户操作,而用户的操作最终要引起变化始终要经你的手。所以说到底改变这些元素的是你,理论上说你肯定会有合适的时机去调整这些元素,不需要依靠onresize这样的事件。只是要看你的代码怎么设计了,弄得不好就是乱七八糟一堆,绕进去了就出不来。
    to 16楼,
    做到AJAX完成时触发代码并不一定会很难看,相反是很基本的。举例来说Prototype和jQuery之类的库都对AJAX进行了封装,上面这样的应用直接用这些库都会很简单,还没到需要自己封装的地步。Web2.0发展下去对JS的要求是没有止境的,能省则省不应该是做程序员的基本追求吗?说下去又感觉我在装B了……实话实说,没有针对任何人的意思。做程序员的就追求这点效率!
      

  13.   


    用扫描的确不如事件触发来的高效。但是你想过如下的场景你如何做到添加事件处理呢:
    1.你的页面上有一个用第三方UI框架比如Ext、YUI生成的TableTree
    2.生成的TabelTree被放到一个Div里边Div的宽度是按百分比定位的会随着窗口的大小而改变
    3.页面左侧有个菜单可以缩起来,这时右侧iframe的宽度会变化进而Div会变化TableTree会变化
    4.TabelTree中有的内容会很长有也可能会换行这时候如果你用添加事件来处理的话会异常复杂,因为需要检测的地方太多了
    窗口尺寸的变化 TableTree的展开 收缩等等,而如果用定期扫描就简单多了
      

  14.   

    那么总结一下, 引起div变化的就三处地方吧? onresize, 菜单折叠, 还有div里的内容变化的时候. 调整代码是公用的, 那只要在这三处地方调用就行了, 哪里复杂呢?我有什么遗漏吗?
      

  15.   


    如果现在需要做一个模拟弹窗的DIV 而这个DIV需要指定父元素
    根据父元素的大小来改变自己的大小
    而父元素是创建这个窗体的时候动态传入的现在你说应该怎么处理?