11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

J'arrive à faire afficher un vote par catégorie mais j'aimerais qu'il affiche dans <li> qui a été cliqué et non à la fin de mon <ul>.

Je veux pas mettre de ID car je vais avoir plusieurs catégories.

Voici mon code jquery :

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
		<script>
	$(document).ready(function(){
	
	$(".categorie").click(function(){
		$("<div class='monvote'>Vote</div>").appendTo(this);
	
	$(this).each( function(){
		$(this).unbind('click');
		});
	
	});
});

	</script>


Voici mon code HTML :

<p>Catégorie A</p>
<div class="categorie">
<ul>
<li>Prénom 1</li>
<li>Prénom 2</li>
<li>Prénom 3</li>
<li>Prénom 4</li>
</ul>
</div>

<p>Catégorie B</p>
<div class="categorie">
<ul>
<li>Prénom 1</li>
<li>Prénom 2</li>
<li>Prénom 3</li>
<li>Prénom 4</li>
</ul>
</div>

Modifié par britanicus75 (18 Mar 2012 - 00:16)
Lorsque je clique sur une catégorie, un seul prénom peut contenir le mot "vote".

Dans le précédent code le "vote" apparaissait bien qu'une seule fois par catégorie, mais il apparaissait après le </ul>.

Dans le code ci-bas, le mot "vote" apparait bien en dessous du <li> cliqué, mais il apparait sur tous les <li> que je clique.


$(document).ready(function(){
	$(".categorie ul li").click(function(){
		$("<div class='monvote'>vote</div>").appendTo(this);
		$(this).unbind('click');
	});
});
Salut

Heureux que tu aies corrigé ton premier code, pour ton deuxième code si je comprends ta quête, tu voudras désactiver le clique pour que le vote soit unique, sur les éléments d'une catégorie, dans ce cas, ce qui te manque est ainsi:

-Ton code actuel permet de détacher le clique sur le <li> cliqué, et n'en pas aussi sur ces conjoints, pour cela il va falloir que la sélection que tu fournis à unbind destine tous les li de la catégorie qui contient le <li> cliqué.

-Je crois que cela suffira:
$('li',$(this).parent()).unbind('click');
ou bien
$(this).parent().children('li').unbind('click');


Bonne courage
Modifié par unami (18 Mar 2012 - 16:52)
À ce niveau Unami, autant utiliser .on() en délégation et faire un unbind seulement sur <ul>

(j'avais mal compris le problème initialement)


$(document).ready(function(){

	$(".categorie ul").on('click', 'li', function(){

		$("<div class='monvote'>vote</div>").appendTo( $(this) );

		$(this).parents('ul').off('click', 'li');

	});

});

Modifié par Vaxilart (18 Mar 2012 - 17:01)
Oui Vaxilart je sais que tu as mal compris le problème et aussi comme tu dis tu pourras faire recours à on() mais il va falloir être muni d'une version de jquery 1.7 pour le faire Smiley smile .
Modifié par unami (18 Mar 2012 - 17:24)
Oh c'est moi qui s'explique mal. Je veux pouvoir continuer à cliquer au cas où je change d'idée.
C'est comme un effet de hover mais, sur click. Donc le mot vote apparait là où je clique.

ex :
Catégorie A
Mélanie - vote
Isabelle
Bruno

Catégorie B
Jacques
Paul - vote
Patrick

Sauf que je peux changer d'idée et vouloir voter pour Isabelle, donc le mot vote apparait à Isabelle et Mélanie n'a plus le mot vote.
Lol Smiley murf

Dans ce cas tu dois seulement le supprimer de la catégorie et de le remettre sur le <li> souhaité, sans avoir à détacher un événement.

$(document).ready(function(){
$(".categorie ul li").click(function(){
$('.monvote',$(this).parent()).remove();
$("<div class='monvote'>vote</div>").appendTo(this);
});
});


Bonne courage
Modifié par unami (18 Mar 2012 - 17:36)
Mais attention, ajouter et retirer des éléments du dom est couteux en performance.

Tu devrais préférer ajouter ton bloc .monvote à même ton HTML, et le mettre en display: none. Ensuite, joue avec les classes ou .show/.hide pour le montrer et le cacher selon le cas.
a écrit :
Mais attention, ajouter et retirer des éléments du dom est couteux en performance.

Modifié par unami (18 Mar 2012 - 19:31)
unami a écrit :
Mais attention, ajouter et retirer des éléments du dom est couteux en performance.
Tu devrais préférer ajouter ton bloc .monvote à même ton HTML, et le mettre en display: none. Ensuite, joue avec les classes ou .show/.hide pour le montrer et le cacher selon le cas.



Salut Vaxilart, tu disposes d'un article ou d'une référence peut être car ça m'intéresse vraiment de mieux savoir sur ce sujet Smiley smile

D'ailleurs pour la solution que tu as fourni, tu n'auras pas besoin d'impliquer des classes .show/.hide dans l'histoire, si non ça sera une simple gâchis de performance. Smiley smile

Merci d'avance
Modifié par unami (18 Mar 2012 - 19:30)
Eh bien, suffirait de faire un test comme ici (changer les class est sur ce cas 57% plus rapide):

http://jsperf.com/append-vs-addclass

Évidemment, je ne change que les fonctions, en théorie la différence serait encore plus grande sur le cas présent puisque sélectionner le <div> demanderait moins d'opérations au dom.

Alors si tu voudrais faire une comparaison plus complète, tu pourrais utiliser le timer de la console sur Firebug.


console.time('timerName');

// Le code que tu souhaite tester

console.timeEnd('timerName');
Si j'ai plus de 100 choix, est-ce vraiment plus performant d'ajouter tous ces div monvote.

Je suis débutante en jquery et lorsque j'ai fait des tests.

J'avais essayé.
$('.monvote').parent().remove(); évidemment ça donnait pas le résultat voulu.

Mais toi tu mets ton this.parent à l'intérieur et tu le sépares avec la virgule, à quoi sert la virgule?
$('.monvote',$(this).parent()).remove();

Merci.
Modifié par britanicus75 (18 Mar 2012 - 23:21)
Salut

A vaxilart:

Merci pour l'éclaircissement c'est intéressant Smiley smile
Toute fois j'ai essayé avec un exemple similaire plus proche de celui que nous avons dans cette discussion, ici http://jsperf.com/append-remove-vs-addclass-removeclass et j'ai eu 30% au max Smiley smile .

Et j'aimerai bien s'expliquer un peu mieux par rapport à ce que tu disais: Quand tu me parle du DOM ta proposition engendre le reflow sur deux fois, ce qui est le cas pour le append aussi, ce qui veut dire qu'au niveau DOM la question de performance ici, n'a pas d'impact.

Ici j'ai bien pris le cas en considération, car les deux codes exécutés avec firebug ne dépassent pas les 2 ms Smiley smile , alors comme je disais la question n'est pas relative au DOM, car les deux codes mènent des actions sur le DOM, mais plutôt au nombre d'instructions exécutées par les commandes auxquelles chacun de nous fait appel. Alors pour moi quelques ns de différence, n'impactent absolument pas la performance dans ce cas, (Si non si toi tu penses qu'un utilisateur puisse remarquer ces ns, alors là Smiley smile ) idem pour la mémoire.

Pour moi je me casse la tête avec ces question quand j'ai un lourd script ou un script qui s'exécute en boucle comme les caroussel ou le Reel, et c'est sur ce principe que se repose l'outil qui compare les deux codes js, qui les exécutent plusieurs fois, et si cette outil permet une seule exécution (comme pour notre exemple ici Smiley smile ) pour calculer le temps, tu sauras que la différence et quasiment null.

Moi j'ai pas de problème avec la méthode des classes, mais me parler de question de gaspillage de performances ici !! c'est ça que, à mon avis, je le crois exagéré Smiley smile .
Modifié par unami (19 Mar 2012 - 00:45)
Salut

A britanicus75:
$('.monvote').parent().remove();

ici tu pointes sur le parent de .monvote qui est le <li>, et tu le supprimes Smiley smile
$('.monvote',$(this).parent()).remove();

Ici this dinstingue le <li> cliqué, alors on demande de récupérer son parent qui est le <ul>, et à l'intérieur de <ul> (cela pour inclure tous les <li> de la catégorie) on cherche le .monvote pour le supprimer. La commande veut dire alors, chercher moi le .monvote qui sont des élement intérieurs du 2 ème argument ($(this).parent()=<ul> qui contient le <li> cliqué).

Bonne courage.
Modifié par unami (19 Mar 2012 - 00:42)
La performance sur un cas semblable ne se trouve pas au niveau du temps de chargement, ni au nombre de milliseconde que prendra l'exécution. C'est au niveau de la fluidité et de la capacité CPU de l'appareil qui effectue ces opérations.

Et, à ce niveau, il ne faut pas voir seulement cette opération, mais penser qu'en cas d'utilisation réel, la page exécutera d'autres scripts, gardera des éléments en mémoire, réagira à d'autres interactions de l’utilisateur, et de plus, l'ordinateur doit faire rouler le navigateur, les autres onglets ouverts et son système d'exploitation propre. Je ne dis pas que ça fera crashé nécessairement l'ordinateur, mais un gain de 30% en terme de performance est énorme.

Sur un site très basique, tu ne risque pas de remarquer de problème avec ton ordinateur de bureau à 4gig de ram. Mais, il faut bien comprendre qu'il y a plusieurs autres appareils beaucoup moins performants sur le marché (suffit de prendre n'importe quelle tablette). Et c'est surtout à ce niveau que le problème risque de se poser.

Ultimement, adopter un script moins couteux en performance est toujours une bonne pratique, et une sécurité pour le moment où un site sera amené à grandir.
Salut

Pour la CPU et comme tu sais, toute commande est un ensemble d'instructions élémentaires alors généralement quand on parle de performance on parle de temps d'exécution (+-). Et quand tu me parles d'occupation de la CPU ça oui je pourrai le prendre en considération si je développais un programme de la 3D ou une application compliquée de finance, (D'ailleurs pour ce dernier cas les calcules sont faits sur un serveur et même pas avec le javascript les raisons je suppose que tu les connais). Alors à nouveau la question de la CPU ici !!.

Oui je comprends que l'utilisateur puisse avoir une surcharge sur son ordinateur, mais soit en sur que ce n'est pas ce clique qui va lui planter ou lui soulager sa machine, car les 30% sont déduites de la comparaison des deux codes, c a d à une exécution la différence et quelques ns, tu prends aussi en considération le nombre de fois qu'un utilisateur va cliquer sur le bouton ??! à toi d'imaginer le reste, alors si tu penses toujours que ce cumule de ns (qui puisse ne pas dépasser un 0,0 ... 1% de la surcharge de la machine Smiley smile ) puisse t'amener quelque part d'autre alors là, c'est ton avis Smiley smile

Je suis d'accord avec toi quand tu me parles de bonnes pratiques, et au domaine professionnel il y a d'autre coût à part la performance, et sincèrement pour un cas similaire je ne demanderai pas à un de mes développeurs de refaire son code, mais de passer à autre chose, car ce qu'il a fait est bien correcte et quand le cas l'impose on en discuterai, mais absolument pas dans ce cas, aussi n'oublie pas que le test que tu as mené de 57% avec un exemple qui n'était pas proche du cas, a donné 30% avec un exemple plus proche, et souviens toi si tu veux que j'enrichisse aussi mon imagination Smiley cligne (comme tu as fait avec cette guerre que tu as décrit en haut) ici nous avions mets seulement une seule catégorie et imagine toi quand nous aurons une dizaine ou bien quelques vingtaines, crois tu que le temps de parcours de ton DOM sera le même pour ajouter les classes (sur 10 catégories de moyenne de 5 éléments, tu disposeras d'une surcharge de 49 éléments ) ?! ou bien veux tu qu'on parle des inconvénients que puisse avoir ce cas sur le référencement de ton site ?! .

Si on part dans cette voie soit en sûr qu'on terminera pas, alors conclusion de ce que je voulais te dire: dans ce cas aucune différence Smiley smile . et bonne journée
Modifié par unami (19 Mar 2012 - 16:52)