Se per le immagini di sfondo il caricamento condizionale può avvenire sfruttando i soli CSS e le media query, non così è per le immagini inserite come contenuto nel codice HTML. E dal momento che nel responsive design la manipolazione dei componenti e dei contenuti avviene per lo più sul lato client, è a JavaScript che dobbiamo rivolgerci.
In questa e nelle lezioni che seguono esamineremo una serie di librerie JavaScript che consentono un efficace caricamento condizionale dei contenuti. Nel nostro progetto sono state adoperate quasi sempre per le immagini, ma una volta compresa la logica di funzionamento, nulla vi impedirà di adottarle per altre tipologie di contenuto.
Immagini della sezione 'Primo piano'
Nella sezione 'Primo piano' troviamo la segnalazione di una serie di articoli con un titolo, un sommario e un'immagine. L'immagine viene mostrata solo su tablet e desktop, non sugli smartphone. Vediamo come.
Le immagini, per iniziare, non vengono definite nel modo canonico nel codice HTML (ovvero con il tag <img>
), ma incluse dinamicamente quando la larghezza della viewport è >= 600px.
Nel codice HTML dobbiamo però inserire comunque un riferimento a queste immagini. Lo facciamo con un attributo data-src
associato ai titoli h3
di ciascun articolo. Al titolo assegniamo pure una classe .conditional-img
:
<article id="a2" class="media">
<h3 class="conditional-img" data-src="barcellona-2.jpg">Eiusmod tempor</h3>
[...]
</article>
Bene, a questo punto abbiamo bisogno di uno script che funzioni più o meno secondo questa logica:
if (larghezza-minima >= 600px) {
// prendi l'attributo data-src di ciascun h3;
// crea un nuovo elemento img per ciascun h3;
// assegnagli come src il valore di data-src;
// inserisci dinamicamente l'immagine prima del titolo h3;
}
Per questa sezione, abbiamo usato uno script sviluppato originariamente da Jeremy Keith e usato dallo stesso nella home page del sito dConstruct 2012.
L'implementazione prevede due passi.
Nel CSS si inserisce questa media query:
@media all and (min-width: 600px)
{
body:after
{
display: none;
content: 'tablet-desk';
}
}
È una media query basata su una larghezza minima di 600px
, quella che abbiamo fissato per il caricamento delle immagini. La regola che segue non ha alcun effetto a livello visuale. Il contenuto generato con :after
è infatti nascosto. Però, come valore della proprietà content
, inseriamo una sorta di variabile, un riferimento a quella che è per noi la larghezza di riferimento (può essere ovviamente un valore qualunque, l'importante è il valore di 600px della media query).
Poi passiamo allo script vero e proprio. Come spiegato dall'autore, non fa altro che testare attraverso JavaScript se una certa media query è stata eseguita. Ovvero: se il valore della proprietà content
corrisponde a tablet-desk
, lo script viene eseguito. E quando la proprietà content
assume il valore tablet-desk
? Quando la larghezza minima è di 600px, perché la regola è inserita in una media query! Geniale. Ecco lo script:
(function (win)
{
var doc = win.document;
if (doc.querySelectorAll)
{
var imgTD = doc.querySelectorAll('h3.conditional-img');
for (var i = 0; i < imgTD.length; i++)
{
if (win.getComputedStyle)
{
var size = win.getComputedStyle(doc.body, ':after').getPropertyValue('content');
if (size.indexOf('tablet-desk') != -1)
{
var src = imgTD[i].getAttribute('data-src');
var img = document.createElement('img');
img.setAttribute('src', src);
img.setAttribute('class', 'scala media--img');
imgTD[i].parentNode.insertBefore(img, imgTD[i]);
}
}
}
}
})(this);
Lo script agisce esattamente secondo la logica vista poc'anzi:
- riga 4: identifica gli
h3
con classe.conditional-img
; - riga 6: verifica il supporto del metodo
getComputedStyle
con cui possiamo rintracciare lo stile calcolato per una proprietà CSS di uno specifico elemento; - riga 7: crea una variabile
size
associata al valore della proprietàcontent
; - riga 8: valuta se il valore di
size
corrisponde atablet-desk
; - righe 9-13: se così è, crea una nuova immagine che ha come valore di
src
il valore deldata-src
di ciascun titolo e la inserisce prima di ciascunh3
.
Questa la versione di base dello script. Nella realtà abbiamo dovuto usarne una leggermente più complessa per estendere il supporto a IE8. Potete consultarla studiando il sorgente della demo.
Tale soluzione ha due vantaggi:
- non si appoggia ad alcuna libreria;
- consente di dichiarare i breakpoint (
min-width: 600px
) solo nel CSS, senza bisogno di duplicarli nel JavaScript.
A prescindere da queste considerazioni, l'efficacia per noi è indubbia. Sui dispositivi mobili risparmiamo ancora un po' di KB, lasciando pienamente fruibili i contenuti, visto che la lista degli articoli è comunque a disposizione dell'utente.