【问题标题】:Absolute positioning breaks in IE8IE8中的绝对定位中断
【发布时间】:2011-03-23 20:54:56
【问题描述】:

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

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

我有三个测试用例,它们与我目前预计将使用此控件的地方有关,我当前的标记和 javascript 在 IE7 的所有三种情况下都有效,但在 FF3.5 和 IE8 标准模式下的其中一种情况下失败.我已经玩了一段时间了,但还没有想出一个解决问题的答案,而不会破坏其他案例。 (请注意,我 90+% 的用户使用 IE7,向 IE8 迁移缓慢)

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

(请注意,实际页面使用了改编自 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>

【问题讨论】:

  • 使用 jQuery 应该更容易将元素放置在其他元素的旁边/下面。这对您来说是一个有效的选择吗?
  • 我无法控制将要使用它的所有地方,因此我正在努力保持在标准 javascript 的领域。如果一切都失败了,我可能会导入另一个库来构建,但我更愿意避免它。

标签: javascript css internet-explorer-8 css-position


【解决方案1】:

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

要测试这种情况,请改用 float,下面是工作示例: http://jsfiddle.net/yahavbr/estYF/1/

【讨论】:

  • 浮动会在需要使用它的页面上引起问题,但会让我的大脑走上正确的轨道。
【解决方案2】:

感谢影子向导让我朝着正确的方向思考。事实证明,问题是当我清除顶部和左侧属性时,我的绝对定位元素不会移动到它们的 0,0 点。如果我在计算偏移差之前更改代码以明确地将它们置于 0,0,那么一切都会很好地工作。

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

变成

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-18
    • 1970-01-01
    相关资源
    最近更新 更多