Attention : Il est recommandé de lire ce billet sur sa page originale pour profiter des exemples et de la coloration syntaxique.

Parmi les très grands avantages du HTML5, il y a la possibilité d'y inclure du SVG, sans pleurer par une balise <object></> ou <embed />. Ce qui veut dire que vos gribouillages vectoriels font réellement partie de la page. Ça ne tuera pas forcément Flash, mais cela y contribue.

Attention, cela ne marche que si votre navigateur dispose d'un vrai parser HTML5. Firefox 3.6 ou Chrome 7 vont râler (et je ne parle pas de MsIE8).
Auparavant (et je parle de 2007 quand j'ai commencé à m'y intéresser), il fallait passer par un document strictement XHTML 1.1 et bricoler sérieusement son doctype. Si le style de balisage XML n'est pas pour me déplaire (au contraire !), faut quand même avouer que la plupart des toolkits javascript du type wysiwyg avaient la très fâcheuse manie d'utiliser d'horribles document.write(). Or, dans le DOM d'un document XML/XHTML strict, la méthode .write() est bannie. Malheureusement, j'avais encore besoin de ces bibliothèques impures qui l'utilisent, ou d'autres horreurs comme eval().

Ça n'excuse en rien l'usage dans un code récent : Je vous préviens que quand je vois ça chez un client, je prends le dev, et je lui démonte son restaurant manière Gordon Ramsay.

Maintenant, c'est nettement plus simple, à tel point qu'on peut s'amuser à bricoler directement en javascript du SVG inclus dans la page. Voire utiliser des bibliothèques toutes prêtes, comme MooTools, ExtJS, YUI ou jQuery, pour ceux qui veulent aller un peu plus vite. Personnellement, je préfère jQuery, et sûrement à tort.

Sauf que une fois qu'on est à l'intérieur du contenu de la balise <svg></>, les méthodes javascript de manipulation du DOM sont complètement différentes, et pas encore intégrées dans ces libs.

En jQuery, il y devient donc impossible d'utiliser les méthodes comme $.html(), laquelle se base sur la propriété de votre objet DOM.innerHTML, et je ne parle pas des dimensions, rendant $.width() ou $.height() inutilisables. C'est là qu'il faut se plonger dans les docs du W3C pour en créer de nouvelles et agrandir les possibilités de ces bibliothèques par des extensions capillaires.

La première d'entre elles étant de palier à l'absence d'$.append(), on va s'amuser à le faire.

Pré-requis

Un navigateur moderne, supportant le SVG dans HTML5.

MsIE, internet selon microsoft Il est donc plus que normal que MsIE version 8 et inférieures ne supportent pas cette page. MsIE 9 est censé l'accepter, mais malgré tout le respect que j'ai dans la IE-team, je parie sur des incompatibilités, une tradition forte chez eux. Il est évidemment possible de s'em⁂☹☈⚒er à utiliser le plugin SVG complètement abandonné par Adobe, qui d'ailleurs comporte de nombreux manques d'implémentation. Un loisir appréciable pour les masos et les amateurs d'expressivité vernaculaire au travail. Mais comme on est là pour travailler sur le web de la décennie à venir, on va gentiment raccompagner pépé à la maison de retraite.

C'est comme ça que j'ai gagné en sécurité dans le développement du backoffice de dAgence : en demandant aux clients d'être à jour. Personne ne s'en est plaint.
En même temps, c'est de bonne guerre.

Ensuite, comme je suis un très mauvais pédagogue, un peu de pratique jQuery et de la notion objet devrait aider.

Comment étendre jQuery, et si possible, pas comme une crêpe

jQuery est un objet “perpétuel” de la lib du même nom, c'est là-dessus qu'on travaille pour l'étendre. Vous connaissez probablement mieux son alias $, mais celui-ci peut dans certains cas entrer en conflit avec d'autres libs (par exemple MooTools). C'est pour ça que quand on écrit un code générique (par exemple, une extension de la bibliothèque qu'on compte ouvrir au public), il est recommandé d'utiliser l'objet qui porte le nom de la lib.

jQuery.fn est un objet qui comporte une collection de méthodes. Ce sont les fonctions de jQuery que vous utilisez après le sélecteur.

jQuery.extend() permet de fusionner deux ou plusieurs objets, parce qu'une simple addition ne marchera pas. Si un seul objet est présent en paramètres, la méthode s'applique sur l'objet parent.

Donc, avec la combinaison jQuery.fn.extend(), si l'objet en paramètre comporte en valeur des fonctions (anonymes ou variabilisées), on étend la syntaxe de jQuery avec de nouvelles méthodes. On peut aussi surcharger les anciennes : dans mon prochain billet technique, vous aurez une illustration de la double décla.

Le Code

On va supposer qu'un <svg></> est déjà présent dans votre page. Dedans, vous allez insérer de nouveaux éléments de façon dynamique. On va étendre jQuery pour vous permettre d'ajouter des éléments SVG.

jQuery.fn.extend({
    appendSvg:function (nom,attributs)
              {
                  var svg = document.createElementNS("http://www.w3.org/2000/svg",nom);
                  for (var cle in attributs)
                  {
                          var valeur = attributs[cle];
                          svg.setAttribute(cle,valeur);
                  }
                  var appendices = this.length;
                  for (var i = 0; i < appendices; i++)
                  {
                          this[i].appendChild(svg);
                  }
                  return svg;
              }
}); 

Oui, je sais, j'ai une manière trèèèèès spéciale pour indenter.
La méthode .appendSvg() s'applique sur un sélecteur d'éléments à l'intérieur duquel on va créer notre balise. Le nom de la balise insérée est en premier paramètre, le deuxième paramètre est un objet comportant des paires attribut=valeur à y attribuer.

Pour appeler la fonction créée, voici la syntaxe :

$('svg').appendSvg('circle',{id:'cercle',fill:'red'});

Ce qui, dans chaque balise trouvée <svg></svg>, ajoutera le code <circle id="cercle" fill="red" />.

Bienvenue dans un univers parallèle

La première chose que nous faisons, c'est créer une nouvelle balise, donc un nouvel objet DOM.
En début de code HTML, après la déclaration doctype HTML5 <!Doctype html>, nous avons précisé notre namespace : <html lang="fr" xmlns="http://www.w3.org/1999/xhtml">. Seulement, nous venons de le quitter et d'entrer dans my inception, nous sommes dans le rêve SVG du rêve HTML. Heureusement, mon totem document, il est âchtement puissant, et il est toujours là. Mouahahaha.

Pour créer un élément DOM HTML, nous utilisons d'habitude document.createElement(tagName). Là, nous utilisons sa variante document.createElementNS(nameSpace,tagName). Le namespace du SVG est "http://www.w3.org/2000/svg", où existe des balises très étranges comme <circle /> donc là, ok, le totem, il tourne toujours, âchtement puissant.

Ça va, vous suivez ?

On a besoin de deux méthodes, à savoir insérer un attribut à l'objet et l'insérer. Ça tombe bien : les interfaces dom-html et dom-svg utilisent parfois des noms de fonctions communs. .setAttribute() et .appendChild() sont dans le tronc commun.

Pop !

Ah oui, y'a un petit bonus sonore.

Et pour terminer

La semaine prochaine, on s'amusera avec les nouvelles structures de programmation apportées par Javascript 1.7, un truc de ouf à t'en retourner le totem à Baboulinet. Et la suivante, vous pleurerez devant les problèmes que nous avons soulevé pour dAgence en stylant le svg avec de la css.

Crédit son : bruit d'une moule qui arrive sur le bouchot, extrait du zoodvinsen de wmcoincoin.