Пропустити навігацію.
Портал українців Луганщини

Javascript вирівнювання висот блоків

У цьому дописі йдеться про вирівнювання висоти однотипних блоків на сторінці.

Ситуація: "Гумовий сайт" на DIV’ах

Робимо "гумовий" сайт. Верстаємо DIV’ами. Однотипні блоки ми робимо однакової ширини. Це просто, у CSS пропишемо ширину. А з висотою - складніше. Якщо її прописати в CSS - то може трапитися, що текст буде не уміщатися у блок і виходитиме за його межі. Можна висоту задати "зі щедрим запасом". Але може трапитися так, що текст у всіх однотипних блоках буде не великим, і тоді наш "гумовий сайт" буде "світити" порожніми боками наших щедро розвисотнутих блоків. А якщо не вказувати висоту у CSS, то з великою імовірністю (залежно від вмісту блоків) можемо отримати ось таку картину:

Схема а: Карявості, через неоднакові висоти блоків

Ідея: JavaScript вирівнювання висоти блоків

Як не крути, я не додумався, як у цій ситуації не йти на якийсь компроміс. Пропоную компромісне рішення. У CSS висоту ми не задаємо. Але при завантаженні сторінки, JavaScript’ом вирівнюємо висоту всіх однотипних блоків, заданих спеціальним чином.

Слід мати на увазі, що вирівнювати висоту може знадобитися не для одного набору, а для двох, трьох чи більше наборів блоків (наприклад, один набір - це блоки, кожен з яких містить інформацію про категорію; другий набір - це блоки останніх новин, публікацій, ну, і так далі). Отже, не треба, щоб усі наскрізь блоки позначені спецпозначкою стали мати одну висоту, а треба, щоб одна висота була у межах одного розділу сторінки, а в іншому розділі була вже інша висота для дочірніх блоків. Себто так, як показано на малюнку "б":

Схема б: Однакові висоти, порядок на сторінці

Реалізація

Для втілення задуму, використаємо глобальну змінну resizeableBlockMaxHeight (це буде максимальна висота серед блоків одного розділу) і oldPitem (це DOM-елемент останнього розгляненого скриптом розділу блоків). Також скористаємося основними можливостями JQuery.

Блоки, для яких буде вирівнюватися висота, матимуть додатковий клас resizeableBlock.

var resizeableBlockMaxHeight = 0;
var oldPitem = null;
function sincronizeBlockHeight(){
	var items = $('.resizeableBlock');
	items.each(
		function(el){
			var item = $(this);
			var pitem = item.parent();
			if(!oldPitem || pitem.get(0) != oldPitem.get(0)){
				if(oldPitem){
					oldPitem.children('.resizeableBlock').height(resizeableBlockMaxHeight);
				}
				resizeableBlockMaxHeight = 0;
				oldPitem = pitem;
			}
			var itemHeight = item.height();
			if(itemHeight > resizeableBlockMaxHeight){
				resizeableBlockMaxHeight = itemHeight;
			}
		}
	);
	$('.resizeableBlock:last').parent().children('.resizeableBlock').height(resizeableBlockMaxHeight);
}

Принцип роботи: Максимальна висота з кожного розділу

Ми перебираємо всі блоки, які мають клас resizeableBlock, порівнюємо висоту кожного з них з максимальною висотою блоків, обчислену на попередніх кроках (resizeableBlockMaxHeight).

Для кожного наступного блоку, перевіряємо, до якого DOM-елементу він належить. Якщо він збігається з DOM-елементом попереднього кроку (oldPitem), то значить обчислення максимальної висоти ще не закінчилося, якщо ж вони різняться. Значить, ми знайшли максимальну висоту для всіх блоків з попереднього розділу. Отже, встановлюємо її для всіх них.

Обнуляємо висоту (бо тепер уже процес починається для наступного розділу), вказівник попереднього розділу переміщаємо на розділ, в якому ми починаємо нове вирівнювання. Через те, що ми висоту встановлюємо для блоків з попереднього розділу, то після закінчення циклу-перебирання, блоки з останнього розділу ще не мають однакової висоти, тому останній рядок функції довершує справу вирівнювання.

Застосування

Для того, щоб картина на нашому "гумовому" сайті зверстаному "на DIV’ах" відбувалося, чіпляємо функцію sincronizeBlockHeight() на подію onload тега BODY.

Має працювати.

Додати новий коментар

Вміст цього поля є приватним і не буде показаний.
КАПЧА
Дайте відповідь на це запитання, щоб ми знали що ви людина, а не робот ).