Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Чудеса математики js при padding (https://javascript.ru/forum/dom-window/18640-chudesa-matematiki-js-pri-padding.html)

borovik 09.07.2011 19:34

Чудеса математики js при padding
 
привет, есть код выдвижной менюшки.

<div><a href="javascript:col()" id="tit">Скрыть</a></div>

<div id="div" style="margin: 0px 15px">
   много текста
</div>


<script type="text/javascript">
  var div = document.getElementById("div");
       
function col(){
    if (div.clientHeight >= step){
        div.style.height = div.clientHeight-1;
        setTimeout("col()",10);
    }
} 
</script>


всё это дело отлично медленно скрывается всё ок.
но как только добавляю параметр padding
<div id="div" style="margin: 0px 15px; padding: 3px">
при нажатии на кнопку, вся менюшка начинает бесконечно открываться вниз Оо, что за чудеса?
вставил алерт
function col(){
    var step = 1;
    [B]alert(div.clientHeight);[/B]
    if (div.clientHeight >= step){
        div.style.height = div.clientHeight-2;
        setTimeout("col()",10);

и выяснил что математичка "-" не работает, выводит 88,90,92,94....
что за бредятина. Повторяю что при удалении padding всё идеально работает.

дефолт

при нажатии (в действии) постепенно скрывается всё ок

вот применяю паддинг, как видно паддинг применяться

и вот баг, при нажатии пошло бесконечное увеличение (в действии)

Amphiluke 09.07.2011 19:54

Всё очень даже логично. Добавляемые padding`и идут в счет общего увеличения высоты контейнера. Свойства типа clientHeight и offsetHeight считают с учетом всех padding`ов, а CSS свойство height — нет, поэтому результирующая выстота растет, несмотря на то, что вы пытаетесь ее уменьшать. Для того, чтобы восстановить нормальный порядок анимации, вам нужно самому учесть наличие padding`ов и вычитать их тоже при анимации.


P.S. И, кстати, не забывайте об единицах измерения, когда устанавливате значение div.style.height

borovik 09.07.2011 20:05

Amphiluke,
padding 12px;
в функции
div.style.height = div.clientHeight-1-24+"px";

как правильно рассчитать? у меняже рекурсия 12+12 каждый раз вычитать будет не правильно

Amphiluke 09.07.2011 20:09

Почему это неправильно? У вас padding`и-то постоянные. Вот вы и вычитаете эту постоянную величину

borovik 09.07.2011 20:14

так например есть 100px ; padding 20px;
надо их один раз вычисть получить 60px и уже потом по -1 в рекурсии, поулчается ~60проходов,
а если по вашему в каждой рекурсии будет отсекаться по 40px; ~2прохода

Amphiluke 09.07.2011 20:25

<div><a href="javascript:col()" id="tit">Скрыть</a></div>
	<div id="div" style="margin: 0px 15px; border:1px solid; padding:12px; overflow:hidden;">
	   много текста<br/>
	   много текста<br/>
	   много текста<br/>
	   много текста<br/>
	   много текста<br/>
	   много текста<br/>
	   много текста<br/>
	   много текста<br/>
	   много текста<br/>
	   много текста<br/>
	   много текста<br/>
	   много текста<br/>
	   много текста<br/>
	   много текста<br/>
	   много текста<br/>
	   много текста<br/>
	   много текста<br/>
	   много текста<br/>
	   много текста<br/>
	</div>
<script type="text/javascript">
  var div = document.getElementById("div");
        
function col(){
    var step = 1;
    if (div.clientHeight >= step){
        div.style.height = div.clientHeight-1-24+"px";
        setTimeout("col()",10);
    }
}
</script>


Если вы проанализируете, что происходит, то поймете, почему так. Вы анимируете уменьшение по 1px только значения высоты, а padding`и остаются постоянной величиной. Поэтому ваш код будет себя неправильно вести, когда менюха свернется до нулевой высоты, точнее по достижении нулевого значения div.style.height. При этом ваш код, который считывает по таймеру значение свойства clientHeight, будет пытаться далее уменьшать высоту в отрицательные области, поскольку наличие постоянных padding`ов не даст свойству clientHeight уменьшаться до значений меньших суммы paddingTop + paddingBottom.
Если вы откроете консоль, то увидите, как растет число ошибок CSS, при попытке установки отрицательной высоты.
Чтобы этого избежать, вам так же надо останавливать анимацию по достижении высоты 24px или же анимировать уменьшение padding`ов, как это делает jQuery.


P.S. Еще раз повторю, если с первого раза было непонятно:
div.style.height = clientHeight − paddingTop − paddingBottom

borovik 09.07.2011 22:02

большое спс, разобрался, трабл был в "сумме информативных переменных". щас покрутил понял их строение )


Часовой пояс GMT +3, время: 07:20.