JQuery knihovna pro tvorbu layoutu webových aplikací
Před časem jsem pro svůj redakční systém hledal javascriptové udělátko pro tvorbu layoutu. Jako obvykle mi žádné z dostupných řešení nevyhovovalo, tak jsem si ho napsal sám a nyní jej uvolňuji jako opensource.
Ono vlastně „nyní“ je trochu silné slovo. Je to už pár let staré řešení. Před víc než půl rokem jsem jej mírně upravil pro aktuální verzi jQuery, očistil s tím, že jej uvolním jako opensource. Založil jsem na to projekt na http://code.google.com/p/moonjs/, vzápětí jsem na to zapomněl a nikomu o tom neřekl :). Dneska jsem si na to vzpomněl, tak o tom aspoň napíšu sem.
Takže o co jde: je to něco jako layoutovací modul z ExtJS, jenže mnohem jednodušší. Oproti ExtJS je to jednoduchoučká jednoúčelová nevtíravá knihovnička, která je psána tak, aby co nejméně ovlivňovala okolí. Ostatně podívejte se na demo a uvidíte sami.
Jak to funguje
Základem layoutu je hierarchický (binární) strom panelů. Každý panel může (ale nemusí) být rozdělen na dvě části, a to buď horizontálně nebo vertikálně. Každá z těchto částí může být zase rozdělená a tak dál až donekonečna. Chování panelů lze ovlinit několika parametry, které popíšu dále.
Zajímavou vlastností (kterou jsem u podobných řešení postrádal) je možnost kombinování šířek (výšek) panelů zadaných v pixelech a v procentech. Pokud má panel šířku zadanou v procentech, pak se při změně velikosti okna prohlížeče (nebo změně velikosti nadřazeného panelu) přepočítá skutečná šířka panelu tak, aby procenta seděla. Pokud má však šířku zadanou v pixelech, zůstává zadaná šířka přesně zachována.
Ačkoliv jsem využil knihovnu jQuery, není řešení implementováno jako jQuery plugin, ale jako klasické javascriptové konstruktory („třídy“ chcete-li) ve vlastním jmenném prostoru (moon). Považuju to za flexibilnější.
K dispozici jsou následující dva konstruktory moon.Panel a moon.PanelSplit. Způsob použití je nejlépe patrný z dema:
$(document).ready(function()
{
// Vytvoření instance panelu:
var panelMain = new moon.PanelSplit({
axis: 'y',
position: ' 10px',
resizable: false,
showHandler: false,
firstPanel: {
type: 'Panel',
sizing: 'contentHeight',
content: $("#header")
},
secondPanel: {
type: 'PanelSplit',
axis: 'y',
position: '60px',
masterPane: 'second',
handlerWidth: 15,
firstPanel: { … },
secondPanel: {
type: 'Panel',
content: $("#footer")
}
}
});
// Panel připojím do dokumentu
panelMain.outer.appendTo($('body'));
// Při resizování okna prohlížeče je nutno překreslit layout
$(window).bind('resize', function(){
panelMain.redraw();
});
// Při načtení dokumentu zavoláme počáteční překreslení layoutu
panelMain.redraw();
}
Každý konstruktor panelu má jako parametr konfigurační objekt, jehož vlastnosti ovlivňují chování a zobrazení panelu a handleru. Vlastnost type určuje typ panelu (nyní 'Panel' nebo 'PanelSplit'). Je to taková obezlička, aby se dal použít konfigurační objekt uložit jako JSON a nefigurovala v něm volání konstruktorů panelů. Možnosti konfigurace jsou následující:
| type | 'Panel' | Následující volby platí pro jednoduchý panel. |
| content | string | jQuery | Obsah panelu. Může být řetězec nebo jQuery objekt. |
| sizing | 'fit' | 'contentWidth' | 'contentHeight' | 'contentBoth' | Způsob určování rozměru panelu. Výchozí je 'fit', což znamená, že panel se přizpůsobí rozměrům nadřazeného panelu. Ostatní volby jsou spíš experimentální – panel se 'jakoby' vyrenderuje bez omezení a pro jeho rozměry se použije šířka, výška, nebo oba rozměry takto vyrenderovaného obsahu. Pokud se to překombinuje, můžou nastat nepředvídatelné konfliktní situace. |
| type | 'PanelSplit' | Následující volby platí pro rozdělený panel. |
| axis | 'x' | 'y' | Určuje osu rozdělení panelu, 'x' znamená vertikální rozdělení, 'y' horizontální. |
| position | 'Npx' | 'N%' | Pozice handleru, neboli šířka (výška) panelu. Může být zadaná v pixelech nebo v procentech - podle toho se mění chování panelu při změně velikosti. To, kterému panelu šířku (výšku) zadáváme (zda prvnímu nebo druhému) se určuje parametrem 'masterPane'. |
| masterPane | 'first' | 'second' | Určuje "hlavní" panel, neboli panel, kterému zadáváme počáteční šířku (výšku). Šířka (výška) druhého panelu se dopočítá automaticky jako doplněk do celkové zbylé šířky (výšky). |
| resizable | true | false | Zda je možné měnit velikost panelu myší táhnutím za handler. |
| handlerWidth |
int | Šířka handleru v pixelech. Výchozí hodnota je 7 pixelů. |
| showHandler | true | false | Zda zobrazit handler či nikoliv. |
| firstPanel | Konfigurační objekt (popř. přímo instance) prvního panelu (první = levý nebo horní). Jde o instanci objektu typu moon.Panel nebo moon.PanelSplit. | |
| secondPanel | Konfigurační objekt (popř. přímo instance) druhého panelu (druhý = pravý nebo spodní). Jde o instanci objektu typu moon.Panel nebo moon.PanelSplit. |
Stylování panelů je 100% řízeno CSS třídami (viz CSS soubor, který je přilinkován k demu).
A to je vše. Nejedná se o nijak robustní řešení, naopak – hlavním cílem byla co nejjednodušší implementace. Jistě by se našla spousta vlastností, které by se hodily, např. perzistence stavu panelů apod. Na druhou stranu to v této podobě už nějakou dobu používám a celkem mi to vyhovuje. Funkčnost testována ve většině současných prohlížečů, od IE6 výš včetně. Licence MIT. Třeba se to někdy někomu bude hodit.
Datum: 1. 12. 2009, Autor: Karel Fučík

Komentáře (1)