Отображение: нет на элементе контейнера нарушает вычисление абсолютного позиционирования jquery дочерних дочерних элементов

#jquery #html #css

#jquery #HTML #css

Вопрос:

HTML:

 <a href="" id="show_link">Show</a><div id="container">
<form class="form">
    <a href="" class="align_middle">Link1</a>
</form>
<form class="form">
    <a href="" class="align_middle">Link2</a>
</form>
<form class="form">
    <a href="" class="align_middle">Link3</a>
</form>
  

Javascript:

 var align_middle = function(element) {

    var sidePadding = 20;

    $(element).css("position", "static");
    $(element).css("float", "left");
    $(element).css("width", "auto");

    var width = $(element).width();
    var parentWidth = $(element).parent().width();

    width = Math.min(width, parentWidth - sidePadding*2);
    $(element).css("width", width);

    var height = $(element).height();
    var parentHeight = $(element).parent().height();
    var top = (parentHeight - height)/2;
    var left = (parentWidth - width)/2;

    $(element).css("position", "absolute");
    $(element).css("left", left   "px");
    $(element).css("top", top   "px");

    $(element).css("float", "");
};

$(document).ready(function(){

    var elements = $(".align_middle");

    $.each(elements, function(key,value){
            align_middle(value);
    });

    $(elements).bind("DOMNodeInserted",function(){
            align_middle(this);
    });


    $("#show_link").click(function(event){
            event.preventDefault();
            $("div#container").toggle();
    });

});
  

CSS:

 .form {
    position: relative;
    border-color: brown;
    border-width: 3px;
    border-style: dotted;
    width: 150px;
    height: 150px;
    float:left;
    margin-left: 10px;
    overflow: hidden;
}
div#container{
    overflow: auto;
    margin-top: 10px;
}
  

Я хочу скрыть контейнер div # с помощью свойства css display: none; поэтому он скрыт при загрузке страницы, но он нарушает функцию align_middle .

Когда я скрываю элементы с помощью функции обратного вызова $.get, она отлично работает. (Ссылка переключения также работает.)

Почему он так себя ведет?

Скрипка: http://jsfiddle.net/7PELA/3 /

Комментарии:

1. вы буквально скрываете элемент, как вы ожидаете, что он будет себя вести? не могли бы вы еще немного разгадать загадку?

2. Может быть, мне следует обновить скрипку, чтобы показать, как она ломается? Если я добавлю display: none; в css для div #container Link1, Link2 и Link3 больше не центрируются..

Ответ №1:

Свойство CSS display:none; с точки зрения DOM полностью удаляет или не обрабатывает элемент в браузере, поэтому jQuery не может правильно вычислить то, что ему нужно. Скорее используйте свойство Visibility в CSS и установите для него значение hidden .

Обновленный HTML:

 <a href="" id="show_link">Show</a>
<div id="container" class="hide">
    <form class="form">
        <a href="" class="align_middle">Link1</a>
    </form>
    <form class="form">
        <a href="" class="align_middle">Link2</a>
    </form>
    <form class="form">
        <a href="" class="align_middle">Link3</a>
    </form>
</div>
  

Обновленный CSS:

 .form
{
position:relative;
border-color:brown;
border-width:3px;
border-style:dotted;
width: 150px;
height: 150px;
float:left;
margin-left:10px;
overflow:hidden;
}

div#container
{
overflow:auto;
margin-top:10px;
}

.hide {
    visibility:hidden;
}
  

Обновленный jQuery:

 var align_middle = function(element){

    var sidePadding = 20;

    $(element).css("position", "static");
    $(element).css("float", "left");
    $(element).css("width", "auto");

    var width = $(element).width();
    var parentWidth = $(element).parent().width();

    width = Math.min(width, parentWidth - sidePadding*2);
    $(element).css("width", width);

    var height = $(element).height();
    var parentHeight = $(element).parent().height();
    var top = (parentHeight - height)/2;
    var left = (parentWidth - width)/2;

    $(element).css("position", "absolute");
    $(element).css("left", left   "px");
    $(element).css("top", top   "px");

    $(element).css("float", "");

};

$(document).ready(function(){

    var elements = $(".align_middle");

    $.each(elements, function(key,value){

        align_middle(value);

    });

    $(elements).bind("DOMNodeInserted",function(){
        align_middle(this);
    });


    $("#show_link").click(function(event){
        event.preventDefault();
        $("div#container").toggleClass('hide');
    });

});
  

Комментарии:

1. Спасибо, чувак, это отлично работает, а также объясняет причину.

Ответ №2:

как насчет этого? http://jsfiddle.net/7PELA/4 /

просто нужно немного $("#show_link").trigger('click'); после функции «click toggle» нет необходимости устанавливать display:none

Комментарии:

1. Это действительно работает. 🙂 Почему не работает использовать display:hidden; ?

2. честно говоря, я понятия не имею! 🙂 никогда не видел или не должен был искать такую проблему!

3. Смотрите Ответ Matts. В любом случае спасибо. 🙂