*/ ?>

Zrovnanie výšok elementov

Zrovnávanie výšok elementov je obvykle špinavá práca. Ak sa to urobí pomocou CSS, musíš si najprv povedať aké vysoké elementy budú a potom sa často stane že sú buď poloprázdne alebo pretekajú. Pomocou JavaScriptu je to fajnovejšie, ale celkom komplikované.

Tak čo s tým? Zrovnávať výšky elementov predsa treba každú chvíľu: upútavky, fotogalérie, stĺpcová sadzba. Súčasný web je toho plný! Ako vždy, pomôže Prototype. Pomocou neho môže byť zrovnanie výšok elementov hračka na pár riadkov.

Čo budeš potrebovať?

Budeš pracovať so zbierkou elementov. Tú získaš buď pomocou Element.select() alebo dvojdolárovej funkcie $$(). Obidve sú v podstate identické, vracajú pole elementov. Najpohodlnejšie teda bude rozšíriť objekt Array o novú metódu matchHeight().

V nej budeš potrebovať zistiť výšku najvyššieho elementu a tú potom aplikovať na všetky ostatné elementy.

Takto bude vyzerať kostra:

Object.extend( Array.prototype, {
	matchHeight : function () {
		// najdenie maximalnej vysky
		// nastavenie vysky vsetkym elementom
		return this;
	}
} );

Odfiltrovanie položiek bez výšky

Je tu malý zádrheľ. Objekt Array je príliš obecný a čisto teoreticky môže obsahovať aj položky, ktoré nie sú elementy. Pre istotu by si ich mal odfiltrovať. V podstate chceš pracovať iba s položkami, ktoré majú metódu getHeight().

Na prefiltrovanie poľa sa hodí metóda Enumerable.findAll(). Ako parameter použij jednoduchú funkciu, ktorá sa opýta či položka má metódu na zistenie výšky alebo nie:

var elementsWithHeight = this.findAll(
	function ( item ) {
		return item.getHeight;
	}
);

Nájdenie najvyššieho elementu

Výslednú zbierku elementov treba prejsť a nájsť ten, ktorý má najväčšiu výšku. Je to jednoduché, urobí to Enumerable.max(). Táto metóda využije jednoduchú funkciu na zistenie výšky elementu:

var maxHeight = elementsWithHeight.max(
	function ( item ) {
		return item.getHeight()
	}
);

Nastavenie jednotnej výšky

Element.getHeight() vracia výšku elementu v pixeloch. Všetkým elementom teda hromadne metódou Enumerable.ivoke() nastavíš pomocou Element.setStyle() výšku toho najvyššieho. A nezabudni uviesť jednotku (pixely):

elementsWithHeight.invoke(
	'setStyle',
	{ height : maxHeight + 'px' }
);

Výsledná metóda

Ked jednotlivé kroky poskladáš dohromady do pôvodnej kostry, dostaneš výslednú metódu:

Object.extend( Array.prototype, {
	matchHeight : function () {
		var elementsWithHeight = this.findAll( function ( item ) { return item.getHeight; } );
		var maxHeight = elementsWithHeight.max( function ( item ) { return item.getHeight() } );
		elementsWithHeight.invoke( 'setStyle', { height : maxHeight + 'px' } );
		return this;
	}
} );

Praktická ukážka

Jednoduchý odrážkový zoznam, ktorého položky majú fixné šírky a sú floatované doľava. Toto je obvykle základom jednoduchej obrázkovej galérie s popismi. Typický prípad, kedy sa hodí zrovnávanie výšok.

Otvoriť ukážku

Poznámka z praxe

Dávaj si pozor na box model. Podľa štandardu výška elementu definuje rozmer (v tomto prípade výšku) jeho vnútra. K tomu sa pripočíta veľkosť paddingu a okraja (border). Ak teda budeš jednotnú výšku počítať z elementov ktoré majú nastavený padding alebo border, bude ich výsledná výška väčšia než očakávaš. V praktickej ukážke je to vidieť, keď zjednotíš výšky elementov LI.

Ak v praxi máš takýto prípad, vlož si do elementov ktorých výšku potrebuješ zrovnať ešte jeden. Ten nebude mať nič čo by mohlo ovplyvniť jeho rozmer. V praktickej ukážke je takýmto elementom odstavec v odrážke.

Poznámka k optimalizácii výkonu

Keď sa poriadne pozrieš na výslednú metódu, iste si všimneš, že prakticky celá zbierka elementov sa v nej prechádza trikrát. To je v pohode, ak pracuješ s malými zbierkami (nanajvýš desiatky elementov). Pri väčších zbierkach určite narazíš na problém s výkonom.

Filtrovanie elementov a hľadanie najväčšej výšky by sa dalo zlúčiť do jedného cyklu. Ďalšou pomocou by bolo použitie klasického for cyklu s counterom a cachovanou dĺžkou. Celý skript však stratí niečo zo svojej elegancie a stručnosti:

Object.extend( Array.prototype, {
	matchHeight : function () {
		var maxHeight = 0;
		var elementsWithHeight = [];
		var elementsWithHeightIndex = 0;
		for ( var index = 0, totalItems = this.length; index < totalItems; ++index ) {
			var currentItem = elementsWithHeight[ elementsWithHeightIndex ] = this[ index ];
			++elementsWithHeightIndex;
			if ( currentItem.getHeight ) {
				var currentItemHeight = currentItem.getHeight();
				if ( maxHeight < currentItemHeight ) {
					maxHeight = currentItemHeight;
				}
			}
		}
		for ( var index = 0; index < elementsWithHeightIndex; ++index ) {
			elementsWithHeight[ index ].style.height = maxHeight + 'px';
		}
		return this;
	}
} );
  1. Pridávaním metód k fajnovému hoveru
  2. Filtrovanie obsahu dokumentu bez použitia Ajaxu
  3. Dynamicky generovaný iframe
  4. Zvýrazňovanie zaškrtnutých položiek
  5. document.getPageSize()

Zverejnené 25.12.2008
v kategórii JavaScript.

Nálepky:
, , , ,

Autor článku

Riki Fridrich, http://fczbkk.com

Som taký dobrý, že som sám sebe vzorom.

Vyjadri sa

Tvůj komentář se zobrazí, až ho některý z adminů schválí. Zveřejňovat budeme pouze hodnotné komentáře, které se přímo týkají tématu.


O projekte

Tento projekt vznikol, pretože všetky odborné weby sajú a my sme tým pádom nemali kde publikovať svoje články.