Table des matières
Manipuler le code HTML avec jQuery
Insertion de contenu
Nous allons voir comment insérer du contenu, ce qui est la base de la manipulation du code HTML.
Sachez tout d'abord qu'il existe trois sortes de contenu :
- le contenu textuel, ce qui correspond à du texte, tout simplement, sans fioritures telles que des balises ;
- le contenu HTML, qui représente le contenu textuel avec les balises structurelles en plus ;
- et le contenu des éléments de formulaire, qui est la valeur des différents champs de texte, de mot de passe, de textarea…
Ces différentes sortes de contenu ne se manipule pas tout à fait de la même manière, nous allons donc apprendre à utiliser les trois méthodes correspondantes, ainsi que quelques autres fonctions bien utiles, pour par exemple ajouter des éléments à une place bien précise.
Le contenu textuel
Commençons par le plus simple : le contenu textuel.
Il n'est vraiment pas difficile de le manipuler, dans la mesure où il n'existe qu'une seule fonction pour le faire : text().
Cette méthode permet soit de récupérer le contenu textuel d'un élément s'il existe, soit de le modifier en donnant la nouvelle version en argument.
Petite note à retenir, les balises données ne fonctionneront pas, car les chevrons (< et >) seront convertis automatiquement en entités HTML (respectivement < et >).
Rappel : en JavaScript, vous utilisez la propriété textContent pour le modifier.
Récupération du contenu
Pour récupérer le contenu d'un élément, il suffit d'utiliser la méthode text() tout simplement, ni plus ni moins. Elle ne retournera qu'une chaîne de caractère (string), qui contiendra le contenu textuel seulement : pas de balises ouvrantes ni fermantes, pas de chevrons HTML, juste du texte.
$('p').text(); // renvoie le texte contenu à l'intérieur du paragraphe
Chose importante à retenir, la fonction s'arrête à la première occurrence trouvée : si vous avez plusieurs paragraphes et que vous lancez le code ci-dessus, vous n'obtiendrez que le contenu du premier paragraphe du document, ayant l'index 0.
De même, elle prend parfaitement bien en compte les espaces divers et les retours à la ligne.
Définition de contenu
Comme dit précédemment, la définition de contenu avec text() se fait par argument.
Faites bien attention à l'utiliser correctement : cette méthode écrase le contenu actuel pour le remplacer par le nouveau !
Nous verrons comment ajouter, au lieu d'écraser, du contenu un peu plus tard dans ce chapitre.
$('p').text('Nouveau contenu !'); // remplace le contenu actuel du paragraphe par "Nouveau contenu !"
Le contenu HTML
Passons dès à présent au plus intéressant : le contenu HTML. Nous vous rappelons qu'il s'agit juste du contenu textuel, avec les balises structurelles en plus. Vous allez donc voir une fonction text() un peu améliorée, html(). Elle fonctionne tout simplement comme la propriété innerHTML que vous utilisez en JavaScript simple, pour la simple et très bonne raison qu'elle est basée dessus (cette fonction ne marchera donc pas sur des documents XML).
En bref, rien de très compliqué, si vous avez des balises à l'intérieur de votre élément, elles seront bien comprises dans le retour :
$('div').html(); // renvoie le code HTML contenu dans ce bloc div $('div').html('<p>Nouveau <strong>code</strong> !</p>'); // remplace le code HTML actuel par celui-ci
Pour la récupération de code HTML, la méthode s'arrête, comme pour text(), à la première occurrence trouvée.
Seulement, cette fonction ne présente pas un très grand intérêt si l'on veut ajouter du contenu au lieu de simplement remplacer.
Écraser les données actuelles peut parfois être embêtant, c'est pourquoi il existe heureusement d'autres méthodes permettant d'insérer du code HTML avant ou après le contenu déjà présent.
Ajouter du contenu HTML avant le contenu actuel prepend()
La méthode prepend() ajoute le contenu HTML passé en argument avant le contenu HTML actuellement en place, tout en restant dans la limite des balises (pour vous en rappeler : pre comme previous, précédent en français).
On a donc une insertion à l'intérieur et au début de l'élément.
$('p').prepend('<strong>Texte inséré avant le contenu actuel.</strong> ');
Résultat :
<p> <strong>Texte inséré avant le contenu actuel.</strong> Contenu actuel. </p>
Au lieu d'une chaîne de caractère, vous pouvez également passer en argument un objet jQuery ; cela aura pour effet d'aller récupérer l'élément indiqué, et de l'insérer directement à l'intérieur :
$('p').prepend( $('h1') );
Résultat :
<p> <h1>Un titre H1</h1> Contenu actuel. </p>
Cette technique agit un peu comme un couper-coller : l'objet donné en argument ne sera pas dupliqué, mais déplacé !
Ajouter du contenu HTML après le contenu actuel append()
Parallèlement à la méthode prepend(), append() ajoute le contenu HTML passé en argument après le contenu HTML actuellement en place. Évidemment, l'insertion s'effectue toujours à l'intérieur des balises de l'élément.
Cette fonction marche exactement de la même manière que sa cousine :
$('p').append(' <strong>Texte inséré après le contenu actuel.</strong>'); $('p').append( $('h1') );
Deux cas spéciaux : prependTo() et appendTo()
Pour ceux qui aiment commencer leur repas par le dessert, il existe deux méthodes qui permettent de faire exactement la même chose que celles que l'on vient de voir, mais de façon inverse. Il s'agit de prependTo() et appendTo(), qui fonctionnent à l'envers : on va tout d'abord sélectionner l'objet à déplacer, puis l'objet receveur, celui qui va accueillir le contenu souhaité.
Pour mieux comprendre, nous vous invitons à regarder ce schéma d'un peu plus près :
- append() :
- objet.append(contenu)
- appendTo() :
- contenu.appendTo(objet)
$('p').append( $('h1') ); // ici, on ajoute le contenu du titre après avoir sélectionné notre élément $('h1').appendTo( $('p') ); /* alors qu'ici, on sélectionne d'abord le contenu du titre, et on le déplace après le contenu actuel de notre élément receveur */ $('p').prepend( $('.description') ); // on ajoute le contenu de .description avant le contenu de notre paragraphe $('.description').prependTo('p'); // on peut spécifier directement l'élément, sans passer par un objet
Création de contenu à l'extérieur de l'élément
S'il est possible d'insérer du code HTML à l'intérieur d'un élément, il est également possible d'en insérer à l'extérieur ! Cela implique alors une modification du parent de cet élément, et non de l'élément lui-même : celui-ci n'est pas modifié, mais la balise qui l'entoure voit son contenu changé. De même que pour prepend() et append(), before() et after() permettent respectivement d'ajouter du contenu HTML avant et après l'élément ciblé.
$('p').before('<p>Paragraphe précédent</p>'); $('p').after('<p>Paragraphe suivant</p>');
Résultat :
<p>Paragraphe précédent</p> <p>Paragraphe ciblé</p> <p>Paragraphe suivant</p>
Équivalents de prependTo() et appendTo(), insertBefore() et insertAfter() permettent d'inverser la logique des choses : pour utiliser ces méthodes, vous devez d'abord cibler l'objet à déplacer, puis spécifier l'objet receveur en argument :
$('h1').insertBefore('p'); // insère un titre H1 et son contenu avant un paragraphe $('.description').insertAfter('h1'); // insère un élément .description et son contenu après un titre H1
Le contenu des éléments de formulaire
Afin de clore cette petite partie, nous allons voir une dernière méthode, dont l'utilité n'est pas des moindres : val().
Équivalente à la propriété value en JavaScript, elle va nous servir à manipuler le contenu des éléments de formulaire, ce qui est en général entré par l'utilisateur.
Elle fonctionne exactement de la même manière que text() (elle n'admet aucune balise structurelle).
$('input').val(); // retourne le contenu de l'élément input $('input').val('Nouvelle valeur !'); // modifie le contenu actuel de l'élément (écrase puis écrit)
Manipulation des éléments HTML
Dès à présent, voyons plus loin dans la manipulation du DOM. Après s'être amusé avec le contenu, qu'il soit textuel, ou issu de formulaires, nous allons maintenant apprendre à manier efficacement les éléments HTML, c'est-à-dire tout ce qui peut être défini comme objet jQuery.
Mais qu'entendons-nous par manipulation des éléments ?
Ici, la manipulation semble à priori basique : vous allez voir comment dupliquer, vider, supprimer, remplacer ou même envelopper des éléments !
Seulement, il faut savoir qu'il existe quelques subtilités relatives aux méthodes mises en place par jQuery. Souvenez-vous que c'est un point fort du framework ; même si son utilisation se veut simple et accessible, du moins plus que le JavaScript pur, il faut quand même maîtriser certaines notions pour affirmer être un bon développeur jQuery (amateur). :-p
Cloner des éléments
Parmi les manipulations possibles existe le clonage d'élément. La méthode clone() (on devrait vous faire deviner le nom des méthodes) a pour effet de dupliquer l'élément ciblé. Pas de soucis jusque là, nous direz-vous, il suffit juste d'utiliser cette fonction sur un objet et hop, le tour est joué. La subtilité dans ce cas-là, c'est que votre clone d'élément ne sera pas ajouté au document, car vous ne lui avez rien ordonné : il restera là, vaquant, ne sachant que faire, perdu et coupé du monde.
Image utilisateur
Il va alors falloir lui indiquer où se placer. Et comment insérer du contenu ?
Avec les méthodes étudiées précédemment, telles que append() ou prepend() !
var $clone = $('.objet').clone(); // on clone notre élément $('body').append($clone); // puis on l'ajoute à la fin de notre document ! // on peut également tout écrire sur une seule ligne grâce au chaînage de méthode : $('.objet').clone().appendTo('body');
Cette fonction clone l'élément original dans sa totalité : les attributs, le contenu, etc.
Seulement, en l'utilisant ainsi, il est impossible de cloner également l'évènement éventuellement associé. Pour faire cela, il suffit de passer true en argument à la méthode.
Vider et/ou supprimer un élément
Viennent ensuite les actions de vidage ou de suppression d'éléments.
Respectivement, bien que leur nom soit assez éloquent, empty() et remove() sont les deux méthodes appropriées.
Mais quelle différence entre vider et supprimer un élément ? Dites-vous que toute la subtilité réside dans le contenu et les balises : vider un élément supprimera simplement son contenu, qu'il soit textuel ou structurel, alors que supprimer un élément fera disparaître ce dernier en totalité, c'est-à-dire son contenu, mais aussi lui-même !
$('p').empty(); // vide l'élément, seules subsisteront les balises <p></p> et leurs attributs $('p').remove(); // supprime l'élément, avec son contenu, rien n'en restera $('div').remove('.suppression'); // supprime les éléments portant la classe .suppression parmi les blocs div trouvés
Remplacer les éléments
On continue ! Après le clonage et la suppression, parlons du remplacement.
Très simple également, tout comme clone(), les deux méthodes replaceWith() et replaceAll() permettent de remplacer un élément par un autre.
Cela va fonctionner comme un couper-coller : l'élément ciblé va être remplacé par un autre, dans le cas d'un objet, mais celui ci va se déplacer au lieu de se cloner.
Encore une fois, vous n'êtes pas obligé de spécifier un objet en tant qu'argument, vous pouvez tout aussi bien mettre du nouveau contenu.
La seule différence entre les fonctions replaceWith() et replaceAll(), c'est que la première va prendre en argument l'objet ou le nouveau contenu à insérer, alors que l'autre va faire l'inverse, c'est-à-dire que vous devrez spécifier l'élément à remplacer en argument.
$('.pomme').replaceWith('<p>Cet élément a été remplacé !</p>'); // on remplace l'élément .pomme par un nouvel élément créé pour l'occasion $('.pomme').replaceWith( $('.poire') ); // ici, l'élément .pomme est remplacé par l'élément .poire, ce dernier va se déplacer $('.poire').replaceAll('.pomme'); // inversement, on ordonne aux éléments .poire de remplacer tous les éléments .pomme trouvés
Rappelez-vous bien que c'est tout l'élément qui est remplacé, pas seulement son contenu ; veillez donc à y mettre un nouvel élément complet à la place !
Envelopper/déballer des éléments
Enfin, pour clore cette partie, vous allez apprendre à envelopper et déballer des éléments.
Ce sont des actions plus ou moins utilisées, car elles ne présentent pas énormément d'intérêt, mais il est tout de même bon de savoir les effectuer, car elles permettent notamment de créer ou de supprimer des parents très rapidement. Nous parlons ici des méthodes wrap() et unwrap().
Plus concrètement, la première fonction va agir autour de l'élément ciblé : elle va y insérer les bonnes balises indiquées, et ce, automatiquement. L'argument a néanmoins une forme un peu particulière, qui va vous préparer à la suite de ce chapitre, c'est-à-dire la création d'éléments à la volée.
La forme de cet argument est plutôt simple ; il suffit d'écrire une balise HTML normalement, en la fermant directement. Vous savez qu'il existe des balises auto-fermantes, telles que <img /> ?
Eh bien, jQuery uniformise la chose en donnant cette convention à toutes les balises.
C'est une habitude à prendre, car même si elle n'est pas obligatoire (vous pouvez tout aussi bien écrire la balise ouvrante et la balise fermante, cela fonctionnera aussi bien), c'est une des conventions qui font la différence entre un mauvais et un bon codeur jQuery. :-p
Pour déballer vos éléments, il suffit d'utiliser unwrap() sans argument. Cela aura pour effet de détruire l'élément parent de celui qui est ciblé.
$('strong').wrap('<p />'); // entoure les balises <strong></strong> de balises de paragraphe $('span').wrap('<p class="description" />'); // il est possible de donner des attributs au nouveau parent $('span').unwrap(); // détruit le parent de tous les span
Vous pouvez bien évidemment créer plusieurs parents d'un seul coup, en imbriquant les balises correctement comme dans une structure HTML normale.
Envelopper plusieurs éléments frères
Le principal problème de wrap(), c'est qu'elle va entourer chaque élément trouvé sur le document.
Avec elle, il est impossible d'entourer plusieurs éléments frères, qui se trouvent côte à côte.
Comme d'habitude, nous vous donnons la solution : wrapAll() !
Elle s'utilise exactement de la même manière, si ce n'est qu'elle va prendre en compte le fait que des éléments soient frères :
$('li').wrapAll('<ul />'); // entoure tous les <li></li> d'un seul parent commun
Envelopper seulement le contenu
Dernière possibilité, est-il réaliste de vouloir entourer le contenu seulement d'un nouveau parent ?
La réponse est bien évidemment positive ! :) La fonction wrapInner() va vous permettre de réaliser ce genre de chose :
$('p').wrapInner('<strong />'); // entoure le contenu de balises <strong></strong>
Résultat :
<p> <strong>Le ciel est bleu.</strong> </p>
Créer des éléments à la volée
Enfin, vous l'attendiez, nous allons apprendre dès maintenant comment créer des éléments à la volée ! Rappelez-vous que cette expression signifie qu'on va fabriquer de nouveaux éléments depuis notre code jQuery, sans passer par la case chargement du DOM. En JavaScript pur, la bonne façon de procéder, ou du moins la plus rapide, était d'utiliser la fonction native createElement().
De notre côté, seule la fonction principale jQuery() va nous servir !
Créer des éléments, une histoire de balises
La création de nouveaux éléments en jQuery se fait de manière extrêmement simple : on inscrit une ou plusieurs balises dans l'argument de la fonction principale, et celles-ci sont automatiquement créées. Se pose alors le problème que nous avons déjà rencontré : l'élément se trouve vaquant, et n'est pas placé dans le DOM, ce qui est assez embêtant. Pour parer ce soucis, il suffit d'utiliser les méthodes de placement que vous avez appris précédemment dans ce chapitre (quand on vous dit que ce chapitre traite de fonctions très importantes :p ).
$('<div />').appendTo('body'); // créé un nouveau bloc div, et le place à la fin du corps du document
Du contenu peut également être créé en même temps, de même que des attributs peuvent être initialisés (cela est possible grâce à la propriété native innerHTML de JavaScript) :
var $lien = $('<a href="http://www.siteduzero.com/">Le Site du Zéro !</a>'); // la variable contiendra l'élément lui-même, ainsi que son contenu // n'oubliez pas de placer l'élément ensuite
Passer des attributs proprement
La création d'attributs pour notre nouvel élément peut se faire directement lors de la fabrication de celui-ci. Seulement, le code peut vite devenir redondant et illisible si vous procédez avec cette méthode lorsque vous avez beaucoup d'attributs à créer. Histoire d'améliorer le confort des développeurs, jQuery s'est vu ajouter, lors de sa version 1.4, la possibilité de donner un objet en second argument à la méthode principale, contenant la liste de tous les attributs du nouvel élément, à la manière d'attr().
Il est ainsi possible de donner un grand nombre d'attributs sans influencer la lisibilité du code jQuery :
$('<div />', { id : "bloc", // identifiant de l'élément css : { // style css de l'élément color : "red", fontSize : "30px" } // etc... });
Il est également possible d'initialiser un ou des évènement(s) en tant que propriété !
L'attribut class
Faites attention à une petite erreur que font beaucoup de débutants. JavaScript est un langage orienté objet, il utilise donc le concept de classes, que l'on peut définir grâce au mot-clé class.
Si vous voulez définir la classe d'un élément, structurellement parlant, il vous faudra mettre le nom de cette propriété entre guillemets ou apostrophes pour ne pas entrer en conflit avec JavaScript.
Le cas Internet Explorer
L'éternel irréductible navigateur de Microsoft nous joue parfois des tours, même si l'on code avec jQuery ! Faites donc attention dans le cas où vous créez un élément de formulaire <input />, et que vous définissez ses attributs type et/ou name. En effet, Internet Explorer ne supporte pas de voir ces propriétés dans un objet, à la création de l'élément. Pour contourner ce problème, vous devrez passer soit par la création directe dans la balises, soit par la méthode attr() avant d'insérer l'élément dans le document (rappelez-vous que la propriété type n'est pas supportée par cette fonction).
$('<input />', { type : "text", name : "pseudo" }); // non supporté par IE $('<input type="text" />').attr({ name : "pseudo" }); // bonne façon de procéder
Vous savez maintenant comment créer des éléments à la volée dans vos documents HTML ! 
La manipulation du DOM est un passage incontournable lorsque vous codez avec jQuery. Vous venez de voir une foule de fonctions maintenant prêtes à l'emploi, mais rassurez-vous, si vous ne les retenez pas toutes, vous pourrez toujours revenir sur ce chapitre un peu plus tard. Retenez pour le moment seulement les principales méthodes, celles qui sont indispensables. En annexes, un mémento des fonctions à connaître vous sera proposé.
