Изменение свойства CSS
Здравствуйте, уважаемые форумчане.
Проблема, вроде бы простая, но у меня её решить не получается. В JavaScript я не особо силён, поэтому не пинайте сильно. Есть 2 div блока. У обоих высота не задана, т.е. зависит от количества контента в них. Причём, у одного из блоков высота динамически меняется при нажатии на ссылку в нём. Требуется сделать так, чтобы высота блоков до раскрытия динамического блока была одинаковой (вот хочется заказчику так, и ничего он слушать не хочет). Я попытался решить проблему следующим образом: Код:
#contentMenuPersonal <script type="text/javascript"> function change_visibility (block_4_close, block_4_open) { document.getElementById(block_4_close).style.display='none'; document.getElementById(block_4_open).style.display=''; } var size = document.getElementById(contentMenuPersonal).style.height; var dynamicSize = document.getElementById(bannerBig1).style.height; if (document.getElementById(block_4_close).style.display='none') {dynamicSize = size;} </script> <div id="contentMenuPersonal"> <table cellspacing="10px" align="center"> ...текст... </table> </div> <div id="bannerBig1" style="padding: 15px;"> <div id="r0"> ...текст... <a href="javascript:change_visibility ('r0', 'r1')">Читать далее →</a> </div> <div id="r1" style="display: none;"> ...текст... <a href="javascript:change_visibility ('r1', 'r0')">← скрыть текст</a> </div> </div> Но ни в одном из браузеров вообще ничего не произошло. |
Squirr,
var dynamicSize = document.getElementById(bannerBig1).style.height; if (document.getElementById(block_4_close).style.disp lay='none') {dynamicSize = size;} красное числовое значение, -а не объект для объекта - так Цитата:
|
Deff, спасибо за помощь. Но ваш вариант работает только в FF.
Изменение конструкции на document.all.contentMenuPersonal.style.height тоже не помогло. |
Цитата:
document.getElementById("contentMenuPersonal")... идентификаторы в кавычки нужно ставить (contentMenuPersonal, bannerBig1), но не block_4_close, block_4_open 12 строка в первом посте в первом коде не будет работать if (document.getElementById(block_4_close).style.display='none') {dynamicSize = size;} block_4_close вне функции...вместо него нужно "r0" или "r1", и в условии нужно ставить не одно равно, а 2 if (document.getElementById("r0").style.display == 'none') {dynamicSize = size;} |
Цитата:
<style> #but {height: 50px} </style> <button id="but" onclick="alert(this.style.height)">click</button> <button style="height: 60px" onclick="alert(this.style.height)">click</button> |
а почему для получение высоты просто не использовать clientWidth, clientHeight ?
|
Цитата:
<style> button {padding: 2px} </style> <button onclick="this.style.height = this.clientHeight">click</button> |
вот , выдрал из скрипта своего
width_drag = drag.obj.offsetWidth + parseInt(getComputed(drag.obj).marginLeft); width_drag += parseInt(getComputed(drag.obj).marginRight); height_drag = drag.obj.offsetHeight + parseInt(getComputed(drag.obj).marginTop); height_drag += parseInt(getComputed(drag.obj).marginBottom); функция getComputed function getComputed (obj){ try{ return getComputedStyle(obj, null) } catch(e){ return obj.currentStyle; } }; |
Лично мне больше нравится такой вид
function getStyle(element) { if (window.getComputedStyle) { return window.getComputedStyle(element, null) } else { return element.currentStyle; } } Если величины будут не в px, то IE<9 не справится, нужно будет усложнять функцию дополнительными действиями по переводу из других единиц измерения + учесть случай, когда выдаётся значение auto. cyber, что нужно будет устанавливать, получив приведённые вами значения width_drag и height_drag? |
<style> button {padding: 2px} </style> <button onclick=" this.style.height = ( this.getBoundingClientRect().bottom - this.getBoundingClientRect().top ) + 'px'; alert( 'Высота элемента: ' + (this.getBoundingClientRect().bottom - this.getBoundingClientRect().top)) ">click</button> |
Цитата:
епт, а о переводе в старых ие я забыл |
Цитата:
|
Цитата:
|
Цитата:
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> <style> button {padding: 2px} </style> <button onclick=" this.style.height = ( this.getBoundingClientRect().bottom - this.getBoundingClientRect().top ) + 'px'; alert( 'Высота элемента: ' + (this.getBoundingClientRect().bottom - this.getBoundingClientRect().top)) ">click</button> |
Да, наверное это самый точный и простой способ, хотя погрешность есть (в хроме видно), но даже это прокатывает.
<style> button {padding: 21px; border: solid 5px;} </style> <button style="height: 43px" onclick=" var h = this.getBoundingClientRect().bottom - this.getBoundingClientRect().top; this.nextElementSibling.style.height = h;//не для IE alert(h +'; ' + this.style.height); "> click</button> <button disabled>click</button> |
хм...
getBoundingClientRect() возвращает результат без учета прокрутки, но в данном случае она и не важна. короче я затупил , сорри =) |
Всем спасибо за ответы :)
Высоту окна getBoundingClientRect() считает отлично, даже если она не была задана. Значит, то, что мне нужно решить с помощью JavaScript можно. Но не работает условие, которое я пишу. Подскажите, пожалуйста, знающие люди, что не так? function change_visibility (block_4_close, block_4_open) { document.getElementById(block_4_close).style.display='none'; document.getElementById(block_4_open).style.display=''; } var size = document.getElementById("contentMenuPersonal").style.height = ( document.getElementById("contentMenuPersonal").getBoundingClientRect().bottom - document.getElementById("contentMenuPersonal").getBoundingClientRect().top ) + 'px'; var dynSize = document.getElementById("bannerBig1").style.height = ( document.getElementById("bannerBig1").getBoundingClientRect().bottom - document.getElementById("bannerBig1").getBoundingClientRect().top ) + 'px'; if (document.getElementById("r0").style.display == 'none') {dynSize = size;} Остальной код из 1-го поста остался без изменений: #contentMenuPersonal { display: block; z-index: 10; position: relative; margin: 80px 10px 30px; float: left; width: 175px; } #bannerBig1 { width: 680px; z-index: 10; position: relative; margin: 80px 10px 30px; float: left; } <div id="contentMenuPersonal"> <table cellspacing="10px" align="center"> ...текст... </table> </div> <div id="bannerBig1" style="padding: 15px;"> <div id="r0"> ...текст... <a href="javascript:change_visibility ('r0', 'r1')">Читать далее →</a> </div> <div id="r1" style="display: none;"> ...текст... <a href="javascript:change_visibility ('r1', 'r0')">← скрыть текст</a> </div> </div> |
В данном примере способ почему-то не отрабатывает
<style> #content { margin: 80px 10px 30px; float: left; width: 100px; background: green; } #banner { width: 200px; margin: 80px 10px 30px; float: left; background: lightgreen; } </style> <div id="content"> <table cellspacing="10px" align="center"> ...текст... </table> </div> <div id="banner" style="padding: 15px;"> <div id="r0"> ...текст... <a href="#">Читать далее →</a> </div> <div id="r1" style="display: none;"> ...текст...<br> ...текст...<br> ...текст... <a href="#">← скрыть текст</a> </div> </div> <script> window.onload = function () { var banner = document.getElementById('banner'); var content = document.getElementById('content'); banner.onclick = function (e) { e = e || event; var target = e.target || e.srcElement; if (target.tagName == 'A') { if (target.parentNode == banner.children[0]) { banner.children[1].style.display = 'block'; banner.style.height = ''; } else { banner.children[1].style.display = 'none'; banner.style.height = (content.getBoundingClientRect().bottom - content.getBoundingClientRect().top) + 'px'; alert('content: ' + (content.getBoundingClientRect().bottom - content.getBoundingClientRect().top)); alert('banner: ' + (banner.getBoundingClientRect().bottom - banner.getBoundingClientRect().top)); } } } } </script> |
devote, как быть в этой ситуации, padding - явная проблема (хотя в примере с кнопкой прокатило), получается всё-таки getBoundingClientRect() - не лучшее решение.
Упрощённый пример <div id="content" style="background: green;"> text </div> <div id="banner" style="background: lightgreen; padding: 5px; overflow: hidden"> <div> click </div> <div> click </div> </div> <script> var banner = document.getElementById('banner'); var content = document.getElementById('content'); banner.onclick = function (e) { banner.style.height = (content.getBoundingClientRect().bottom - content.getBoundingClientRect().top) + 'px'; alert('content: ' + (content.getBoundingClientRect().bottom - content.getBoundingClientRect().top)); alert('banner: ' + (banner.getBoundingClientRect().bottom - banner.getBoundingClientRect().top)); } </script> |
Реакция на код в браузере появилась после того, как я скрипт переместил в сам div, который он должен изменять. На отдельно вынесенный js почему-то реакции не было. Но с getBoundingClientRect() всё равно не вышло: в разных браузерах высота разная, и ни в одном не та, которая нужна. Пресловутый padding всё портит, как мастера тут сказали.
|
И снова вынужден я обратиться к мудрости гуру. Проблема схожая, поэтому новую ветку заводить не стал.
На странице следующая конструкция из блоков: ![]() Блоки div#r0 и div#r1 сменяют друг друга при нажатии на ссылку и имеют разное количество контента (высота их не задана). Мне нужно добиться того, чтобы при нажатии на ссылку изменялась параметры "height" у div#content и "top" у div#bottom. Я написал следующий скрипт: <div id="content"> <table width="100%"> <tr><td> <div id="contentMenuPersonal"> <table> <tr><td class="contentMenu"><a href="/">Main</a></td></tr> ... </table> </div> <div id="bannerBig1"> <div id="r0"> <p>Текст</p> <a href="javascript:change_visibility ('r0', 'r1')">Читать далее →</a> </div> <div id="r1" style="display: none;"> <p>Текст</p> <a href="javascript:change_visibility ('r1', 'r0')">← скрыть текст</a> </div> </div> </td></tr> </table> <script type="text/javascript"> if (document.getElementById("r1").style.display = 'none') document.getElementById("content").style.height = "1100px"; else document.getElementById("content").style.height = "1484px"; </script> </div> <div id="bottom"> <script type="text/javascript"> document.getElementById("content").style.height = ( document.getElementById("content").getBoundingClientRect().bottom - document.getElementById("content").getBoundingClientRect().top ) + 'px'; var h = parseInt((document.getElementById("content").getBoundingClientRect().bottom - document.getElementById("content").getBoundingClientRect().top)); //if (h == 1484.8333740234375) if (h > 1450) { document.getElementById("bottom").style.top = "1620px"; } else { document.getElementById("bottom").style.top = "1275px"; } </script> </div> Я долго пытался его отладить, но пока не смог добиться нужного результата. Скрипт вынесен в сами блоки, потому что иначе он почему-то вообще не работал, как будто браузер его не видел. Функция смены видимости блоков "r0" и "r1" работает нормально, так же как и функция, которая меняет параметр "top" у div#bottom (проверено изменением условия). А вот параметр "height" у div#content никак изменить динамически не получается. |
Цитата:
<script type="text/javascript"> if (document.getElementById("r1").style.display = 'none') document.getElementById("content").style.height = "1100px"; else document.getElementById("content").style.height = "1484px"; </script> поставьте == и если изначально свойство height у элемента content не задано, то вы не сможете его изменить |
lord2kim, да, я постоянно забываю ставить равенство в условии вместо присваивания. Высоту div#content я попробовал задать разными способами, но никакого результата не было. При этом значение "top" у div#bottom у меня вообще нигде не задано, однако это условие работает. Я уже не знаю, что тут ещё можно сделать. :help: А функция скрытия части текста на странице должна быть обязательно.
Кстати. Если не писать дополнительный скрипт для сдвига блоков, то значение "height" у div#content изменяется автоматически, только отдельный нижний блок остаётся на своём месте, потому что он там зафиксирован с абсолютным позиционированием. |
Убрал строку с определением высоты блока content. После этого его высота стала меняться автоматически. Так что теперь загвоздка в сдвиге div#bottom. Что-то, видимо, не так в условии, но оно работает. Только отладить его надо. Если я ставлю в условии
if (h < 1450), то div#bottom.top = 1620px постоянно, и наоборот. |
Написал функцию проверки значения "height" у div#content. При скрытом тексте 1076, при раскрытом — 1469,8333740234375. Условие, вроде бы правильно составил. Не понимаю, что тут не так.
|
Squirr,
:) Мон чисто табличкой верстку забодать и никаких мучений #content - это сама табла - отступы для ячеек #meny и #banner задаем cellpadding #ro0/#r1 => div блок cо style=width:100%; height:100%; |
Deff, если по-другому не получится, только такой вариант и останется. А так, как я пытаюсь сделать, не получится по-вашему? Из-за различий в браузерах, конфликта внутреннего или ещё каких-то факторов.
|
Объясните подробнее какого поведения хотите добиться (опишите поведение каждого из блоков).
Например, пока не понятно представленный на рисунке вид должен оставаться таким в рамках экрана или может прокручиваться, меню имеет постоянную высоту или зависит от содержимого, то же самое про баннер и т.д., также непонятно как это всё должно вести себя при масштабировании. Deff, таблицу тоже проблематично удержать в рамках экрана при масштабировании (ну или я может быть чего-то не догоняю). Вот пример <!doctype html> <style> body { margin: 0px; padding: 0px; overflow: hidden; } table { position: absolute; left: 0px; top: 0px; width: 100%; height: 100%; } td { border: 1px solid gray; } table div { width: 100%; height: 100%; overflow: auto; } </style> <table> <tr> <td colspan="2" height="5%">mainMenu</td> </tr> <tr > <td width="30%" height="90%"> menu </td> <td width="70%"> <div> content1<br>content1<br>content1<br>content1<br>content1<br> content1<br>content1<br>content1<br>content1<br>content1<br> content1<br>content1<br>content1<br>content1<br>content1<br> content1<br>content1<br>content1<br>content1<br>content1<br> content1<br>content1<br>content1<br>content1<br>content1<br> content1<br>content1<br>content1<br>content1<br>content1<br> </div> </td> </tr> <tr> <td colspan="2">bottom</td> </tr> </table> |
bes,
На картинке представлена структура div-ных блоков. #r0 и #r1 — это 2 разных блока с текстом разного объёма, виден в любой момент времени только 1 из них. Соответственно, должна меняться высота блока banner, в котором находится текст (это автоматом происходит, т.к. его высота не определена) и высота блока content (тоже не задана, меняется автоматически). Блок bottom находится отдельно от них. Это нужно, чтобы не нарушать дизайн. У него, соответственно, надо реализовать динамически изменяемое установленное свойство CSS top. Вот этого-то мне добиться и не удалось пока. В блоке banner основной контент, а не баннер. Название блока перешло по наследству с главной страницы, чтобы не писать лишние стили. Здесь я оставил название, чтобы самому потом не запутаться. |
Squirr,
Цитата:
Как вариант <style> div { padding: 0px; margin: 1%; } .menu { float: left; width: 30%; background: lightgrey; } #banner { padding: 10px; float: left; width: 63%; background: green; } #banner div { background: lightgrey; } .bottom { clear: both; background: gray; } </style> <div class="content"> <div class="menu"> <a href="#" onclick=" banner.children[i].style.display = 'none'; banner.children[j].style.display = 'block'; k = i; i = j; j = k; return false; "> menu</a> </div> <div id="banner"> <div> content1<br>content1<br>content1<br>content1<br>content1<br>content1<br>content1<br> content1<br>content1<br>content1<br>content1<br>content1<br>content1<br>content1<br> </div> <div style="display: none">content2<br>content2</div> </div> </div> <div class="bottom"> bottom </div> <script> var i = 0; var j = 1; var k; </script> |
bes,
Цитата:
В зависимости от размера экрана контент должен прокручиваться. Меню имеет постоянную высоту и зависит от количества содержимого. Баннер должен менять высоту в зависимости от того, скрыта ли часть текста. А нижний блок, отделённый от общего, должен смещаться вниз равномерно вместе с основным контентом. У этого нижнего блока изначально было фиксированное положение, т.к. я не знал при вёрстке, что придётся менять CSS.top. Сверху страницы ещё есть шапка с логотипом, основным меню и пр. Они не вызывали у меня проблем, поэтому я их опустил. Здесь указываю, чтобы у Вас было полное представление о том, что это будет. Спасибо за Ваш пример. Должно быть именно так, только ссылка на скрытие текста у меня в блоке #banner, и при загрузке страницы большая часть текста скрыта. Попробую с ним разобраться завтра на свежую голову :) |
Часовой пояс GMT +3, время: 10:15. |