Je repasse de temps en temps poser des questions pour l'appli en
JavaScript dont je nettoie le code en l'améliorant. J'avais déjà
demandé comment faire pour ajouter des éléments de façon dynamique,
et on m'avait répondu « cloneNode() ».
Ce que je voudrais savoir, c'est comment la fonction se comporte sur un
n½ud (ou des sous-n½uds) avec un attribut id. En effet, par définition,
un id est unique sur l'ensemble du document, et c'est même ce qui permet
d'accéder à un élément directement par getElementById.
Pour clarifier ma pensée, voici un petit bout de code parsemé de
questions sous forme de commentaires.
{
var fieldset = document.getElementById("un_fieldset");
var ref_div = document.getElementById("div_de_reference");
// div_de_reference contient des boutons, des checkboxes, etc.
var new_div = ref_div.cloneNode();
// ai-je le droit de faire ça, sachant que cela duplique l'id,
// en l'occurrence "div_de_reference" ?
fieldset.appendChild(new_div);
// c'est peut-être ça que je n'ai pas le droit de faire
// à moins de changer d'id ?
}
...
// là il se passe plein de choses, en particulier je modifie le contenu
// de new_div, puis je retourne dans la fonction ci-dessus
...
{
var fieldset = document.getElementById("un_fieldset");
var ref_div = document.getElementById("div_de_reference");
// lequel vais-je récupérer ? celui de base ? ou son clone qui,
// je le rappelle, a vu son contenu modifié après clonage ?
var new_div = ref_div.cloneNode();
fieldset.appendChild(new_div);
// mêmes questions que précédemment : ai-je le droit de faire ça ?
}
Tu veux bien détailler dans quels cas on est obligés d'utiliser setAttribute et dans quels cas on peut s'en dispenser ?
Dans le cas d'un document HTML, le DOM HTML est utilisable: http://www.yoyodesign.org/doc/w3c/dom2/html/Overview.html
Utilisable aussi sur un document XHTML 1.0.
-- Bobe (Aurélien Maille) http://webnaute.net
"la vie d'un geek est un combat perpétuel contre l'imperfection"
Bobe
Olivier Miakinen nous a dit le 10/12/2004 00:47:
Nous sommes d'accord. Ma question était plutôt de savoir, s'il y a deux éléments avec le même id, lequel sera récupéré par un getElementById. Mais comme je vais changer l'id avant l'insertion la question ne se posera pas, en fait.
Comme chaque identifiant utilisé dans le document doit être unique, la question ne se pose pas. Se la poser revient à tenter d'imaginer le comportement que va avoir le navigateur.
Dans l'idéal, une erreur javascript devrait être retournée, mais comme il a été dit plus haut, ce n'est apparamment pas le cas.
-- Bobe (Aurélien Maille) http://webnaute.net
"la vie d'un geek est un combat perpétuel contre l'imperfection"
Olivier Miakinen nous a dit le 10/12/2004 00:47:
Nous sommes d'accord. Ma question était plutôt de savoir, s'il y a deux
éléments avec le même id, lequel sera récupéré par un getElementById.
Mais comme je vais changer l'id avant l'insertion la question ne se
posera pas, en fait.
Comme chaque identifiant utilisé dans le document doit être unique, la
question ne se pose pas. Se la poser revient à tenter d'imaginer le
comportement que va avoir le navigateur.
Dans l'idéal, une erreur javascript devrait être retournée, mais comme
il a été dit plus haut, ce n'est apparamment pas le cas.
--
Bobe (Aurélien Maille)
http://webnaute.net
"la vie d'un geek est un combat perpétuel contre l'imperfection"
Nous sommes d'accord. Ma question était plutôt de savoir, s'il y a deux éléments avec le même id, lequel sera récupéré par un getElementById. Mais comme je vais changer l'id avant l'insertion la question ne se posera pas, en fait.
Comme chaque identifiant utilisé dans le document doit être unique, la question ne se pose pas. Se la poser revient à tenter d'imaginer le comportement que va avoir le navigateur.
Dans l'idéal, une erreur javascript devrait être retournée, mais comme il a été dit plus haut, ce n'est apparamment pas le cas.
-- Bobe (Aurélien Maille) http://webnaute.net
"la vie d'un geek est un combat perpétuel contre l'imperfection"
Pourquoi pas ? Faut bien que j'amortisse mon stage de dactylo :)
Sébastien
Olivier Miakinen wrote:
Tu peux mettre à jour l'ID avec setAttribute( ).
Pourquoi avec setAttribute ? On travaille -- de toute évidence -- sur un document HTML ou XHTML, on peut donc utiliser l'attribut id et écrire : new_div.id = idString
Tu veux bien détailler dans quels cas on est obligés d'utiliser setAttribute et dans quels cas on peut s'en dispenser ? J'aimerais bien acquérir les bonnes pratiques dès le départ, autant qu'il m'est possible de le faire.
Dans ce cas on peut se dispenser de setAttribute( ) parce que la propriété id est accessible à tous les éléments d'une page (X)HTML, tout comme title, lang, dir, className et d'autre selon les éléments sur lesquels tu travailles. La recommandation : <http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html>
setAttribute( ) est vraiment utile dans une page XML (pas (X)HTML) dans laquelle tu utilises tes propres éléments.
Olivier Miakinen wrote:
Tu peux mettre à jour l'ID avec setAttribute( ).
Pourquoi avec setAttribute ? On travaille -- de toute évidence --
sur un document HTML ou XHTML, on peut donc utiliser l'attribut id
et écrire :
new_div.id = idString
Tu veux bien détailler dans quels cas on est obligés d'utiliser
setAttribute et dans quels cas on peut s'en dispenser ? J'aimerais bien
acquérir les bonnes pratiques dès le départ, autant qu'il m'est possible
de le faire.
Dans ce cas on peut se dispenser de setAttribute( ) parce que la
propriété id est accessible à tous les éléments d'une page (X)HTML, tout
comme title, lang, dir, className et d'autre selon les éléments sur
lesquels tu travailles.
La recommandation :
<http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html>
setAttribute( ) est vraiment utile dans une page XML (pas (X)HTML) dans
laquelle tu utilises tes propres éléments.
Pourquoi avec setAttribute ? On travaille -- de toute évidence -- sur un document HTML ou XHTML, on peut donc utiliser l'attribut id et écrire : new_div.id = idString
Tu veux bien détailler dans quels cas on est obligés d'utiliser setAttribute et dans quels cas on peut s'en dispenser ? J'aimerais bien acquérir les bonnes pratiques dès le départ, autant qu'il m'est possible de le faire.
Dans ce cas on peut se dispenser de setAttribute( ) parce que la propriété id est accessible à tous les éléments d'une page (X)HTML, tout comme title, lang, dir, className et d'autre selon les éléments sur lesquels tu travailles. La recommandation : <http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html>
setAttribute( ) est vraiment utile dans une page XML (pas (X)HTML) dans laquelle tu utilises tes propres éléments.
YD
Olivier Miakinen wrote:
[...] dans quels cas on est obligés d'utiliser setAttribute et dans quels cas on peut s'en dispenser ? J'aimerais bien acquérir les bonnes pratiques dès le départ, autant qu'il m'est possible de le faire.
Dans ce cas on peut se dispenser de setAttribute( ) parce que la propriété id est accessible à tous les éléments d'une page (X)HTML, tout comme title, lang, dir, className et d'autre selon les éléments sur lesquels tu travailles. La recommandation : <http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html>
setAttribute( ) est vraiment utile dans une page XML (pas (X)HTML) dans laquelle tu utilises tes propres éléments.
J'ajouterai que dans le cas des navigateurs on travaille sur des objets "préconstruits" (les éléments HTML) qui sont instanciés avec toutes leurs propriétés. Donc si on clone ou si on crée un <input type="checkbox"> on a accès à un objet fini avec ses propriétés.
Autrement dit, dans le cas d'un élément (X)HTML manipulé par un navigateur, on peut se dispenser de setAttribute.
La différence est, puisqu'il y en a une, qu'avec les navigateurs Gecko, le positionnement avec setAttribute écrit l'attribut dans la balise (visible en observant document.body.innerHTML) alors que le positionnement par script /ne l'écrit pas forcément/... truc.id=aString -> écrit dans la balise truc.checked=true -> non écrit mais pris en compte truc.setAtttribute("checked","true") -> écrit et pris en compte
Pour ceux que ça pourrait amuser, tester dans plusieurs navigateurs :
var a=document.createElement("input"); a.type="checkbox"; a.id="cb"; document.body.appendChild(a); a.setAttribute("checked","");//après insertion à cause d'IE !!! onload=function(){alert(document.body.innerHTML)}
Puis remplacer a.setAttribute("checked",""); par a.checkedúlse
En déduire la méthode la plus robuste.
-- Y.D.
Olivier Miakinen wrote:
[...] dans quels cas on est obligés d'utiliser
setAttribute et dans quels cas on peut s'en dispenser ? J'aimerais bien
acquérir les bonnes pratiques dès le départ, autant qu'il m'est possible
de le faire.
Dans ce cas on peut se dispenser de setAttribute( ) parce que la
propriété id est accessible à tous les éléments d'une page (X)HTML, tout
comme title, lang, dir, className et d'autre selon les éléments sur
lesquels tu travailles.
La recommandation :
<http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html>
setAttribute( ) est vraiment utile dans une page XML (pas (X)HTML) dans
laquelle tu utilises tes propres éléments.
J'ajouterai que dans le cas des navigateurs on travaille sur des objets
"préconstruits" (les éléments HTML) qui sont instanciés avec toutes leurs
propriétés. Donc si on clone ou si on crée un <input type="checkbox"> on a
accès à un objet fini avec ses propriétés.
Autrement dit, dans le cas d'un élément (X)HTML manipulé par un navigateur,
on peut se dispenser de setAttribute.
La différence est, puisqu'il y en a une, qu'avec les navigateurs Gecko, le
positionnement avec setAttribute écrit l'attribut dans la balise (visible
en observant document.body.innerHTML) alors que le positionnement par script
/ne l'écrit pas forcément/...
truc.id=aString -> écrit dans la balise
truc.checked=true -> non écrit mais pris en compte
truc.setAtttribute("checked","true") -> écrit et pris en compte
Pour ceux que ça pourrait amuser, tester dans plusieurs navigateurs :
var a=document.createElement("input");
a.type="checkbox";
a.id="cb";
document.body.appendChild(a);
a.setAttribute("checked","");//après insertion à cause d'IE !!!
onload=function(){alert(document.body.innerHTML)}
Puis remplacer a.setAttribute("checked",""); par a.checkedúlse
[...] dans quels cas on est obligés d'utiliser setAttribute et dans quels cas on peut s'en dispenser ? J'aimerais bien acquérir les bonnes pratiques dès le départ, autant qu'il m'est possible de le faire.
Dans ce cas on peut se dispenser de setAttribute( ) parce que la propriété id est accessible à tous les éléments d'une page (X)HTML, tout comme title, lang, dir, className et d'autre selon les éléments sur lesquels tu travailles. La recommandation : <http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html>
setAttribute( ) est vraiment utile dans une page XML (pas (X)HTML) dans laquelle tu utilises tes propres éléments.
J'ajouterai que dans le cas des navigateurs on travaille sur des objets "préconstruits" (les éléments HTML) qui sont instanciés avec toutes leurs propriétés. Donc si on clone ou si on crée un <input type="checkbox"> on a accès à un objet fini avec ses propriétés.
Autrement dit, dans le cas d'un élément (X)HTML manipulé par un navigateur, on peut se dispenser de setAttribute.
La différence est, puisqu'il y en a une, qu'avec les navigateurs Gecko, le positionnement avec setAttribute écrit l'attribut dans la balise (visible en observant document.body.innerHTML) alors que le positionnement par script /ne l'écrit pas forcément/... truc.id=aString -> écrit dans la balise truc.checked=true -> non écrit mais pris en compte truc.setAtttribute("checked","true") -> écrit et pris en compte
Pour ceux que ça pourrait amuser, tester dans plusieurs navigateurs :
var a=document.createElement("input"); a.type="checkbox"; a.id="cb"; document.body.appendChild(a); a.setAttribute("checked","");//après insertion à cause d'IE !!! onload=function(){alert(document.body.innerHTML)}
Puis remplacer a.setAttribute("checked",""); par a.checkedúlse
En déduire la méthode la plus robuste.
-- Y.D.
YD
Oui. Il fallait bien que je me trompe au moins une fois en rédigeant mon article. Dans le vrai code JavaScript j'ai bien mis "true".
:-)
fieldset.appendChild(new_div); // c'est peut-être ça que je n'ai pas le droit de faire // à moins de changer d'id ?
Exact. Il faut modifier l'id. Personnellement, j'effectue toutes les transformations *avant* l'insertion dans le document.
[...] Ma question était plutôt de savoir, s'il y a deux éléments avec le même id, lequel sera récupéré par un getElementById. Mais comme je vais changer l'id avant l'insertion la question ne se posera pas, en fait.
Je ne pense pas qu'il y ait une règle absolue, le traitement des erreurs dans le document doit être "implementation dependent". Comme il a été dit dans le fil, le premier rencontré dans le parcours de l'arbre est généralement retourné.
J'ai instinctivement tendance à me méfier des variables globales, même quand je ne le devrais pas. Après réflexion, je crois que je vais suivre ton conseil (pas pour le fieldset, en revanche, car lui changera d'un appel à l'autre).
Pourquoi ? Tu en utilises de toute façon ! Les fonctions javascript en font partie. La seule précaution, que tu dois connaître, est d'effectuer leur affectation après le chargement de la page dans un gestionnaire onload si les variables référencent un élément HTML.
var new_div = ref_div.cloneNode(); fieldset.appendChild(new_div); // mêmes questions que précédemment : ai-je le droit de faire ça ?
Et même réponse, manipule-le avant l'insertion. Ça évitera au navigateur de redessiner éventuellement plusieurs fois les contrôles...
.... sauf que parfois cela ne marche pas sous IE, par exemple pour l'histoire de l'attribut "checked" dans une checkbox...
Je n'y pensais plus au checked remis à false lors de l'insertion... Moralité : tester et retester... (cf. autre article, mêmes jour et heure)
-- Y.D.
Oui. Il fallait bien que je me trompe au moins une fois en rédigeant mon
article. Dans le vrai code JavaScript j'ai bien mis "true".
:-)
fieldset.appendChild(new_div);
// c'est peut-être ça que je n'ai pas le droit de faire
// à moins de changer d'id ?
Exact. Il faut modifier l'id. Personnellement, j'effectue toutes les
transformations *avant* l'insertion dans le document.
[...] Ma question était plutôt de savoir, s'il y a deux
éléments avec le même id, lequel sera récupéré par un getElementById.
Mais comme je vais changer l'id avant l'insertion la question ne se
posera pas, en fait.
Je ne pense pas qu'il y ait une règle absolue, le traitement des erreurs dans
le document doit être "implementation dependent". Comme il a été dit dans le
fil, le premier rencontré dans le parcours de l'arbre est généralement
retourné.
J'ai instinctivement tendance à me méfier des variables globales, même
quand je ne le devrais pas. Après réflexion, je crois que je vais suivre
ton conseil (pas pour le fieldset, en revanche, car lui changera d'un
appel à l'autre).
Pourquoi ? Tu en utilises de toute façon ! Les fonctions javascript en font
partie. La seule précaution, que tu dois connaître, est d'effectuer leur
affectation après le chargement de la page dans un gestionnaire onload si
les variables référencent un élément HTML.
var new_div = ref_div.cloneNode();
fieldset.appendChild(new_div);
// mêmes questions que précédemment : ai-je le droit de faire ça ?
Et même réponse, manipule-le avant l'insertion. Ça évitera au navigateur de
redessiner éventuellement plusieurs fois les contrôles...
.... sauf que parfois cela ne marche pas sous IE, par exemple pour
l'histoire de l'attribut "checked" dans une checkbox...
Je n'y pensais plus au checked remis à false lors de l'insertion...
Moralité : tester et retester... (cf. autre article, mêmes jour et heure)
Oui. Il fallait bien que je me trompe au moins une fois en rédigeant mon article. Dans le vrai code JavaScript j'ai bien mis "true".
:-)
fieldset.appendChild(new_div); // c'est peut-être ça que je n'ai pas le droit de faire // à moins de changer d'id ?
Exact. Il faut modifier l'id. Personnellement, j'effectue toutes les transformations *avant* l'insertion dans le document.
[...] Ma question était plutôt de savoir, s'il y a deux éléments avec le même id, lequel sera récupéré par un getElementById. Mais comme je vais changer l'id avant l'insertion la question ne se posera pas, en fait.
Je ne pense pas qu'il y ait une règle absolue, le traitement des erreurs dans le document doit être "implementation dependent". Comme il a été dit dans le fil, le premier rencontré dans le parcours de l'arbre est généralement retourné.
J'ai instinctivement tendance à me méfier des variables globales, même quand je ne le devrais pas. Après réflexion, je crois que je vais suivre ton conseil (pas pour le fieldset, en revanche, car lui changera d'un appel à l'autre).
Pourquoi ? Tu en utilises de toute façon ! Les fonctions javascript en font partie. La seule précaution, que tu dois connaître, est d'effectuer leur affectation après le chargement de la page dans un gestionnaire onload si les variables référencent un élément HTML.
var new_div = ref_div.cloneNode(); fieldset.appendChild(new_div); // mêmes questions que précédemment : ai-je le droit de faire ça ?
Et même réponse, manipule-le avant l'insertion. Ça évitera au navigateur de redessiner éventuellement plusieurs fois les contrôles...
.... sauf que parfois cela ne marche pas sous IE, par exemple pour l'histoire de l'attribut "checked" dans une checkbox...
Je n'y pensais plus au checked remis à false lors de l'insertion... Moralité : tester et retester... (cf. autre article, mêmes jour et heure)