Nel post precedente ho tagliato dall’xhtml qualsiasi struttura utile alla sola componente js.
jQuery
Aggiungere, manipolare in generale, elementi html di una pagina è uno dei principali motivi di successo nel mondo, della libreria creata dal genio di John Resig.
Una delle invenzioni più geniali che io abbia potuto veder nascere e crescere in questo mondo da quando “lo vivo”.
Prima odiavo il “front-end”.
Il css soprattutto e le sue differenze tra browsers. Poi non conoscevo assolutamente le tecniche (gli idiomi e i pattern) avanzate del linguaggio javascript. E in ultimo non esisteva (o non conoscevo) firebug.
Andavo avanti a funzioni e anche li era una lotta perenne tra attributi proprietari e standard. Tra ambienti di debug minimi (mozilla/firefox) e lo zero assoluto (Explorer).
Tra messaggi di errore comprensibili e assurde traduzioni in italiano (”Impossibile eseguire lo script liberato”… si certo, come no? cos’è lo script liberato?).
jQuery come è possibile vedere dalla sua reference è divisibile in
- jQuery Core
- DOM (Selectors/Attributes/Traversing/Manipulation)
- CSS
- Events
- Effects
- Ajax
In questo post vedremo come aggiungere a runtime le differenza xhtml tra il primo e il secondo template.
Tra lo studio del componente finito e la sua versione accessibile senza javascript attivo.
Cosa dobbiamo fare? Facciamo un minimo di analisi.
Tralasciamo per ora le BUONE PRATICHE di programmazione javascript (terzo punto per una programmazione non intrusiva).
Vediamo passo passo quali operazioni deve eseguire il nostro js: il nostro rozzo “main”.
- Noto subito che i records (<div class="record"><!– lorem ipsum –></div>) non sono divisi in pagine.
- La toolbar.
- La visualizzazione della pagina attiva e il “nascondimento” delle pagine non visibili.
Procediamo per passi.
Innanzitutto come ho già ripetuto alla noia devo aspettare l’evento “onload”.
Non ho immagini, ne operazioni da fare su di esse. (Questo però non lo posso sapere a priori, e a dire il vero qualche test con swf e oggetti esterni potrei farlo, per vedere eventuali bugs di visualizzazione).
jQuery(document).ready(function(){
});
Ready prende come argomento una funzione.
Il poter passare come argomento una funzione anonima è una delle funzionalità più potenti del linguaggio javascript.
Il nostro programma verrà eseguito una volta che il DOM è disponibile e raggiungibile.
All’interno di questa closure (poi ne parlerò, ogni argomento funzione rappresenta una closure) il nostro programma ha un ambito ristretto e definito.
Se non commetto “refusi” nella programmazione non avrò “globali”: una fondamentale BUONA PRATICA di programmazione non intrusiva.
Il refuso più diffuso è inizializzare una variabile senza var davanti. Lo chiamo refuso… perchè uno che sa, lo fa per distrazione.
Secondo refuso è scrivere una cosa del genere: var a = b = 0;
b è globale attenzione! Ci sono cascato.
Usare variabili globali diffusamente è una cattiva pratica. Secondo me un punto globale ci deve sempre essere. Ed è il “singleton“. Ma c’è chi sostiene che anche questa sia una cattiva pratica. O mi sfugge qualcosa, o loro non hanno forse mai programmato.
In software engineering, the singleton pattern is a design pattern that is used to restrict instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. Sometimes it is generalized to systems that operate more efficiently when only one or a few objects exist. It is also considered an anti-pattern by some people, who feel that it is often used as a euphemism for global variable. - da wikipedia
Passo 1 - Dividere in pagine i record
Dividiamo inizialmente in blocchi da 3 record le pagine e “wrappiamo” (racchiudiamo, inglobiamo) 3 record all’interno di un div (contenitore) “pagina”.
var _records = jQuery(".record");
var _per_pagina = 3;
var _pages = Math.ceil(_records.size() / _per_pagina);
for(var _x= 1;_x <= _pages; _x++){
//wrap
var _page_start = (_x - 1) * _per_pagina;
var _page_stop = _page_start + _per_pagina;
var _slice = _records.slice(_page_start, _page_stop);
_slice.wrapAll('<div class="jp-page" id="page-'+_x+'" />');
}
*cerco di scrivere sempre i nomi di variabili in inglese - mi è sfuggito _per_pagina
Testiamo il codice con firebug. Vediamo se scatena eccezioni. Nel tab html (di firebug, o altrimenti tramite webdevolperbar, sempre firefox, View Source -> View generated source, o altrimenti sempre con firefox, seleziona tutto -> tasto destro -> vedi selezione) è possibile vedere il codice generato.
Ho aggiunto classe e id alla pagine perchè so già che ne avrò bisogno per gli eventi.
Le variabili con l’underscore davanti stanno a indicare che sono private ad un ambito.
Questione di stile (ma anche di buone pratiche, non tutti hanno a disposizione la chiarezza sintattica di java, e a volte può essere una vera fortuna).
Liberi di fare un po’ quello che preferite. Io in questo modo vedo le variabili che arrivano dall’esterno di un ambito (arguments) o le variabili globali (se mai ce ne dovessero essere) o le proprietà/attributi che stabilisco essere pubbliche (perchè c’è il modo di stabilire la visibilità in javascript, solo che lo vedremo in un altro tutorial).
Sottolineo un paio di passaggi dello “snippet” precendente jQuery.
jQuery(selector);
La query innanzitutto: jQuery(”.record”);
Non uso mai il $.
jQuery può essere usato via alias $.
- Io spesso lavoro in ambiti dove si usa prototype… non voglio problemi di conflitti.
- E poi il dollaro mi ricorda altro. Il php. Ed ha un altro senso il dollaro nel php.
- E con un search&replace posso sempre aggiungerlo.
- E google registra che qui si parla di jQuery. Ed è un bene.
.record è un selettore css.
Si usa per le interrogazioni jQuery esattamente come nel css viene usato per applicare lo stile.
E’ il tipo di selezione più diffuso e semplice. Ne esistono altri (xPath) più complessi da leggere e da applicare ma anche più potenti.
La query restituisce gli oggetti jQuery che “wrappano” le references html.
Per chi viene dal DOM classico:
invece di avere il risultato di un document.getElementByTagName (o byID o con estensione byClassName) fatto di nodi HTML, attraverso interrogazione jQuery ho lo “stesso risultato”, ma fatto di oggetti jQuery. Chiaro?
Con un nodo HTML potrei fare risultato.id per ottenere l’ID del nodo o setAttribute per settare un nuovo attributo al nodo. Con l’oggetto jQuery posso fare le stesse cose usando i metodi jQuery o posso fare le native operazioni DOM con
jQuery(risultato).get(0).id
Quindi con il metodo get() ottengo la reference HTML. 0 può essere sottointeso.
Capire questo è fondamentale per proseguire.
DIMENTICATEVI l’implementazione nativa del DOM e tutti i suoi problemi. Almeno io non la voglio più vedere. Nonostante sia uno standard (in teoria) qualche multinazionale mi ha fatto odiare l’implementazione nativa.
E poi mi sento dire dai Programmatori filo-microsoft che IO non sono professionale!
Potevano prima di criticare me, insegnare loro la lettura di documenti di standard? RFC e quant’altro.
jQuery(selector).slice();
Ho usato il metodo slice (jQuery) per avere una porzione di nodi dall’array restituito dalla selezione (dal record x al record y).
jQuery(selector).wrapAll();
E il metodo wrapAll che permette di wrappare (racchiudere, inglobare) appunto gli elementi selezionati con un nodo (o più) html.
Il metodo wrap avrebbe aggiunto ad ogni singolo elemento restituito da slice il codice html, quindi invece di avere un div page a contenere 3 record avrei avuto un div page a contenere ogni singolo record (e non serviva a niente).
jQuery(selector).size();
Il metodo size permette di avere il numero di elementi ottenuti dalla selezione jQuery.
Ecco la
e qui il codice generato da queste prime 5 righe di codice js:
Da:
<div class="target">
<div class="record"></div>
<div class="record"></div>
<div class="record"></div>
<div class="record"></div>
<div class="record"></div>
<div class="record"></div>
<div class="record"></div>
<div class="record"></div>
<div class="record"></div>
<div class="record"></div>
<div class="record"></div>
</div>
A:
<div class="target">
<div id="page-1" class="jp-page">
<div class="record"></div>
<div class="record"></div>
<div class="record"></div>
</div>
<div id="page-2" class="jp-page">
<div class="record"></div>
<div class="record"></div>
<div class="record"></div>
</div>
<div id="page-3" class="jp-page">
<div class="record"></div>
<div class="record"></div>
<div class="record"></div>
</div>
<div id="page-4" class="jp-page">
<div class="record"></div>
<div class="record"></div>
</div>
</div>
[... continua]
{ 2 } Trackbacks
[...] post precedente : differenze via jQuery - 1/2 [...]
[...] applicate via jQuery (1 e [...]
Post a Comment