Абсолютные разрывы позиционирования в IE8 - PullRequest
1 голос
/ 22 марта 2011

Я работаю над разработкой элемента управления asp.net, который мне нужно иметь, чтобы я мог добавить его в другие приложения. Элемент управления - это в основном пользовательский выпадающий список, в котором элемент div отображается или скрывается при нажатии другого элемента.

Проблема в том, что я пытаюсь заставить динамический div выравниваться под элементом, по которому щелкают. Я написал функцию javascript, которая теоретически должна позволить мне указать два элемента и желаемое выравнивание, а затем переместить второй элемент в правильное положение относительно первого элемента.

У меня есть три тестовых случая, которые относятся к местам, где я ожидаю, что этот элемент управления будет использоваться, моя текущая разметка и javascript работают во всех трех случаях для IE7, но в одном из случаев в режиме стандартов FF3.5 и IE8 не удается , Я играл с этим некоторое время и до сих пор не нашел ответа, который исправит проблему, не сломав ни одну из других. (Обратите внимание, что более 90% моих пользователей используют IE7 с медленным переходом на IE8)

Я ищу любые предложения, кроме добавления директивы режима совместимости на страницу, которая исправляет вещи в IE8, но я бы предпочел альтернативу, если она возможна, так как я не всегда могу контролировать, где это используется. Вот документ HTML, который иллюстрирует соответствующую разметку и javascript вместе с контрольными примерами. В третьем случае возникают проблемы: вместо аккуратного выравнивания под входным элементом div перекрывается по вертикали и смещается вправо на расстояние, эквивалентное ширине элемента select.

(Обратите внимание, что реальные страницы используют таблицу стилей сброса, адаптированную из таблицы, опубликованной Эриком Мейером, в том числе / опуская эту таблицу стилей, не имеет никакого отношения к этим тестовым случаям.)

<!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>

Ответы [ 2 ]

1 голос
/ 23 марта 2011

Третий случай разваливается из-за отображения inline родительского div - насколько я знаю, относительная позиция не имеет никакого эффекта.

Чтобы проверить такой случай, используйте вместо этого float, вот рабочий пример: http://jsfiddle.net/yahavbr/estYF/1/

0 голосов
/ 23 марта 2011

Спасибо Shadow Wizard за то, что заставил меня задуматься в правильном направлении. Оказывается, проблема в том, что мои абсолютно позиционированные элементы не перемещаются в свои 0,0 точки, когда я очищаю свойства top и left. Если я изменю код, чтобы явно установить их в 0,0, прежде чем вычислять разницу смещений, все будет прекрасно работать.

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

становится

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