aboutsummaryrefslogtreecommitdiff
path: root/files/fr/web/api/document_object_model/whitespace/index.html
blob: d13a541dc7217854a8528901b776ce5536f1e58e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
---
title: Gestion des espaces dans le DOM
slug: Web/API/Document_Object_Model/Whitespace
tags:
  - DOM
translation_of: Web/API/Document_Object_Model/Whitespace
---
<h2 id="Le_probl.C3.A8me" name="Le_probl.C3.A8me">Le problème</h2>

<p>La présence d'espaces et de blancs dans le <a href="fr/DOM">DOM</a> peut rendre la manipulation de l'arbre de contenu difficile dans des aspects qu'on ne prévoit pas forcément. Dans Mozilla, tous les espaces et blancs dans le contenu texte du document original sont représentés dans le DOM (cela ne concerne pas les blancs à l'intérieur des balises). (C'est nécessaire en interne afin que l'éditeur puisse conserver le formatage des documents et que l'instruction <code>white-space: pre</code> en <a href="fr/CSS">CSS</a> fonctionne.) Cela signifie que :</p>

<ul>
 <li>il y aura certains nœuds texte qui ne contiendront que du vide, et</li>
 <li>certains nœuds texte commenceront ou se termineront par des blancs.</li>
</ul>

<p>En d'autres termes, l'arbre DOM pour le document qui suit ressemblera à l'image ci-dessous (où « \n » représente un retour à la ligne) :</p>

<pre class="eval">&lt;!-- My document --&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;My Document&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h1&gt;Header&lt;/h1&gt;
  &lt;p&gt;
    Paragraph
  &lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>

<p><img src="https://mdn.mozillademos.org/files/854/whitespace_tree.png" style="height: 306px; width: 618px;"></p>

<p>Ceci peut rendre les choses un peu plus difficiles pour les utilisateurs du DOM qui aimeraient parcourir le contenu, sans se préoccuper des blancs.</p>

<h2 id="Rendre_les_choses_plus_faciles" name="Rendre_les_choses_plus_faciles">Rendre les choses plus faciles</h2>

<p><span id="result_box" lang="fr"><span>On peut formater leur code comme indiqué ci-dessous pour contourner le problème:</span></span></p>

<pre class="brush: html line-numbers  language-html"><code class="language-html"><span class="comment token">&lt;!-- jolie impression conventionnelle
     avec des espaces entre les balises:
 --&gt;</span>
<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>div</span><span class="punctuation token">&gt;</span></span>
 <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>ul</span><span class="punctuation token">&gt;</span></span>
  <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>li</span><span class="punctuation token">&gt;</span></span>Position 1<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>li</span><span class="punctuation token">&gt;</span></span>
  <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>li</span><span class="punctuation token">&gt;</span></span>Position 2<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>li</span><span class="punctuation token">&gt;</span></span>
  <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>li</span><span class="punctuation token">&gt;</span></span>Position 3<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>li</span><span class="punctuation token">&gt;</span></span>
 <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>ul</span><span class="punctuation token">&gt;</span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>div</span><span class="punctuation token">&gt;</span></span>

<span class="comment token">&lt;!-- jolie impression adaptée au problème :
 --&gt;</span>
<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>div</span>
 <span class="punctuation token">&gt;</span></span><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>ul</span>
  <span class="punctuation token">&gt;</span></span><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>li</span><span class="punctuation token">&gt;</span></span>Position 1<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>li</span>
  <span class="punctuation token">&gt;</span></span><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>li</span><span class="punctuation token">&gt;</span></span>Position 2<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>li</span>
  <span class="punctuation token">&gt;</span></span><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>li</span><span class="punctuation token">&gt;</span></span>Position 3<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>li</span>
 <span class="punctuation token">&gt;</span></span><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>ul</span>
<span class="punctuation token">&gt;</span></span><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>div</span><span class="punctuation token">&gt;</span></span></code></pre>

<p>Le code JavaScript ci-dessous définit plusieurs fonctions facilitant la manipulation d'espaces dans le DOM :</p>

<pre class="brush: js line-numbers  language-js"><code class="language-js"><span class="comment token">/**
 * Tout au long, les espaces sont définis comme l'un des caractères
 *  "\t" TAB \u0009
 *  "\n" LF  \u000A
 *  "\r" CR  \u000D
 *  " "  SPC \u0020
 *
 * Ceci n'utilise pas le "\s" de Javascript parce que cela inclut le non-brisement
 * espaces (et aussi d'autres caractères).
 */</span>


<span class="comment token">/**
 * Détermine si le contenu du texte d'un nœud est entièrement blanc.
 *
 * @param nod  Un nœud implémentant l'interface |CharacterData| (c'est-à-dire,
 *             un nœud |Text|, |Comment| ou |CDATASection|
 * @return     True <em>(vrai)</em> Si tout le contenu du texte du |nod| est un espace,
 *             sinon false <em>(faux)</em>.
 */</span>
<span class="keyword token">function</span> <span class="function token">is_all_ws</span><span class="punctuation token">(</span> nod <span class="punctuation token">)</span>
<span class="punctuation token">{</span>
  <span class="comment token">// Utilise ECMA-262 Edition 3 chaînes et fonctionnalités RegExp</span>
  <span class="keyword token">return</span> <span class="operator token">!</span><span class="punctuation token">(</span><span class="regex token">/[^\t\n\r ]/</span><span class="punctuation token">.</span><span class="function token">test</span><span class="punctuation token">(</span>nod<span class="punctuation token">.</span>textContent<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>


<span class="comment token">/**
 * Détermine si le nœud doit être ignoré par les fonctions d'itération.
 *
 * @param nod  Un objet implémentant l'interface DOM1 |Node|.
 * @return     true <em>(vrai)</em> si le nœud est :
 *                1) un nœud |Text| qui est tout en espace
 *                2) un nœud |Comment|
 *             et autrement false <em>(faux)</em>.
 */</span>

<span class="keyword token">function</span> <span class="function token">is_ignorable</span><span class="punctuation token">(</span> nod <span class="punctuation token">)</span>
<span class="punctuation token">{</span>
  <span class="keyword token">return</span> <span class="punctuation token">(</span> nod<span class="punctuation token">.</span>nodeType <span class="operator token">==</span> <span class="number token">8</span><span class="punctuation token">)</span> <span class="operator token">||</span> <span class="comment token">// un nœud commentaire</span>
         <span class="punctuation token">(</span> <span class="punctuation token">(</span>nod<span class="punctuation token">.</span>nodeType <span class="operator token">==</span> <span class="number token">3</span><span class="punctuation token">)</span> <span class="operator token">&amp;&amp;</span> <span class="function token">is_all_ws</span><span class="punctuation token">(</span>nod<span class="punctuation token">)</span> <span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// un nœud texte, tout espace</span>
<span class="punctuation token">}</span>

<span class="comment token">/**
 * Version de |previousSibling| qui ignore les nœuds qui sont entièrement
 * espace ou commentaire.  (Normalement |previousSibling| est une propriété
 * de tous les nœuds DOM qui donnent le nœud frère, le nœud qui est
 * un enfant du même parent, qui se produit immédiatement avant le
 * nœud référence.)
 *
 * @param sib  Le nœud référence .
 * @return     soit :
 *               1) le frère précédent le plus proche de |sib| qui ne peut
 *                  être ignoré du fait de la fonction |is_ignorable|, ou
 *               2) null si aucun nœud n'existe.
 */</span>
<span class="keyword token">function</span> <span class="function token">node_before</span><span class="punctuation token">(</span> sib <span class="punctuation token">)</span>
<span class="punctuation token">{</span>
  <span class="keyword token">while</span> <span class="punctuation token">(</span><span class="punctuation token">(</span>sib <span class="operator token">=</span> sib<span class="punctuation token">.</span>previousSibling<span class="punctuation token">)</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
    <span class="keyword token">if</span> <span class="punctuation token">(</span><span class="operator token">!</span><span class="function token">is_ignorable</span><span class="punctuation token">(</span>sib<span class="punctuation token">)</span><span class="punctuation token">)</span> <span class="keyword token">return</span> sib<span class="punctuation token">;</span>
  <span class="punctuation token">}</span>
  <span class="keyword token">return</span> <span class="keyword token">null</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>

<span class="comment token">/**
 * Version de |nextSibling| qui ignore les nœuds qui sont entièrement
 * espace ou commentaire.
 *
 * @param sib  Le nœud référence .
 * @return     soit :
 *               1) le frère précédent le plus proche de |sib| qui ne peut
 *                  être ignoré du fait de la fonction |is_ignorable|, ou
 *               2) null si aucun nœud n'existe.
 */</span>
<span class="keyword token">function</span> <span class="function token">node_after</span><span class="punctuation token">(</span> sib <span class="punctuation token">)</span>
<span class="punctuation token">{</span>
  <span class="keyword token">while</span> <span class="punctuation token">(</span><span class="punctuation token">(</span>sib <span class="operator token">=</span> sib<span class="punctuation token">.</span>nextSibling<span class="punctuation token">)</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
    <span class="keyword token">if</span> <span class="punctuation token">(</span><span class="operator token">!</span><span class="function token">is_ignorable</span><span class="punctuation token">(</span>sib<span class="punctuation token">)</span><span class="punctuation token">)</span> <span class="keyword token">return</span> sib<span class="punctuation token">;</span>
  <span class="punctuation token">}</span>
  <span class="keyword token">return</span> <span class="keyword token">null</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>

<span class="comment token">/**
 * Version de |lastChild| qui ignore les nœuds qui sont entièrement
 * espace ou commentaire. (Normalement |lastChild| est une propriété
 * de tous les nœuds DOM qui donnent le dernier des nœuds contenus
 * directement dans le nœud de référence.)
 *
 * @param sib  Le nœud référence.
 * @return     soit :
 *               1) Le dernier enfant de |sib| qui ne peut
 *                  être ignoré du fait de la fonction |is_ignorable|, ou
 *               2) null si aucun nœud n'existe.
 */</span>
<span class="keyword token">function</span> <span class="function token">last_child</span><span class="punctuation token">(</span> par <span class="punctuation token">)</span>
<span class="punctuation token">{</span>
  <span class="keyword token">var</span> res<span class="operator token">=</span>par<span class="punctuation token">.</span>lastChild<span class="punctuation token">;</span>
  <span class="keyword token">while</span> <span class="punctuation token">(</span>res<span class="punctuation token">)</span> <span class="punctuation token">{</span>
    <span class="keyword token">if</span> <span class="punctuation token">(</span><span class="operator token">!</span><span class="function token">is_ignorable</span><span class="punctuation token">(</span>res<span class="punctuation token">)</span><span class="punctuation token">)</span> <span class="keyword token">return</span> res<span class="punctuation token">;</span>
    res <span class="operator token">=</span> res<span class="punctuation token">.</span>previousSibling<span class="punctuation token">;</span>
  <span class="punctuation token">}</span>
  <span class="keyword token">return</span> <span class="keyword token">null</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>

<span class="comment token">/**
 * Version de |firstChild| qui ignore les nœuds qui sont entièrement
 * espace ou commentaire..
 *
 * @param sib  le nœud référence.
 * @return     soit:
 *               1) le nœud premier enfant de |sib| qui ne peut
 *                  être ignoré du fait de la fonction |is_ignorable|, ou
 *               2) null si aucun nœud n'existe.
 */</span>
<span class="keyword token">function</span> <span class="function token">first_child</span><span class="punctuation token">(</span> par <span class="punctuation token">)</span>
<span class="punctuation token">{</span>
  <span class="keyword token">var</span> res<span class="operator token">=</span>par<span class="punctuation token">.</span>firstChild<span class="punctuation token">;</span>
  <span class="keyword token">while</span> <span class="punctuation token">(</span>res<span class="punctuation token">)</span> <span class="punctuation token">{</span>
    <span class="keyword token">if</span> <span class="punctuation token">(</span><span class="operator token">!</span><span class="function token">is_ignorable</span><span class="punctuation token">(</span>res<span class="punctuation token">)</span><span class="punctuation token">)</span> <span class="keyword token">return</span> res<span class="punctuation token">;</span>
    res <span class="operator token">=</span> res<span class="punctuation token">.</span>nextSibling<span class="punctuation token">;</span>
  <span class="punctuation token">}</span>
  <span class="keyword token">return</span> <span class="keyword token">null</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>

<span class="comment token">/**
 * Version de |data| cela n'inclut pas les espaces au début
 * et termine et normalise tous les espaces dans un seul espace. (Normalement
 * |data | est une propriété des nœuds de texte qui donne le texte du nœud.)
 *
 * @param txt  Le nœud de texte dont les données doivent être renvoyées
 * @return     Une chaîne donnant le contenu du nœud de texte avec
 *             espace blanc s'est effondré.
 */</span>
<span class="keyword token">function</span> <span class="function token">data_of</span><span class="punctuation token">(</span> txt <span class="punctuation token">)</span>
<span class="punctuation token">{</span>
  <span class="keyword token">var</span> data <span class="operator token">=</span> txt<span class="punctuation token">.</span>textContent<span class="punctuation token">;</span>
  <span class="comment token">// Utilise ECMA-262 Edition 3 chaînes et fonctionnalités RegExp</span>
  data <span class="operator token">=</span> data<span class="punctuation token">.</span><span class="function token">replace</span><span class="punctuation token">(</span><span class="regex token">/[\t\n\r ]+/g</span><span class="punctuation token">,</span> <span class="string token">" "</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
  <span class="keyword token">if</span> <span class="punctuation token">(</span>data<span class="punctuation token">.</span><span class="function token">charAt</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">)</span> <span class="operator token">==</span> <span class="string token">" "</span><span class="punctuation token">)</span>
    data <span class="operator token">=</span> data<span class="punctuation token">.</span><span class="function token">substring</span><span class="punctuation token">(</span><span class="number token">1</span><span class="punctuation token">,</span> data<span class="punctuation token">.</span>length<span class="punctuation token">)</span><span class="punctuation token">;</span>
  <span class="keyword token">if</span> <span class="punctuation token">(</span>data<span class="punctuation token">.</span><span class="function token">charAt</span><span class="punctuation token">(</span>data<span class="punctuation token">.</span>length <span class="operator token">-</span> <span class="number token">1</span><span class="punctuation token">)</span> <span class="operator token">==</span> <span class="string token">" "</span><span class="punctuation token">)</span>
    data <span class="operator token">=</span> data<span class="punctuation token">.</span><span class="function token">substring</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> data<span class="punctuation token">.</span>length <span class="operator token">-</span> <span class="number token">1</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
  <span class="keyword token">return</span> data<span class="punctuation token">;</span>
<span class="punctuation token">}</span></code></pre>

<h2 id="Exemple" name="Exemple">Exemple</h2>

<p>Le code qui suit montre l'utilisation des fonctions présentées plus haut. Il parcourt les enfants d'un élément (dont les enfants sont tous des éléments) pour trouver celui dont le texte est <code>"Ceci est le troisième paragraphe"</code>, et change ensuite l'attribut <code>class</code> et le contenu de ce paragraphe.</p>

<pre class="brush: js line-numbers  language-js"><code class="language-js"><span class="keyword token">var</span> cur <span class="operator token">=</span> <span class="function token">first_child</span><span class="punctuation token">(</span>document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">"test"</span><span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="keyword token">while</span> <span class="punctuation token">(</span>cur<span class="punctuation token">)</span>
<span class="punctuation token">{</span>
  <span class="keyword token">if</span> <span class="punctuation token">(</span><span class="function token">data_of</span><span class="punctuation token">(</span>cur<span class="punctuation token">.</span>firstChild<span class="punctuation token">)</span> <span class="operator token">==</span> <span class="string token">"This is the third paragraph."</span><span class="punctuation token">)</span>
  <span class="punctuation token">{</span>
      cur<span class="punctuation token">.</span>className <span class="operator token">=</span> <span class="string token">"magic"</span><span class="punctuation token">;</span>
      cur<span class="punctuation token">.</span>firstChild<span class="punctuation token">.</span>textContent <span class="operator token">=</span> <span class="string token">"This is the magic paragraph."</span><span class="punctuation token">;</span>
  <span class="punctuation token">}</span>
  cur <span class="operator token">=</span> <span class="function token">node_after</span><span class="punctuation token">(</span>cur<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span></code></pre>

<div class="originaldocinfo">
<h3 id="Informations_sur_le_document_original" name="Informations_sur_le_document_original">Informations sur le document original</h3>

<ul>
 <li>Auteur : <a class="external" href="http://dbaron.org">L. David Baron</a></li>
 <li>Dernière mise à jour : 1er janvier 2003</li>
 <li>Copyright : © 1998-2005 by individual mozilla.org contributors ; contenu disponible sous <a class="external" href="http://www.mozilla.org/foundation/licensing/website-content.html">licence Creative Commons</a></li>
</ul>
</div>