11499 sujets

JavaScript, DOM et API Web HTML5

Bonjour,
chaque id d'une page doit être unique.
Mais quel est le moyen le plus simple en js de vérifier dynamiquement qu'un id est bien unique ?

Par exemple, on peut être dans un cas où les attributions d'IDs sont dynamiques et où plusieurs codes js d'origines diverses peuvent cohabiter.

Je ne débute pas en programmation mais ne suis pas expert js car je me recycle AS3 vers JS.

Au cas où répondre à ma question ne serait pas si simple, mon but final est de faire un composant html+js+etc qui peut se mettre aussi bien dans un page que je crée , que d'être encapsulé dans une page existante que je ne contrôlerais pas.

merci
jm
Bonsoir fmafwo.

"fmafwo" a écrit :
Mais quel est le moyen le plus simple en js de vérifier dynamiquement qu'un id est bien unique ?
Pour connaitre le nombre de ID dans un document HTML, il suffit d'utiliser la fonction javascript : document.querySelectorAll("#un");

voici un exemple qui fonctionne :
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>essai</title>
<script>
window.onload = function ()
{
	var xx = document.querySelectorAll("#un");
	alert("Nombre = " + xx.length);
}
</script>
</head>

<body>
	<div id="un">bla bla</div>
	<div id="un">bla bla</div>
	<div id="un">bla bla</div>
	<div id="un">bla bla</div>
	<div id="un">bla bla</div>
</body>
</html>
La solution techniquement correcte est de parcourir tous les éléments possédant un id pour voir s'il y en a deux ou plus qui ont le même.
Attention, code écrit en live, pas testé. Risque de lenteur si la page est complexe.

var elems = document.querySelectorAll("\u005Bid\u005D");
var map = {};
for (var i=0; i<elems.length; i++) {
var id = elems[ i ].getAttribute('id');
if (map[ id]) {
alert("L'id " + id + " est présent plus d'une fois dans la page");
}
map[ id]=true;
}

Note: \u005B et \u005D sont à remplacer par respectivement un crochet ouvrant et fermant. Le BB Code buggé du forum m'empêche d'utiliser les crochets convenablement.

Maintenant une réponse un peu plus pragmatique: le script ci-dessus sera peut-être un peu lent car il doit parcourir linéairement tous les éléments de la page. si ton but est de faire une API, un script incorporable, passe-partout et sans risque de conflit, la solution raisonnable est de générer des id aléatoires. La technique la plus utilisée est la plus simple: un préfixe commun et un grand nombre aléatoire, comme par exemple "MonScript_AutoID_" + Math.floor(Math.random()*2147483647)). La probabilité que tu génères deux identifiants identiques est de l'ordre de 4.7 * 10^-10. Tu as au moins 1000 fois plus de chances de gagner à l'euro-millions.

A partir de ton id aléatoire, tu peux vérifier, au cas très improbable où ça arriverait quand même, que ton id généré n'existe pas déjà. Ca c'est très simple et très rapide, ça se résume à document.getElementById('XXXXXX')!=null.
Modifié par QuentinC (03 Nov 2013 - 19:22)
merci...je suis épaté par la rapidité des réponses.
je pense effectivement me diriger vers l'ID aléatoire...
bonne fin de we
Bonsoir à toutes et à tous.

Nul besoin de passer par un tableau intermédiaire pour faire les comparaisons.
De plus, on commence la recherche à partir de la balise "BODY", et non sur la totalité du document.
Voici une solution plus courte !

<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Id en double</title>

<script>
window.onload = function ()
{
	var tab = document.body.getElementsByTagName("*");
	for (var z=0; z<(tab.length-1); z++)
		for (var x=z+1; x<tab.length; x++)
			if (tab[z].id == tab[x].id)	alert("l'identifiant '" + tab[z].id + "' est présent plus d'une fois dans la page");
}
</script>
</head>

<body>
<div id="un"></div>
<div id="deux"></div>
<div id="trois"></div>
<div id="un"></div>
<div id="quatre"></div>
<div id="cinq"></div>
<div id="six"></div>
<div id="un"></div>
</body>
</html>
@+
@Tournikoti: Bien vu pour le getElementsByTagName qui est probablement plus rapide que querySelectorAll. Par contre pour la rapidité globale, c'est faux: ton algorithme est de complexité O(n^2), le mien O(n) (ou éventuellement O(n*log(n)) si les maps sont triées en interne mais dans tous les navigateurs que je connais ce n'est pas le cas).
Modifié par QuentinC (06 Nov 2013 - 08:07)
en tout cas, tournikoti, je note le
xxxElement().getElementsByTagName("*")
qui permet pour d'autres besoins, d'avoir tous les enfants même indirects d'un Element !!

Venant d'AS3 j'étais habitué à cibler en suivant l'arborescence stricte mais JS permet un ciblage plus varié et direct ; bien pratique dans certains cas... si on en abuse pas. Faut trouver je pense, la bonne dose pour garder une structure à son code Smiley cligne
Modifié par fmafwo (07 Nov 2013 - 11:10)