Přes Vánoce jsem byl u rodičů. Kromě celodenního jídla a hraní deskových her jsem se pokusil přečíst dvě knihy, které jsem si přinesl.
Jednou z knih byl ODPOVĚDNÝ RESPONZIVNÍ DESIGN od Scotta Jehla. Nedávno vyšla a je to opravdu dobré čtení. Ještě jsem ji nedočetl, ale baví mě a určitě je v TOP5 žebříčku mých oblíbených knih o responzivním webdesignu.
Ve světě responzivního webdesignu se neustále zabýváme mediálními dotazy, abychom našim návštěvníkům poskytli nejlepší možný zážitek v závislosti na jejich zařízení a prostředí. Obvykle to znamená, že weboví vývojáři se zabývají rozměry obrazovky v rámci mediálních dotazů a to je každým dnem bláznivější a užitečnější.
Pokud vás zajímá, co může přijít v budoucnu, specifikace pro Media Queries Level 4 je docela zajímavá – podívejte se na specifikaci pro úroveň osvětlení.;)
Mediální dotazy se většinou používají uvnitř souborů CSS k přizpůsobení stylu konkrétnímu zařízení, které návštěvník používá. To dává naprostý smysl, ale responzivní web design by neměl být jen o tom, „aby to vypadalo pěkně“.
Mělo by se také jednat pouze o používání a inicializaci potřebných komponent.
Ve své poslední práci jsem hodně spolupracoval s Foundation. A opravdu se mi to líbilo. Bloková mřížka je úžasná! A také implementace Off-canvas je podle mého názoru docela pěkná.
Jediná věc, která mi vždy vadila na implementacích ve slavných frameworkech jako Bootstrap a Foundation, je to, že skripty a moduly používané pro menší zařízení se spouštějí i na větších zařízeních a naopak.
Bez ohledu na to, zda jsou moduly a jejich funkce potřebné nebo ne, daný kód se provede a všechny obslužné rutiny událostí jsou stále svázány. Tyto obslužné rutiny událostí se v mnoha případech nespustí, protože dané prvky DOM spojené s funkcí jsou v několika kombinacích prostředí skryty pomocí CSS.
Když se podíváte na navigační řešení pro menší zařízení v obou projektech, uvidíte, že moduly JavaScriptu, které zaručují dobrou zkušenost na menších zařízeních, jsou inicializovány a obslužné rutiny událostí jsou bezdůvodně vázány – bez ohledu na to, zda jsou potřeba. Toto je jednoduché plýtvání CPU a není to vůbec potřeba.
Hodně se diskutuje o tom, co nabídnout zákazníkovi, pokud jde o detekci funkcí a vlastní sestavení, ale ne každý projekt má dostatek času a zdrojů na implementaci komplikovaných systémů sestavení.
Proto jsem začal dané moduly inicializovat pouze v případě potřeby. Vlastní sestavení Modernizru je obvykle součástí mých projektů, takže praktický Modernizr
Funkce se většinou používá k tomu, aby se neinicializovaly věci, které vůbec nejsou potřeba.
// only initialize the off-canvas
// navigation for smaller devices
if ( Modernizr.mq( '(max-width: 50em)' ) ) {
// initialize Foundation's offcanvas
$document.foundation( 'offcanvas' );
}
Modernizr.mq
- jak to funguje?
Pojďme se podívat, jak tato funkce funguje. Funkce je definována v mq.js a testMediaQuery.js.
// -> testMediaQuery.js
define(['injectElementWithStyles'], function( injectElementWithStyles ) {
// adapted from matchMedia polyfill
// by Scott Jehl and Paul Irish
// gist.github.com/786768
var testMediaQuery = (function () {
var matchMedia = window.matchMedia || window.msMatchMedia;
if ( matchMedia ) {
return function ( mq ) {
var mql = matchMedia(mq);
return mql && mql.matches || false;
};
}
return function ( mq ) {
var bool = false;
injectElementWithStyles('@media ' + mq + ' { #modernizr { position: absolute; } }', function( node ) {
bool = (window.getComputedStyle ?
window.getComputedStyle(node, null) :
node.currentStyle)['position'] == 'absolute';
});
return bool;
};
})();
return testMediaQuery;
});
Jak vidíme interně, Modernizr používá matchMedia
funkce (pokud je k dispozici), která je definována ve specifikaci modulu zobrazení CSSOM. Pokud matchMedia
není podporováno, poskytuje podložku pro dosažení stejné funkčnosti.
window.matchMedia
- tak co?
matchMedia
poskytuje funkci kontroly mediálních dotazů na straně JavaScriptu. A skvělé na tom je, že je podle caniuse.com skutečně poměrně široce podporován.
Modernizr
nám již poskytuje podporu při získávání informací o tom, zda daný mediální dotaz odpovídá či nikoliv. Jedna klíčová věc, na kterou je třeba si dávat pozor, je matchMedia
nevrací booleovskou hodnotu, se kterou se má pracovat – místo toho vrací rozhraní MediaQueryList.
Informace, zda se mediální dotaz shoduje, je uložen ve vlastnosti matches
.
( function( window, document ) {
// get MediaQueryList Interface
var mql = window.matchMedia( '(min-width:20em)' );
// get a container to do something with it depending
// on matching media query
var container = document.getElementById( 'container' );
// create new paragraph object
var paragraph = document.createElement( 'p' );
// set innerHTML depending on matching media query
paragraph.innerHTML = mql.matches ?
'Yeah - matching!' :
'No - not matching!';
// append element to container
container.appendChild( paragraph );
} )( window, document );
Už to je skvělé, protože tímto způsobem můžeme snadno vyhodnotit, zda je potřeba konkrétní modul JavaScriptu inicializovat nebo ne. Ale co případ změny prostředí, jako je změna výřezu z režimu na výšku na režim na šířku? To je něco, s čím jsem se už nějakou dobu potýkal – a při čtení knihy Scotta Jehla jsem právě narazil na super elegantní řešení.
Už jsem četl spoustu článků o matchMedia
, ale předtím jsem nevěděl, že poskytuje více než jen matches
vlastnost.
Vráceno MediaQueryList Interface
také poskytuje možnost připojit posluchače k okamžiku, kdykoli se dotaz na média změní z odpovídající na neodpovídající nebo naopak.
( function( window, document ) {
// get MediaQueryList Interface
var mql = window.matchMedia( '(min-width:20em)' );
// get a container to do something with it depending
// on matching media query
var container = document.getElementById( 'container' );
// create new paragraph element
var paragraph = document.createElement( 'p' );
// set innerHTML depending on matching media query
paragraph.innerHTML = mql.matches ?
'Yeah - matching!' :
'No - not matching!';
// append element to container
container.appendChild( paragraph );
// attach event listener to changed state
// of the given media query
mql.addListener( function( mql ) {
// create new paragraph element
var paragraph = document.createElement( 'p' );
// set innerHTHML depending on matching media query
paragraph.innerHTML = mql.matches ?
'Yeah - changed to matching!' :
'No - changed to not matching!';
// append element to container
container.appendChild( paragraph );
} );
} )( window, document );
To je přesně to, co jsem chvíli hledal, poskytuje snadný způsob, jak vylepšit rozhraní při změně prostředí za chodu a od začátku šetřit zdroje.
Pokud si s tím chcete hrát, vytvořil jsem pro vás pero, se kterým si můžete hrát.
A to je pro dnešek vše - doufám, že se vám krátké čtení líbilo. Jakékoli nápady a připomínky jsou více než vítány. :)