Table des matières
Parcourir les éléments du DOM
Naviguer dans le DOM
Rappel sur le Document Object Model
Le Document Object Model, beaucoup plus couramment appelé DOM, permet littéralement de naviguer entre les éléments HTML.
Nous rappelons qu'il s'agit d'une interface de programmation, utilisée exclusivement pour les documents XML et HTML, qui se base sur la structure.
C'est grâce à ce concept qu'il est possible d'agir sur une page web avec JavaScript, et plus précisément ses fonctions ; sans cela, nous ne pourrions pas désigner les éléments !
Vous vous en doutez, nous faisons constamment appel au DOM, même si en jQuery, on s'en rend beaucoup moins compte.
En effet, même si nous n'avons pas encore appris à utiliser les fonctions de parcours, sachez que la sélection d'éléments, par exemple, use de certaines fonctions JavaScript qui ont besoin du DOM (c.f. getElementById()).
Positionnement des éléments
La position des éléments dans la structure d'une page HTML est très importante. C'est pourquoi on vous répète souvent : ayez un code propre, une structure claire et bien rangée, et vous aurez beaucoup plus de facilité à manipuler vos éléments en JavaScript !
Une sémantique bien faite, c'est un gain de temps et d'énergie.
Prenons pour exemple un code HTML très mauvais, que l'on peut malheureusement rencontrer sur le web :
<div id="bloc"> <a href="#" id="lien">Un lien</a><a href="#" id="lien">Un autre lien</a> <div> <span class="paragraphe">Contenu</span> <div></div> </div>
Nous espérons sincèrement que vous n'écrirez JAMAIS ce genre d'aberration…
Dans un cas comme celui-là, la sélection simple ne sera pas altérée ; en revanche, si vous devez parcourir le DOM pour ne pas devoir refaire une requête d'élément inutile, alors bonne chance ! :p Une bonne sémantique est primordiale, nous ne vous le répéterons jamais assez.
La descendance
Si on vous rabâche depuis quelques temps que la descendance est un concept très utilisé en programmation orientée objet, ce n'est pas pour rien : souvent apparentée à l'héritage, cette technique se base sur le principe de parents et d'enfants.
Dans un contexte comme le nôtre, cela peut paraître un peu tiré par les cheveux comme méthode de travail, et pourtant, sans cela, il serait beaucoup plus compliqué de réaliser de véritables applications en jQuery !
Quelques chapitres auparavant, nous avons abordé rapidement la chose avec les sélecteurs, et plus précisément ceux-ci :
- $('.parent .enfant') ;
- $('.parent > .enfant').
En effet, nous vous avions expliqué qu'une structure HTML permettait d'imbriquer des blocs les uns dans les autres : ceux étant à l'intérieur sont appelés enfants, ceux qui entourent un élément sont des parents.
Le parcours du DOM va énormément se baser sur ce concept, à retenir et maîtriser absolument.
Nous allons étudier quelques fonctions qui permettent d'accéder aux éléments, qu'ils soient parents, enfants, ou même frères !
Parents, enfants et ancêtres
Commençons par une des fonctions de parcours les plus utilisées : parent().
Plus facile à retenir, tu meurs ! :-p Comme vous vous en doutez, cette méthode va nous permettre d'accéder au bloc parent de l'élément actuellement ciblé.
Lorsque nous agirons sur notre objet jQuery, ce ne sera donc plus ce dernier qui sera influencé, mais bien le bloc qui l'entoure.
$('a').css('color', 'blue'); // rend le lien ciblé seulement de couleur bleue $('a').parent().css('color', 'blue'); // ici, c'est le parent de l'enfant (un paragraphe, si l'on respecte la sémantique) qui verra son texte devenir bleu
Il est possible de préciser la requête, en sélectionnant la classe, l'identifiant et le type de l'élément à récupérer en tant qu'argument :
$('a').parent('.texte'); // retourne seulement l'ensemble des blocs parents ayant la classe .texte
Inversement, la fonction children() permet de cibler l'élément enfant descendant directement de l'élément sélectionné. Cette méthode équivaut donc au sélecteur >, mais permet, comme la fonction parent(), de préciser la recherche avec un argument.
$('div').children(); // cible l'élément enfant direct du bloc div $('div').children('p'); // cible seulement l'ensemble des paragraphes enfants du bloc div
Cette méthode est néanmoins quelque peu restrictive : elle ne va cibler que les enfants directs d'un élément.
Que se passerait-il si l'on voulait récupérer tous les fils et petits-fils d'un bloc ?
On ne pourrait tout simplement pas, ou tout du moins avec children().
Car oui, bien heureusement, jQuery possède la fonction find(), qui va se charger de trouver tous les enfants d'un élément, quelle que soit leur position par rapport à ce dernier !
Il suffit alors de donner le type d'élément à trouver, et find() se charge du reste :
$('body').find('p'); // cible l'ensemble des paragraphes contenus dans le corps du document, quelle que soit leur position !
La dernière méthode usant de ce principe de descendance est parents().
N'oubliez pas le “s”, car elle est légèrement différente de la fonction parent(), et ne s'utilise pas tout à fait de la même façon !
Concrètement, cette dernière retournait seulement la première occurrence trouvée : dès qu'elle tombait sur un parent, elle s'arrêtait sans aller plus loin.
Il se peut que vous vouliez agir sur tous les parents d'un élément en même temps.
Par soucis de précision, on ne parlera ici plus de parents, mais d'ancêtres.
$('a').parents(); // cible tous les éléments ancêtres du lien : paragraphe, bloc(s), balise <body>...
La fraternité d'éléments
Après le père et le grand-père, nous demandons le frère ! :lol: Eh oui, comme pour les méthodes développées précédemment, nous sommes dans l'obligation d'étudier les fonctions ciblant les élément frères de la sélection. Le frère d'un élément, c'est tout simplement la balise présente directement à côté de celui-ci.
Il y a quatre façons de faire appel à ce concept :
- prev(), qui sélectionne l'élément frère précédant directement l'objet ciblé ;
- next(), qui sélectionne l'élément frère suivant directement l'objet ciblé ;
- prevAll(), qui sélectionne tous les éléments frères précédant l'objet ciblé ;
- nextAll(), qui sélectionne tous les éléments frères suivant l'objet ciblé.
Filtrer et boucler les éléments
Moins utilisés mais tout de même d'une praticité flagrante, les filtres et les conditions permettent de cibler des éléments de manière plus précise et concise que les méthodes apparentées à la descendance. En effet, jusqu'ici, vous ne savez que sélectionner les éléments enfants, parents, ancêtres ou frères d'un objet. En revanche, le ciblage par l'index, par exemple, vous est totalement inconnu. Afin de combler ces lacunes, nous vous invitons à lire la suite.
Filtrer les éléments
Filtre par sélecteur
La méthode principale permettant de filtrer des éléments se nomme filter().
Elle va permettre de supprimer tous les objets ne correspondant pas à la recherche de la sélection, ce qui est très pratique dans le cas où vous souhaitez ne récupérer que certains éléments et pas d'autres, dans une recherche plus globale.
La requête est à spécifier en tant qu'argument, et peut être vraiment très précise dans le cas où il est possible de donner plusieurs sélecteurs d'un seul coup en les séparant de virgules !
$('p').filter('.texte'); // supprime de la sélection tous les paragraphes n'ayant pas la classe .texte $('p').filter('.texte, #description'); // supprime de la sélection tous les paragraphes n'ayant pas la classe .texte ou l'identifiant #description
La méthode not() permet de faire la même chose, mais prend en argument les objets à ne pas prendre en compte.
Filtre par index
Vous avez déjà rencontré le sélecteur :eq() plus tôt dans le cours. Il suffisait de l'utiliser avec un index pour sélectionner un élément grâce à celui-ci.
Il existe également la méthode eq() qui elle s'exécute sur un objet.
Elle va donc parcourir le tableau d'occurrences trouvées et sélectionner seulement celui qui possède l'index indiqué en argument.
$('p').eq(2); // cible le troisième paragraphe trouvé (l'index commence à 0)
Petite astuce, vous pouvez spécifier un nombre négatif : jQuery commencera alors à compter à partir du dernier index. Si vous possédez quatre paragraphes et que vous donnez la valeur -1 à la méthode, alors votre objet sera le quatrième paragraphe.
Moins utilisée, la méthode slice() permet de prendre une portion d'un tableau d'objets, grâce à leur index.
Elle prend un argument obligatoire, et un second facultatif :
- start, qui est la position (ou l'index) du premier élément à filtrer ;
- end, qui est la position (ou l'index) du dernier élément à filtrer, non pris en compte par la sélection.
Il s'agit donc littéralement de couper un tableau contenant l'ensemble de nos éléments ciblés.
Seuls ceux étant compris entre les index spécifiés seront gardés, les autres étant alors supprimés de la sélection :
$('div').slice(1, 3); // garde seulement les blocs div ayant l'index 1 ou 2
Vérifier le type d'un élément
La fonction is() est peu utilisée, mais il est bon de la connaître dans le cas où vous rencontrez un code qui la contient pour une quelconque raison.
Elle renvoie simplement un booléen, true si elle déduit que l'argument donné correspond au type de l'élément analysé, false si ce n'est pas le cas :
var vrai = $('div').is('div'); var faux = $('div').is('p'); console.log(vrai); // affiche true console.log(faux); // affiche false
Boucler les éléments
Non content de sa puissance, jQuery révolutionne le concept des boucles en permettant une nouvelle forme : le bouclage d'éléments.
Assez particulier, ce système est toutefois bien utile : il va traiter chaque occurrence trouvée et exécuter une fonction définie dessus. Il s'agit de la méthode each().
Elle va agir sur chaque objet trouvé, en effectuant littéralement une boucle.
Cela va vous permettre par exemple d'exécuter des fonctions qui, normalement, s'arrête au premier élément rencontré, les autres étant laissé à l'abandon.
$('p').each( function(){ alert( $(this).text() ); // $(this) représente l'objet courant } );
Il est possible de récupérer l'index de l'élément courant grâce à un argument, à placer dans la fonction de retour.
Si la fonction retourne false, alors la boucle s'arrête brutalement.
Si au contraire elle retourne true, alors la boucle passe directement à l'élément suivant.
Il existe d'autres utilisations de cette méthodes, notamment avec sa sœur $.each(), mais nous ne les aborderons pas ici car elles ne sont pas vraiment courantes et utilisées.
