Salut,Modifier les éléments du DOM - logo

On a commencé à pouvoir se balader un peu dans le DOM dans l’article précédent. Dans cet article on va commencer pouvoir modifier les éléments du DOM. On va pouvoir accéder aux balises HTML, au texte, aux classes CSS, aux ID et aux attributs.

Introduction courte aujourd’hui. Pour rappel je fais un peu de musique, c’est ce qui m’a inspiré l’exemple qui va suivre, et qu’on va torturer tout au long de cet article que j’ai essayé de construire comme un tutoriel.

Rien à voir avec la qualité des tutoriels des pros du genre…

 

 

innerHTML

.innerHTML permet de récupérer du code HTML dans la console pour afficher quelque chose de particulier, mais cette propriété va surtout nous servir à modifier le contenu HTML d’un élément du DOM.

Reprenons l’exemple du dernier article:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Instruments de musiques</title>
</head>

<body>
<h1>Les instruments utilisés en musiques actuelles</h1>
    <div>
        <ul id="instruments">
          	<li>Guitare</li>
            <li>Basse</li>
            <li>Batterie</li>
        </ul>
    </div>
    <script>
//Ecrire ici le code JAvascript pour fair les tests
	</script>
</body>

</html>

Essayons d’ajouter un instrument à la liste, et un titre après cette liste. Nous pouvons réaliser cela avec innerHTML:

document.getElementById("instruments").innerHTML += "<li>Piano</li>";
document.body.innerHTML += "<h1>Le Blues</h1>";

Si tout s’est bien passé, tu dois avoir des éléments en plus dans ta page web

On vient de voir qu’avec innerHTML on peut ajouter des éléments, mais on peut aussi les supprimer. Pour faire cela, on va ajouter une chaine de caractère («  ») vide sur l’élément que l’on souhaite supprimer, par exemple la « guitare », qui est le premier élément de la liste, donc l’index 0, pour le remplacer par guitare électrique:

//on supprime le li existant
document.getElementsByTagName("li")[0].innerHTML = "";
//on ajoute le nouveau
document.getElementsByTagName("li")[0].innerHTML += "<li>Guitare Electrique</li>";

Petites précisions, je me suis fait surprendre plusieurs fois:

  • ne pas oublier que le signe égale signifie ici « j’assigne »,
  • Toujours cibler précisément ce que l’on souhaite. Il faut donc bien utiliser les instructions qui ciblent un seul élément à la fois. On ne peut pas assigner une propriété quelconque à quelque chose qui n’est pas définit précisément. On reviendra sur ce point de détail mais au combien important la semaine prochaine…

« Donc c’est super avec inner HTML on peut faire du HTML, ajouter et supprimer des choses, donc plus besoin d’avoir un fichier HTML alors?! »

Euh… non, inner HTML ne doit servir qu’à faire de petites modifications, pas à coder un site entier, ça serait trop compliqué et rapidement bordélique. On verra la semaine prochaine , qu’il existe d’autre moyen pour créer des éléments HTML en Javascript plus proprement.

Pour finir, je te propose de vérifier le fichier HTML que le navigateur lit pour afficher ce qu’on lui a demandé:

console.log(document.body);

Comme tu peux le voir, les modifications ont bien été réécrites en HTML sans pour autant avoir modifié une seule ligne de HTML dans le fichier de base. C’est le navigateur qui lit les informations et qui monte la page en fonction de ce qu’on lui donne.

textContent

La propriété text content permet de modifier le contenu textuel d’un élément HTML du DOM.

Il y a une différence notable entre innerHTML et textContent:

  • innerHTML permet de rajouter/modifier des balisesHTML,
  • textContent permet de rajouter/modifier du texte à l’intérieur des balises

Pour illustrer ça, je te propose  de mettre un id à la balise body, que l’on appellera body, parce qu’on a beaucoup d’imagination, puis tu vas tester le code suivant:

console.log(document.getElementById("body").innerHTML);
console.log(document.getElementById("body").textContent);

Voici ce que ça donne, même si je te conseille d’expérimenter ça tout seul…

Nous allons par exemple ajouter un paragraphe sous la liste avec la méthode innerHTML, puis nous allons ajouter du texte dans le paragraphe. N’oublie pas que la balise body comporte désormais un id= »body ».

// Création de la balise paragraphe au sein du body
document.getElementById("body").innerHTML += "<p></p>";
// Ajout du texte dans la balise
document.querySelector("p").textContent = "J'aime pas les cons";
//Vérifions comment cela a été interprété par le navigateur
console.log(document.body);

Tu auras sans doute remarqué que le paragraphe a été ajouté après la balise script! Cela ne change rien au rendu visuel de la page, mais d’un point de vue des règles de l’art ce n’est pas ce qu’on ferait si on avait à coder ceci en HTML directement. C’est donc une des limites de cette méthode pour ajouter des éléments, elle les ajoute automatiquement comme dernier enfant.  Nous verrons la semaine prochaine, d’autre méthode pour ajouter des balises où on veut.

Les attributs

Léger retour à l’article précédent (Javascript, les débuts dans le DOM) où on a rapidement vu des méthodes pour accéder aux éléments du DOM. Il est également possible de cibler directement l’attribut d’un élément comme l’url d’un lien ou la source d’une image par exemple.

La méthode getAttribute cible un élément du DOM et renvoi la valeur de l’attribut dans la console, une url si on cible le href d’un lien par exemple.

Pour commencer, on va ajouter quelques éléments complémentaires à notre document HTML:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Instruments de musiques</title>
</head>

<body id="body">
<h1>Les instruments utilisés en musiques actuelles</h1>
    <div>
        <ul id="instruments">
            <li>Guitare</li>
            <li>Basse</li>
            <li>Batterie</li>
        </ul>
    </div>

<h1>Les constructeurs d'instruments</h1>
    <div>
      <ul id="constructeur">
          <li id="fender" class="guitare basse"><a href="http://www.fender.com">Fender</a></li>
          <li class="guitare"><a href="http://www.gibson.com">Gibson</a></li>
          <li id="dw" class="pour-les-sourds"><a href="http://www.dwdrums.com">DW</a></li>
      </ul>
    </div>
    <script>

	</script>
</body>

</html>

Voici comment on pourrait récupérer l’url du lien:

// on veut récupérer la première url
console.log(document.getElementsByTagName("a")[0].getAttribute("href"));

Raccourci

Pour certains attributs, on peut éviter de retaper getAttribute(« ___ »);, il suffit de noter les méthodes suivantes:

  • .id
  • .href
  • .value

Voici donc le même code vu précédemment mais avec le raccourci:

//Idem que l'exemple au dessus mais avec un code un peu raccourci
console.log(document.getElementsByTagName("a")[0].href);

On peut aussi demander si tel élément a bien tel attribut avec la méthode .hasAttribute(« nom de l’attribut recherché« );

Cette instruction retourne un booléen, puisque l’élément a l’attribut (true) ou il ne l’a pas(false).

//On veut savoir si le 2 eme li possède l'attribut "basse"
console.log(document.getElementsByTagName("li")[1].hasAttribute("basse"));
// => retourne false

 

Ajouter des attributs

Il est possible de créer un élément HTML avec inner HTML, il est désormais possible de lui ajouter des attributs pour pouvoir le cibler ensuite en CSS.

Pour cela on utilise la méthode .setAttribute(« nom », « valeur »).

//On ajoute un id au deuxième titre de la page
document.getElementsByTagName("h1")[1].setAttribute("id", "titre");
//on vérifie dans la console
console.log(document.body);

Cette méthode prend donc 2 paramètres, le nom de l’attribut (id par exemple) et la valeur de celui-ci (menu par exemple).

Comme pour la méthode getAttribute, on bénéficie de raccourci pour certains attributs régulièrement utilisés:

  • id,
  • href,
  • value.

Voici à quoi ressemble le même code vu plus haut avec le raccourci:

// même code avec raccourci
document.getElementsByTagName("h1")[1].id = "titre";
console.log(document.body);

Les classes

Comme pour les id, on peut accéder aux classes d’un élément HTML. On va commencer par voir comment les consulter avant de les modifier ou d’en ajouter. Si tu as déjà fait du HTML et du CSS, j’imagine que c’est le cas,  tu sais déjà qu’un élément HTML peut comporter plusieurs classes. Si tu utilises Bootstrap, je suis sûr que tu vois très bien de quoi je parle…

.classList

La propriété .classList, permet de lister les classes d’un élément. J’insiste sur le fait que l’on ne peut cibler les classes d’un seul élement et non de plusieurs. J’avais oublié ce détail lors d’un exercice, donc j’ai tourné en rond un petit moment avant de comprendre ce qu’il se passait…

Veille donc bien à utiliser .classList avec des méthodes type .getElementById ou querySelector. Les autres renverront « undefined », ce qu’on cherche rarement à obtenir…

Dans notre exemple on peut écrire le code suivant par exemple:

// recherchons quels sont les classes de "Fender
console.log(document.getElementById("fender").classList);// retourne un tableau avec lequelon peut travailler
//Par exemple:
console.log(document.getElementById("fender").classList.length); // retourne le nombre de classe, ici 2
console.log(document.getElementById("fender").classList[0]); // retourn la classe ciblée, ici guitare

Dans la console on obtient un tableau (DOMTokenList), au sein duquel tu retrouves les classes que l’élément possède.

.contains

Cette méthode, .contains, permet de vérifier si l’élément ciblé possède la classe recherchée. Cette méthode va chercher dans la liste des classes de l’éléments si celle qu’on souhaite cibler existe.

Comme pour les id, cette méthode retourne un boolée, puisque l’élément possède la classe (true) ou il ne la possède pas (false).

// regardons si DW possède la classe guitare
console.log(document.getElementById("dw").classList.contains("guitare")); // retourne false

 

Ajouter des classes

Pour ajouter une classe à un élément, on va avoir besoin de cibler la liste des classes avec .classList et d’ajouter l’une ou l’autre des méthodes suivantes:

  • add(« nomDeClasse« ):  pour ajouter une classe,
  • remove(« nomDeClasse« : pour supprimer une classe.

Par exemple:

// On va retirer la classe "pour-les-sourds"par la classe batterie
document.getElementById("dw").classList.remove("pour-les-sourds");
document.getElementById("dw").classList.add("batterie");
console.log(document.body);

On voit que la classe existante a été supprimée et que la nouvelle a été ajoutée. On est obligé de le faire en 2 temps. On ne peut pas tout inscrire sur la même ligne. Voici ce qu’ile ne faut pas faire:

// Par exemple
let nePasFaire = document.querySelector("h1").classList.remove("").add("");

console.log(nePasFaire); // => retourne undefined

N’oublions pas que .classList retourne un tableau(array), donc .add et .remove reviennent à faire .push et .pop quand on travaille sur un tableau. Je ne dis pas non plus qu’il faut utiliser push à la place de add, ça ne fonctionne pas. Le fonctionnement est un peu similaire simplement. C’est en tout cas ce dont à quoi j’ai pensé en faisant des tests avec ces 2 dernières méthodes: add et remove.

C’est tout pour aujourd’hui, on avance petit à petit. On poursuit la semaine prochaine notre exploration du DOM et notre maîtrise de Javascript!

Bon week end,

A la semaine prochaine!!

Guillaume