11486 sujets

JavaScript, DOM et API Web HTML5

Bonjour,
Je parviens seulement à modifier le premier <li> de ma liste et je souhaite pouvoir modifier n'importe quel <li>...
Je mets le code qui fonctionne avec un document.querySelector car quand je mets document.querySelectorAll j'ai une erreur dans la console : "TypeError: document.querySelectorAll(...).addEventListener is not a function[En savoir plus]"
Une solution ? Merci !
Je souhaite conserver le modèle présenté ici en objet


<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>Liste desserts</title>
</head>

<body>
    <h1>Desserts</h1>

    <ul>
    	<li>Dessert 1</li>
    	<li>Dessert 2</li>
    </ul>

<script>
class Ajout {

	modifier() {
		// return console.log("ccececece");
	var modifElt = prompt("modifier le nom du dessert :");
	var dessertElt = document.querySelector("li");
	dessertElt.textContent = modifElt;
	}
	
	ajouter() {
	document.querySelector("li").addEventListener("click", this.modifier);	
	}
}
const listeDessert = new Ajout();
listeDessert.ajouter();
</script>
</body>

</html>

Modifié par woubi (19 Jan 2019 - 19:13)
Modérateur
Bonjour,

document.querySelectorAll renvoie une liste d'éléments sous forme d'une sorte de tableau.

Il faut que tu fasses des document.querySelectorAll("li")[n].addEventListener("click", this.modifier); n étant un nombre compris entre 0 et ton nombre de li moins 1.

Amicalement,
Merci! J'ai pu avancer mais j'ai encore du mal.
Je peux maintenant sélectionner tous les li mais ils ne sont pas modifiable !! J'ai l'erreur : ReferenceError: i is not defined
Le code ci-dessous :

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>Liste desserts</title>
</head>

<body>
    <h1>Desserts</h1>

    <ul>
    	<li>Dessert 1</li>
    	<li>Dessert 2</li>
    </ul>

<script>
class Ajout {

	modifier() {

	var modifElt = prompt("modifier le nom du dessert :");
	var dessertElt = document.querySelectorAll("li")[i];
	dessertElt.textContent = modifElt;
	}
	
	ajouter() {
	var divs = document.querySelectorAll("li"), i;
	for (i = 0; i < divs.length; ++i) {
	  divs[i].addEventListener("click", this.modifier);	
		}
	
	}
}
const listeDessert = new Ajout();
listeDessert.ajouter();
</script>
</body>

</html>

Merci
Modérateur
Bonjour,

Ce qu'il y a de bien avec javascript ES6 par rapport aux versions précédentes, c'est qu'avant c'était difficile de s'y retrouver, alors que maintenant, on a l'assurance de ne plus rien comprendre (certains y verront peut-être un progrès dans le sens où maintenant on est sûr du résultat).

Il y a dans ce ES6 tous les ingrédients pour fabriquer des nids à bug par conteneur entier, et des pertes de temps en quantité industrielle pour ceux qui essaieront de comprendre le code des autres.

Mais ça, a priori, ce n'était pas le soucis de ses concepteurs.

Bon, passons donc au problème posé par woubi "qui a du mal" (et ça, on le comprend bien, contrairement à son code). Smiley cligne

Cher woubi, tu as donc ta classe Ajout, qui contient 2 méthodes : "modifier" et "ajouter". Jusque là, tout est clair et tout va bien.

Mais là où ça se corse, c'est que tu "ajoutes" la méthode "modifier" de la classe "Ajout" en tant que fonction se déclenchant lors d'un clic sur un "li" (donc pas du tout un objet de la classe "Ajout").

Et évidemment, ça ne marche pas tel que tu l'as écrit. Le problème, c'est la variable "i" : elle n'est pas définie dans la méthode "modifier", ni dans un autre endroit où cette méthode pourrait "voir" sa valeur. La variable "i" est certes définie dans la méthode "ajouter", mais cela ne suffira pas pour qu'elle soit aussi "visible" dans la méthode "modifier" lorsque cette méthode sera exécutée suite à un clic sur un "li". D'où le message d'erreur que tu obtiens.

Et même si "i" était "visible" dans la méthode "modifier", elle n'aurait probablement pas la bonne valeur au moment du clic.

Pour corriger ce problème, on a des solutions variées. L'une d'entre elles consiste à utiliser la variable "this" dans la méthode "modifier", car cette variable contiendra l'élément "li" sur lequel tu auras cliqué, et non pas un objet de la classe "Ajout" (bref, tordu, mais miraculeux). Par exemple :

class Ajout {
	modifier() {
		var modifElt = prompt("modifier le nom du dessert :");
		// lors d'un clic sur un "li"
		// le this ci-dessous contiendra ce "li"
		this.textContent = modifElt; 
	}
	ajouter() {
		var divs = document.querySelectorAll("li"), i;
		for (i = 0; i < divs.length; i++) {
			// le this ci-dessous contiendra un objet de la classe "Ajout"
			divs[i].addEventListener("click", this.modifier);	
		}
	}
}
const listeDessert = new Ajout();
listeDessert.ajouter();


Amicalement,
Modifié par parsimonhi (20 Jan 2019 - 01:38)
Meilleure solution
Bonjour
Merci pour l'explication!
En suivant l'exemple j'ai voulu aller un peu plus loin! Ca sort un peu de la première question mais j'ai ajouté la possibilité d'ajouter des desserts et la je comprends pas pourquoi mais je n'ai pas d'écouteurs d’événements sur mes nouveaux <li> créés.
En d'autres termes je ne parviens pas à modifier les <li> créés en plus !
Une autre solution peut être avec le modèle orienté objet ? Merci !!
Voilà le code (j'ai ajouté une balise <button> et un id sur le <ul> dans le html)


<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>Liste desserts</title>
</head>

<body>
    <h1>Desserts</h1>

    <ul id="desserts">
    	<li>Dessert 1</li>
    	<li>Dessert 2</li>
    </ul>
    <button>Ajouter un dessert</button>
<script>
class Ajout {

	modifier() {
		// return console.log("ccececece");
	var modifElt = prompt("modifier le nom du dessert :");
	// var dessertElt = document.querySelectorAll("li")[i];
	this.textContent = modifElt;
	}
	
	ajouter() {
	var divs = document.querySelectorAll("li"), i;
	for (i = 0; i < divs.length; ++i) {
	  divs[i].addEventListener("click", this.modifier);	
		}
	}

	creer() {
	var nomElt = prompt("ajouter un dessert");
	var modifElt = document.createElement("li"); // Création d'un élément li
	modifElt.textContent = nomElt; // Définition de son contenu textuel
	document.getElementById("desserts").appendChild(modifElt);
	}

	ajouter2() {
	document.querySelector("button").addEventListener("click", this.creer);	
	}
}
const listeDessert = new Ajout();

listeDessert.ajouter2();
listeDessert.ajouter();
</script>
</body>

</html>

Modifié par woubi (20 Jan 2019 - 23:59)
Modérateur
Bonjour,

Quand tu crées un nouveau "li", il n'a pas d'écouteur. Or, "listeDessert.ajouter();" est exécutée avant que tu n'ajoutes un dessert via ton "this.creer". Du coup, ton nouveau "li" n'a jamais l'occasion d'avoir un écouteur.

Il faut ajouter cet écouteur à chaque création d'un nouveau "li" à la fin de la méthode "creer".

Amicalement,