DHTML 中的绝对定位

  下面的东西显示了在复杂的情况下,

  怎样最好地在一个Element的旁边显示某个DIV。

  当然,你可以滚动窗口,使这个按纽靠窗口的 左/上/右/下 的情况,观察菜单的弹出方位。

  全部代码:

  

复制代码 代码如下:
<table border=1 cellpadding=8 cellspacing=0>

  <tr><td>table1</td><td>table1</td></tr>

  <tr><td>table1</td><td>

  <div id=div1 style='position:absolute;background-color:wheat;padding:4px;'>

  div1 start

  <div id=div1button style='border:outset 2px;background-color:threedface;color:red;font-weight:bold;cursor:hand;padding:4px;'>

  ClickMe

  </div>

  div1 end

  </div>

  </td></tr>

  </table>

  <div style='height:100px'>-</div>

  <table border=1 cellpadding=8 cellspacing=0>

  <tr><td>table2</td><td>table2</td></tr>

  <tr><td>table2</td><td>

  <div id=div2 style='position:relative;left:24px;background-color:wheat;'>

  div2 start

  <div id=div2menu style='display:none;position:absolute;background-color:lightgrey;height:200px;width:120px;border:outset 1px;padding:4px'>

  div2menu<br>

  div2menu<br>

  div2menu<br>

  div2menu<br>

  div2menu<br>

  </div>

  div2 end

  </div>

  </td></tr>

  </table>

  <script language='jscript'>

  //get the position of a element ( by the scroll offset )

  function LostinetWebGetScrollPostion(e)

  {

  var b=e.document.body;

  if(e==b)return {left:0,top:0};

  with(e.getBoundingClientRect())

  {

  return {left:b.scrollLeft+left,top:b.scrollTop+top};

  }

  }

  //get the position of a element ( by the client offset )

  function LostinetWebGetClientPosition(e)

  {

  var b=e.document.body;

  if(e==b)return {left:-b.scrollLeft,top:-b.scrollTop};

  with(e.getBoundingClientRect())

  {

  return {left:left-b.clientLeft,top:top-b.clientTop};

  }

  }

  //get absolute or relative parent

  function LostinetWebGetStandParent(e)

  {

  for(var p=e.parentElement;p!=null;p=p.parentElement)

  {

  var sp=p.currentStyle.position;

  if(sp=='absolute'||sp=='relative')

  return p;

  }

  return e.document.body;

  }

  //calc the position of floate that relative to e

  function LostinetWebCalcPosition(floate,e)

  {

  var epos=LostinetWebGetScrollPostion(e);

  var spos=LostinetWebGetScrollPostion(LostinetWebGetStandParent(floate));

  var s=LostinetWebGetStandParent(floate);

  return {left:epos.left-spos.left-s.clientLeft,top:epos.top-spos.top-s.clientTop};

  }

  //get the best position to put the floate

  function LostinetWebAdjustMirror(floate,e,pos)

  {

  //c:Client,f:floate,e:e,p:floate's StandParent,m:Mirror

  var cw=e.document.body.clientWidth;

  var ch=e.document.body.clientHeight;

  var fw=floate.offsetWidth;

  var fh=floate.offsetHeight;

  var ew=e.offsetWidth;

  var eh=e.offsetHeight;

  var ecpos=LostinetWebGetClientPosition(e);

  var empos={left:ecpos.left+ew/2,top:ecpos.top+eh/2};

  var pcpos=LostinetWebGetClientPosition(LostinetWebGetStandParent(floate));

  var fcpos=LostinetWebGetClientPosition(floate);

  var fmpos={left:pcpos.left+pos.left+fw/2,top:pcpos.top+pos.top+fh/2};

  //left<-->right

  if( (fmpos.left<empos.left) ? ((fmpos.left-fw/2<0)&&((empos.left*2-fmpos.left)+fw/2<=cw)) : ((fmpos.left+fw/2>cw)&&((empos.left*2-fmpos.left)-fw/2>=0)) )

  fmpos.left=empos.left*2-fmpos.left;

  //top<-->bottom

  if( (fmpos.top<empos.top) ? ((fmpos.top-fh/2<0)&&((empos.top*2-fmpos.top)+fh/2<=ch)) : ((fmpos.top+fh/2>ch)&&((empos.top*2-fmpos.top)-fh/2>=0)) )

  fmpos.top=empos.top*2-fmpos.top;

  pos.left=fmpos.left-pcpos.left-fw/2;

  pos.top=fmpos.top-pcpos.top-fh/2;

  }

  document.attachEvent('onclick',function f()

  {

  if(div1button.contains(event.srcElement))return;

  if(div2menu.contains(event.srcElement))return;

  div2menu.runtimeStyle.display='none';

  });

  function div1button.onclick()

  {

  div2menu.runtimeStyle.display='block';

  var pos=LostinetWebCalcPosition(div2menu,div1button);

  pos.top+=div1button.offsetHeight;

  LostinetWebAdjustMirror(div2menu,div1button,pos);

  div2menu.runtimeStyle.left=pos.left;

  div2menu.runtimeStyle.top=pos.top;

  }

  </script>