我正在开发一个asp.net控件,我需要能够放入其他应用程序。该控件基本上是一个自定义下拉列表,其中在单击另一个元素时显示或隐藏div。
我遇到的问题是尝试让动态div在被点击的元素下方对齐。我写了一个javascript函数,从理论上讲,它允许我指定两个元素和所需的对齐,然后将第二个元素移动到与第一个元素相关的正确位置。
我有三个测试用例与我目前期望使用此控件的地方相关,我目前的标记和javascript在IE7的所有三种情况下都有效但在FF3.5和IE8标准模式下的一个案例失败。我已经玩了一段时间了,还没有找到解决问题的答案,而不会打破其中一个。 (请注意,90%以上的用户使用IE7进行IE8缓慢迁移)
我正在寻找除了向页面添加兼容性模式指令之外的任何建议,这确实解决了IE8中的问题,但如果可能的话,我更愿意使用替代方案,因为我可能无法始终控制使用它的位置。这是一个HTML文档,它说明了相关的标记和javascript以及测试用例。情况三是有问题的情况,而不是在输入元素下整齐地对齐,div垂直重叠并向右偏移相当于select元素宽度的距离。
(请注意,真实页面使用的重置样式表改编自Eric Meyer发布的,包括/省略此样式表对这些测试用例没有相关影响。)
<!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 :(得分:1)
由于父inline
的{{1}}显示,第三种情况正在分崩离析 - 据我所知,它会导致相对位置无效。
要测试这种情况,请使用float,这是一个工作示例: http://jsfiddle.net/yahavbr/estYF/1/
答案 1 :(得分:0)
感谢Shadow Wizard让我思考正确的方向。事实证明,当我清除顶部和左侧属性时,我的绝对定位元素不会移动到它们的0点。如果我在计算偏移差异之前将代码更改为显式地将它们放在0,0,那么一切都可以正常工作。
element2.style.top = "";
element2.style.left = "";
变为
element2.style.top = "0px";
element2.style.left = "0px";