Как стать автором
Обновить

Проблема: выравнивание размеров окна по контенту

Время на прочтение4 мин
Количество просмотров747
Во время работы над проектом наткнулся на проблему, которую «с кондачка» решить не смог.
Выношу на общее обсуждение. Даже если никто не прокомментирует — выложу свои домыслы и решение, если найду.

Задача



По ссылке открывается окно, в котором содержится какой-то контент. Точные размеры контента заранее неизвестны, однако заранее предполагается, что они не будут больше какого-то «разумного» предела. Пусть этот предел будет, например, 1000 на 800.

Требуется, чтобы после открытия окно приняло бы размеры в соответствии с контентом, оставив небольшой, заранее определённый отступ.



Предварительный вариант решения



Сначала было предложено
1. Открывать окно с каким-то абстрактным размером. Например, 600 на 500.
2. Изменять размер окна в зависимости от размера контента.
3. Центровать контент методом, прежде обнаруженным на страницах хабра.

Получилось примерно следующее

HTML:


<div id="rootDiv">
<div id="popupContainer">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed porta. Vestibulum augue metus, lacinia non, sollicitudin nec, tempus vitae, lacus. Phasellus ligula magna, vulputate non, tempus sit amet, ullamcorper id, est. Nam tellus quam, ultrices sit amet, feugiat a, egestas non, mi. Curabitur malesuada tristique nulla. Nullam libero turpis, scelerisque id, ultrices auctor, imperdiet vel, pede.
</div>
</div>


CSS

div#popupContainer
{
background-color: white;
position: absolute;
left: 50%;
padding: 10px;
}
div#rootDiv
{
top: 50%;
left: 0px;
width: 100%;
height: 1px;
overflow: visible;
visibility: visible;
display: block;
position: absolute;
}


Javascript

$(document).ready(function(){
window.resizeTo(
$("#popupContainer").width() + 120,
$("#popupContainer").height() + 160
);
$("#popupContainer").css("margin-left", "-" + ($("#popupContainer").outerWidth() / 2) + "px");
$("#popupContainer").css("margin-top", "-" + ($("#popupContainer").outerHeight() / 2) + "px");
});


Проблема №1


И тут, собственно, начинается проблема. Отчасти ею обусловлен и несколько кривоватый метод реализации… Итак, при resizeTo изменяется размер окна, причём размер полученной контентной области будет зависеть от наличия или отсутствия тулбаров, тайтла окна и т.п. и будет наверняка разным для разных браузеров. Потому и высота взята «с запасом», но точно его вычислить нельзя.

Есть мыслишка, что можно тупо проанализировать размеры этих отступов путём
  1. Произвести resizeTo к каким-то константным величинам
  2. Измерить размеры контентной области через document.body.clientWidth, clientHeight или innerWidth, innerHeight соответственно
  3. Вычислить разницу и затем отресайзить уже с учётом этой разницы


Но мне этот метод кажется неправильным ввиду двойного ресайза — нехорошо смотрится, когда окно перед глазами пользователя прыгает и сползается/расползается.

Проблема №2


Обнаружилась в опере — в других браузерах вроде не так заметно, что

Проходит некоторе время, прежде чем «popupContainer» подползает к своей положенной точке в середине окна, что тоже создаёт неприятный эффект.

Внимание, вопрос


Как можно было бы решить эти обе проблемы с минимальными затратами, а вторую, если возможно, чисто методами CSS?

Комментарии и пояснения


Update 1

При открытии у окна заданы какие-то конкретные размеры. По умолчанию дивы растянутся максимально на всю ширину этого окна. Но контент может оказаться и шире, так как внутри могут оказаться какие угодно элементы — и дивы и картинки и таблицы.

Значит, как минимум, нужно выровнять высоту окна. В случае, если контент не влезает по ширине, то приходится подгонять и ширину окна.

Update 2

В принципе задача (получается) может быть решена в случае, если удастся определить во всех браузерах реальные размеры окна. В таком случае и сложные конструкции CSS и Javascript, занимающийся центровкой, не потребуется.

Update 3

Решение, как обычно, было где-то рядом: достаточно вместо resizeTo использоваться resizeBy и реальные размеры окна нам уже не нужны. Тогда, если нам нужны отступы по 10 пикселов от каждого края, получается

HTML:


<div id="popupContainer">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed porta. Vestibulum augue metus, lacinia non, sollicitudin nec, tempus vitae, lacus. Phasellus ligula magna, vulputate non, tempus sit amet, ullamcorper id, est. Nam tellus quam, ultrices sit amet, feugiat a, egestas non, mi. Curabitur malesuada tristique nulla. Nullam libero turpis, scelerisque id, ultrices auctor, imperdiet vel, pede.
</div>


CSS

div#popupContainer
{
background-color: white;
position: absolute;
left: 10px;
top: 10px;
}


Javascript

function docWidth() {
return (typeof(window.innerWidth) != 'undefined') ? window.innerWidth : document.body.clientWidth;
}

function docHeight() {
return (typeof(window.innerHeight) != 'undefined') ? window.innerHeight: document.body.clientHeight;
}

$(document).ready(function(){
window.resizeBy(
20 - (docWidth() - $("#popupContainer").outerWidth()),
20 - (docHeight() - $("#popupContainer").outerHeight())
);
});


Ну и проблема №2 решилась как бы сама собой — центровка теперь происходит «естественным» образом — за счёт изменения размеров окна.

За подсказку спасибо Илье Cтpeльцыну aka SelenIT
Теги:
Хабы:
Всего голосов 5: ↑3 и ↓2+1
Комментарии35

Публикации