2011-03-22 112 views
1

我正在开发一个需要能够放入其他应用程序的asp.net控件。该控件基本上是一个自定义下拉列表,其中一个div在单击另一个元素时显示或隐藏。绝对定位中断在IE8中

我遇到的问题是试图让动态div对齐被点击的元素下方。我写了一个javascript函数,它理论上应该允许我指定两个元素和所需的对齐,然后将第二个元素移动到与第一个元素相关的正确位置。

我有三个测试用例,它们与我目前所期望的这个控件将被使用的地方有关,我的所有三种情况下我的当前标记和JavaScript工作对于IE7,但对于FF3.5和IE8标准中的一种情况失败模式。我一直在玩这个游戏一段时间,还没有拿出一个解决问题的答案,而没有打破其他问题。 (请注意,我的用户有90%以上在IE7上,并且向IE8缓慢迁移)

我正在寻找除了向页面添加兼容模式指令之外的任何建议,它确实解决了IE8中的问题,但我更愿意如果可能的话可以选择,因为我可能无法控制使用的位置。这里是一个HTML文档,它说明了相关的标记和JavaScript以及测试用例。第三种情况是存在问题的,而不是在输入元素下整齐排列,div垂直重叠,并向右偏移与选择元素宽度相等的距离。

(注意,真正的页面使用改编自一个由埃里克·迈耶出版,包括/忽略这个样式表重置样式表对这些测试用例没有相关的影响。)

<!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> 
    <title></title> 
</head> 
<body> 
<script type="text/javascript"> 
    var VAlign = { "top": -1, "center": 0, "bottom": 1 }; 
    var HAlign = { "left": -1, "center": 0, "right": 1 }; 
    function AlignElements(element1, vAlign1, hAlign1, element2, vAlign2, hAlign2) { 
     var List1 = BuildOffsetList(element1); 
     var List2 = BuildOffsetList(element2); 
     var Index1 = List1.length - 1; 
     var Index2 = List2.length - 1; 

     while (Index1 >= 0 && Index2 >= 0 && List1[Index1] == List2[Index2]) { 
      Index1--; 
      Index2--; 
     } 

     element2.style.top = ""; 
     element2.style.left = ""; 

     var OT1 = 0; 
     var OL1 = 0; 
     var OT2 = 0; 
     var OL2 = 0; 

     while (Index1 >= 0) { 
      OT1 += List1[Index1].offsetTop; 
      OL1 += List1[Index1].offsetLeft; 
      Index1--; 
     } 

     while (Index2 >= 0) { 
      OT2 += List2[Index2].offsetTop; 
      OL2 += List2[Index2].offsetLeft; 
      Index2--; 
     } 

     var top = (OT1 - OT2); 
     if (vAlign1 == VAlign.bottom) { 
      top += element1.offsetHeight; 
     } else if (vAlign1 == VAlign.center) { 
      top += (element1.offsetHeight/2); 
     } 
     if (vAlign2 == VAlign.bottom) { 
      top -= element2.offsetHeight; 
     } else if (vAlign2 == VAlign.center) { 
      top -= (element2.offsetHeight/2); 
     } 

     var left = (OL1 - OL2); 
     if (hAlign1 == HAlign.right) { 
      left += element1.offsetWidth; 
     } else if (hAlign1 == HAlign.center) { 
      left += (element1.offsetWidth/2); 
     } 
     if (hAlign2 == HAlign.right) { 
      left -= element2.offsetWidth; 
     } else if (hAlign2 == HAlign.center) { 
      left -= (element2.offsetWidth/2); 
     } 

     element2.style.top = top + "px"; 
     element2.style.left = left + "px"; 
    } 

    function BuildOffsetList(elelment) { 
     var I = 0; 
     var List = new Array(); 
     var Element = elelment; 
     while (Element) { 
      List[I] = Element; 
      Element = Element.offsetParent; 
      I++; 
     } 
     return List; 
    } 
</script> 
Case 1 
<div> 
    <div id="control1" style=" display:inline; position:relative;"> 
     <div id="control1_div1" style="background-color:Blue; height:75px; width:150px; position:absolute;"></div> 
     <input id="control1_txt1" type="text" style="width:150px;" /> 
     <script type="text/javascript"> 
      AlignElements(document.getElementById("control1_txt1"), VAlign.bottom, HAlign.left, document.getElementById("control1_div1"), VAlign.top, HAlign.left); 
     </script> 
    </div> 
</div> 
<div style="height:100px;"></div> 
Case 2 
<div> 
    <div id="Nav" style="float:left; width:200px; height:150px; background-color:Aqua;"></div> 
    <div id="Content" style="margin-left:200px; height:150px; background-color:#ddd;"> 
     <div style="margin-left:100px;"> 
      <h5 style="float:left; margin-left:-100px; width:90px; margin-right:10px; text-align:right; font-weight:.9em;">Label</h5> 
      <div id="control2" style=" display:inline; position:relative;"> 
       <div id="control2_div1" style="background-color:Blue; height:75px; width:150px; position:absolute;"></div> 
       <input id="control2_txt1" type="text" style="width:150px;" /> 
       <script type="text/javascript"> 
        AlignElements(document.getElementById("control2_txt1"), VAlign.bottom, HAlign.left, document.getElementById("control2_div1"), VAlign.top, HAlign.left); 
       </script> 
      </div> 
     </div> 
    </div> 
</div> 
<div style="height:100px;"></div> 
Case 3 
<div> 
    <select><option>something</option></select> 
    <br /> 
    <select><option>something else</option></select> 
    <div id="control3" style=" display:inline; position:relative;"> 
     <div id="control3_div1" style="background-color:Blue; height:75px; width:150px; position:absolute;"></div> 
     <input id="control3_txt1" type="text" style="width:150px;" /> 
     <script type="text/javascript"> 
      AlignElements(document.getElementById("control3_txt1"), VAlign.bottom, HAlign.left, document.getElementById("control3_div1"), VAlign.top, HAlign.left); 
     </script> 
    </div> 
</div> 
</body> 
</html> 
+0

使用jQuery它应该是更容易放置元素之外/低于其他元素..这是给你的一个有效的选择吗? – 2011-03-22 18:04:18

+0

我无法控制所有这将被使用,所以我努力留在标准的JavaScript领域。如果一切都失败了,我可能会逃避导入另一个库来构建,但我宁愿避免它。 – Rozwel 2011-03-22 18:18:37

回答

0

感谢阴影向导让我在正确的方向思考。原来问题是,当我清除顶部和左侧属性时,绝对定位的元素不会移动到0,0点。如果在计算偏移量差异之前将代码更改为明确地将它们设置为0,0,那么所有内容都可以很好地工作。

element2.style.top = ""; 
    element2.style.left = ""; 

成为

element2.style.top = "0px"; 
    element2.style.left = "0px"; 
1

第三种情况由于父母divinline显示正在分解 - 据我所知,它导致相对位置无效。

为了测试这种情况下使用浮动,而不是,这里是工作示例: http://jsfiddle.net/yahavbr/estYF/1/

+0

漂浮会导致需要使用这些页面上的问题,但要让我的大脑进入正确的轨道。 – Rozwel 2011-03-23 12:50:42

+0

Cheers @Rozwel,感谢您分享“真正的”解决方案! :) – 2011-03-23 13:00:44