Blog momentaneamente fermo, riprenderò le pubblicazioni quando la mia vita sarà meno frenetica... :D

mercoledì 3 agosto 2011

La magia del vettoriale: HTML, SVG, Javascript

In questi caldi giorni d'estate si continua a lavorare, il nuovo sito del LENS richiede tempo e concentrazione e ogni tanto offre qualche sfida che merita di essere raccontata. In questo caso ecco il problema: includere un'immagine svg in una pagina web (un diagramma disegnato con Inkscape, per la precisione) con la caratteristica che un click sui vari elementi del grafico lanci una funzione javascript che fa apparire o scomparire un div della pagina, posto sotto l'immagine.

Disclaimer: come forse avrai intuito, questo sarà un post terribilmente tecnico, quindi se tu lettore non hai idea di cosa significhino le sigle del titolo, smetti pure di leggerlo.

La struttura della pagina è la seguente: libreria javascript per l'effetto toggle residente in un file esterno incluso nella pagina html, funzioni javascript in un elemento script, immagine svg inclusa in un elemento object (ma è equivalente usare embed o iframe, vedi qua), vari div su cui agisce il codice javascript.

Le funzioni javascript sono eseguite quando si clicca su un elemento del diagramma, quindi sono richiamate nell'attributo xlink:href dell'elemento a nell'svg (ma si può usare anche l'evento onclick). Il guaio è che in questa configurazione non funziona un bel niente! Per il semplice fatto che l'svg incluso nell'html mediante l'elemento object non vede la definizione delle funzioni javascript e tanto meno la libreria. Si potrebbe spostare tutto il javascript all'interno dell'elemento script dell'svg? Provato, ma niente, probabilmente perché a questo punto il javascript non riesce a gestire il DOM della pagina html, essendo definito dentro l'svg. Senza contare che non potrei poi usare quel javascript al di fuori dell'svg.

Ok, la soluzione? Inserire l'svg inline, cioè direttamente nell'html della pagina. Qui c'è un semplice esempio (non sembra necessario che la pagina sia in XHTML). Gli attributi dell'elemento svg definiscono tutti i namespace corretti, quindi il browser (nel mio caso Chrome) riesce a renderizzare tutto per bene, le funzioni javascript definite prima dell'elemento svg sono richiamabili all'interno di esso e agiscono sui div definiti dopo l'svg stesso. E non è tutto: le normali regole css agiscono come ci si aspetta anche sugli elementi interni all'svg, io per esempio ho eliminato la sottolineatura ai link del diagramma con un semplice svg a { text-decoration:none; }.

In Rete ho trovato centinaia di tutorial che parlano di come rendere interattive le immagini svg mediante javascript, ma poco o niente che tratti la questione di funzioni javascript richiamate da un evento interno all'immagine svg, ma agenti su elementi al di fuori di essa. Spero che questo post sia quindi utile a qualcuno... :)
Add to Diigo


Nessun commento:

Posta un commento