Retour à la catégorie - Programmation | Accueil A525G | Commentaires

Livres Livres sur le langage JavaScript

Atelier d'introduction aux composants HTML (HTC)

Réutilisation de code javascript

Les versions 4 de Netscape et d'Internet explorer ont offert aux développeurs de pages web des langages de script évolués, permettant à ceux-ci de faire la création de pages web dotées de beaucoup d'interactivité coté client. Le seul manque à tout ca par contre, c'était un modèle de composant! En effet, le seul moyen connu de réutiliser du code était les fichiers avec extenssion js. De tel fichiers contiennent une série de lignes de code javascrit. Vous pouvez faire une référence à ceux-ci dans vos pages html. Avec les fichiers js ou l'inclusion direct de script dans les pages html, il en résultait toujours en un grand regroupement de script, pas toujours très clair. De plus, les lignes créées avec de tel code javascript pouvaient être influencé par une feuille de style interne ou greffé à une page web.

Microsoft propose une solution à tout ca avec les composants HTML, mis au monde avec Internet Explorer 5. Ceux si fournisse au développeur le pouvoir d'implémentation de composants avec des scripts. Ceux-ci sont savegardez sous l'extenssion « .htc ». Ils sont formés de scripts et d'un certain nombre d'éléments spécifiques aux composants HTML.

Note : Si vous en lisant ces lignes, vous vous attendez à trouver une solution pouvant convenir à plusieurs type de navigateurs, notemment Netscape, vous pouvez cesser la lecture ici car, je préfère vous prévenir que cette technologie est malheureusement propre à Microsoft et à son navigateur. Les composants que vous pourrez développer ne fonctionneront qu'avec Internet Explorer 5+, à moi bien sur que d'autres compagnie viennent à adopter cette technologie.

En fait, je trouve qu'une telle technologie peut se révéler très utile si vous prévoyez développer un groupe restreint de pages dans votre site qui seront utiliser comme une aplication. Dans un tel cas, il est plus facile de garder une clientèle générale pour la majorité de vos pages et offrir un petit plus à ceux qui possèdent IE5+. La technologie peut se révélé aussi très utile dans le confection d'un Intranet si vous prévoyez que tout les gens qui l'utiliseront se serviront d'Internet Explorer et que vous pourrez exercer un contrôle sur le type de navigateur accédant aux applications.

Le présent atelier vous propose d'abord une description des éléments et de la structure d'un objet HTML et ensuite, la création de deux composants visant à être utiliser conjointement.

Voici la liste des éléments (ou objets) proposés par Microsoft avec cette technologie.

PUBLIC:ATTACH

Utiliser pour lier une fonction à un événement particulié.

Syntaxe :

<PUBLIC:ATTACH
EVENT = "evenement"
FOR = "objet"
ID = "identifiant"
ONEVENT = "fonction à executer"
/>

PUBLIC:COMPONENT

Pour spécifier que le contenu du fichier est un composant HTML

Syntaxe :

<PUBLIC:COMPONENT
ID = "identifiant"
lightWeight = "valeur booléenne spécifiant si le composant contient ou non des balises"
literalContent = "chaine spécifiant si oui ou non le contenu est analysé ou traité comme un ilôt de données"
NAME = "nom"
supportsEditMode = "valeur booléenne spécifiant si le contenu du composant est éditable ou non"
tagName = "chaine spécifiant le nom de la balise représentant le composant"
URN = "chaine de type (URN) qui sert à rendre l'identification du composant unique"
> </PUBLIC:COMPONENT>

PUBLIC:DEFAULTS

Assigner une propriété par défaut à un composant de tel sorte que lorsque vous écrivez seulement le nom de celui-ci, suivi de l'opérateur d'affectation et d'une valeur, cette valeur soit affecté à la propriété spécifié.

Syntaxe :

<PUBLIC:DEFAULTS
canHaveHTML = "valeur booléenne spécifiant si le composant peut contenir des balises"
contentEditable = "valeur spécifiant si oui ou non, le contenu du composant est éditable"
style = "Chaine définissant le style de la balise définit par le composant"
tabStop = "valeur booléenne spécifiant si le composant est actif ou inactif à la tabulation"
viewInheritStyle = "valeur booléene spécifique à «Viewlink» (nouveauté de IE6)"
viewLinkContent = "valeur booléene spécifique à «Viewlink» (nouveauté de IE6)"
viewMasterTab = "valeur booléene spécifique à «Viewlink» (nouveauté de IE6)"
/>

PUBLIC:EVENT

Associer un événement à l'objet

Syntaxe :

<PUBLIC:EVENT
ID = "identifiant"
NAME = "nom"
/>

La méthode utilisé conjointement avec cet objet est "fire", permettant de déclencher l'événement lui étant passé en paramètre.

PUBLIC:METHOD

Syntaxe :

Définir une méthode associée au composant.

<PUBLIC:METHOD
ID = "identifiant"
INTERNALNAME = "chaine spécifiant le nom par lequel la méthode est appelée à dans le fichier du composant."
NAME = "chaine spécifiant le nom par lequel la méthode est référée dans le document contenant le composant"
/>

PUBLIC:PROPERTY

Définition d'une propriété du composant qui sera utilisable via le document contenant le composant.

Syntaxe :

<PUBLIC:PROPERTY
GET = "chaine permettant d'associer une fonction déclenché lorsque la valeur de la propriété est demandée par le client. Lorsque vous déclarer une propriété en ne mentionnant pas l'attribut PUT mais uniquement l'attribut GET, la propriété est en lecture seul."
ID = "identifiant"
INTERNALNAME = "Chaine spécifiant le nom par lequel la propriété est appelée dans le fichier du composant."
NAME = "Chaine spécifiant le nom par lequel la propriété est appelé dans le document contenant le composant."
PERSIST = "bPersist"
PUT = "chaine permettant d'associer une fonction déclanché lorsque la valeur de la propriété tente d'être affectée par le client."
VALUE = "valeur spécifiant la valeur par défaut de la propriété."
/>

Notons aussi les éléments «document» et «element».

Mis à part les objets, il existe une série de quatre événements pouvant être associés au composant. Voici la liste de ceux-ci :

  • oncontentready : Déclenché lorsque le composant lui-même a été complètement analysé.
  • ondocumentready : Déclenché lorsque le contenu du document contenant le composant a été complètement analysé.
  • ondetach : Déclenché avant qu'un composant soit détaché d'un élément.
  • oncontentsave : Déclenché avant que le contenu d'un élément attaché à un composant soit sauvegardé ou copié.

Atelier

L'atelier, tel que mentionné ci-dessus, propose la création de deux composants inter-reliés. Ceux-ci se nomme « dynamiccontainer » et « dynamicbox ».

dynamiccontainer

Le composant « dynamiccontainer » sert de contenant à un ou plusieurs composants « dynamicbox ».

dynamicbox

Le composant « dynamicbox » est un composant représenté par une zone rectangulère divisée en trois parties. Une zone de titre, une zone de contenu et finalement, une zone composé de petits icônes comportant chacun une utilité bien précise, soit, le déplacement d'un composant à l'intérieur de son contenant, soit, la réduction du composant ou son agrandissement.

Voici le listing du composant « dynamiccontainer »

Note : Les composants si dessous ne sont pas encore optimisé au maximum. Ils n'ont été testé que sensiblement rapidement et donc, pourraient contenir encore quelques erreurs.

Listing 1.0 DYNAMICCONTAINER
1. // HTML Component (DYNAMICCONTAINER)
2. 
3. <public:component tagName=dynamiccontainer lightweight>
4.   <public:attach event=ondocumentready onevent=dynamicContainer_DocumentReady() />
5.   <public:method name="deplacer" />
6.   <public:method name="etat" />
7.   <public:property name="left" value="0"/>
8.   <public:property name="top" value="0"/>
9.   <public:property name="name" value="none"/>
10. </public:component>
11. 
12. <script language="JScript">
13. 
14. var objElement = null;
15. 
16. 
17. function dynamicContainer_Ready()
18. {
19.   window.event.srcElement.cancelBubble = true;
20.  
21.   if (element.name != 'none')
22.   {
23.    var intCpt = 0;
24.    for(var x=0;x<element.children.length;x++)
25.    {
26.     var strChampHidden = "";
27.     if (element.children[x].tagName == 'dynamicbox')
28.     {
29.      strChampHidden += '<input type="hidden" id="id' + element.children[x].getAttribute("id") + '" value="' + intCpt + '">';
30.      intCpt ++;
31.      element.children[x].innerHTML += strChampHidden;
32.     }
33.    }
34.   }
35.   with(element.style)
36.   {
37.    position = 'absolute';
38.    top = element.top;
39.    left = element.left;
40.    border = '0px solid #ffffff';
41.    margin = '0px';
42.    padding = '0px';
43.   }
44. }
45. 
46. function deplacer(strId, strDirection)
47. {
48.   if (strDirection == 'h')
49.   {
50.    strTemp = new String('id' + strId);
51.   
52.    if (eval(window.document.all[strTemp].value) > 0)
53.    {
54.     strTemp2 = new String();
55.     strId2 = new String();
56.     var intY;
57.     for(var y=0;y<element.children.length;y++)
58.     {
59.      if (element.children[y].tagName == 'dynamicbox')
60.      {
61.       strTemp2 = "id" + element.children[y].getAttribute("id");
62.       if (eval(window.document.all[strTemp2].value) == eval(window.document.all[strTemp].value) - 1)
63.       {
64.        strId2 = element.children[y].getAttribute("id");
65.        intY = y;
66.       }
67.      }
68.     }
69.    
70.     strTemp2 = "id" + element.children[intY].getAttribute("id");
71.    
72.     // Déplacer les éléments à l'écran.
73.     strTop = new String(window.document.all[strId2].style.top);
74.     strHeight = new String(window.document.all[strId].style.height);
75.    
76.     strTop = strTop.substring(0,strTop.length - 2);
77.     strHeight = strHeight.substring(0,strHeight.length - 2);
78.    
79.     window.document.all[strId].style.top = strTop;
80.     window.document.all[strId2].style.top = eval(strTop) + eval(strHeight);
81.    
82.     // Changer l'indicateur d'ordre des éléments
83.     window.document.all[strTemp2].value = window.document.all[strTemp].value;
84.     window.document.all[strTemp].value = eval(window.document.all[strTemp].value)-1;
85.    }
86.   }
87.   else
88.   {
89.    strTemp = new String('id' + strId);
90.   
91.    if (eval(window.document.all[strTemp].value) < element.children.length - 1)
92.    {
93.     strTemp2 = new String();
94.     strId2 = new String();
95.     var intY;
96.     for(var y=0;y<element.children.length;y++)
97.     {
98.      if (element.children[y].tagName == 'dynamicbox')
99.      {
100.       strTemp2 = "id" + element.children[y].getAttribute("id");
101.       if (eval(window.document.all[strTemp2].value) == eval(window.document.all[strTemp].value) + 1)
102.       {
103.        strId2 = element.children[y].getAttribute("id");
104.        intY = y;
105.       }
106.      }
107.     }
108.    
109.     strTemp2 = "id" + element.children[intY].getAttribute("id");
110.    
111.     // Déplacer les éléments à l'écran.
112.     strTop = new String(window.document.all[strId].style.top);
113.     strHeight = new String(window.document.all[strId2].style.height);
114.    
115.     strTop = strTop.substring(0,strTop.length - 2);
116.     strHeight = strHeight.substring(0,strHeight.length - 2);
117.    
118.     window.document.all[strId2].style.top = strTop;
119.     window.document.all[strId].style.top = eval(strTop) + eval(strHeight);
120.    
121.     // Changer l'indicateur d'ordre des éléments
122.     window.document.all[strTemp2].value = window.document.all[strTemp].value;
123.     window.document.all[strTemp].value = eval(window.document.all[strTemp].value) + 1;
124.    }
125.   }
126. }
127. function etat(strId,strEtat)
128. {
129.   var intCpt = 0;
130.   for(var x=1;x<element.children.length;x++)
131.   {
132.    if (element.children[x].tagName == 'dynamicbox')
133.     intCpt ++;
134.   }
135.   if (strEtat == 'r')
136.   {
137.    window.document.all['txtHeight' + strId].value = window.document.all[strId].style.height;
138.    window.document.all['txtContenu' + strId].value = window.document.all['idContenu' + strId].innerHTML;
139.    window.document.all['idContenu' + strId].innerHTML = "";
140.    strIdH = new String(window.document.all[strId].style.height);
141.    var intIdH = eval(strIdH.substring(0, strIdH.length - 2));
142.    window.document.all[strId].style.height = '70px';
143.    if (window.document.all['id' + strId].value < intCpt)
144.    {
145.     for(var y=0;y<element.children.length;y++)
146.     {
147.      if (element.children[y].tagName == 'dynamicbox')
148.      {
149.       if (eval(window.document.all['id' + element.children[y].getAttribute("id")].value) > eval(window.document.all['id' + strId].value))
150.       {
151.        strHTmp = new String(element.children[y].style.top);
152.        var intHTmp = eval(strHTmp.substring(0, strHTmp.length - 2));
153.        element.children[y].style.top = intHTmp - (intIdH - 70);
154.       }
155.      }
156.     }
157.    }
158.   }
159.   else
160.   {
161.    window.document.all[strId].style.height = window.document.all['txtHeight' + strId].value;
162.    window.document.all['idContenu' + strId].innerHTML = window.document.all['txtContenu' + strId].value;
163.    strIdH = new String(window.document.all[strId].style.height);
164.    var intIdH = eval(strIdH.substring(0, strIdH.length - 2));
165.    if (window.document.all['id' + strId].value < intCpt)
166.    {
167.     for(var y=0;y<element.children.length;y++)
168.     {
169.      if (element.children[y].tagName == 'dynamicbox')
170.      {
171.       if (eval(window.document.all['id' + element.children[y].getAttribute("id")].value) > eval(window.document.all['id' + strId].value))
172.       {
173.        strHTmp = new String(element.children[y].style.top);
174.        var intHTmp = eval(strHTmp.substring(0, strHTmp.length - 2));
175.        element.children[y].style.top = intHTmp + (intIdH - 70);
176.       }
177.      }
178.     }
179.    }
180.   }
181. }
182. </script>

Voici maintenant le listing du composant « dynamicbox »

Listing 2.0 DYNAMICBOX
1. // HTML Component (DYNAMICBOX)
2. 
3. <public:component tagName=dynamicbox lightweight>
4.   <public:attach event=oncontentready onevent=dynamicBox_Ready() />
5.   <public:property name="left" value="0"/>
6.   <public:property name="top" value="0"/>
7.   <public:property name="width" value="200"/>
8.   <public:property name="height" value="200"/>
9.   <public:property name="titre" value="dynamic box"/>
10.   <public:property name="vbarcolor" value="red"/>
11.   <public:property name="hbarcolor" value="lightgrey"/>
12.   <public:property name="bgcolor" value="white"/>
13. </public:component>
14. 
15. <script language="JScript">
16. 
17. var objElement = null;
18. 
19. function dynamicBox_Ready()
20. {
21.   window.event.srcElement.cancelBubble = true;
22.   strId = new String(Math.random());
23.   strId = strId.substring(2,strId.length);
24. 
25.   with(element.style)
26.   {
27.    position = 'absolute';
28.    top = element.top;
29.    left = element.left;
30.    width = element.width;
31.    height = element.height;
32.    backgroundColor = '#ffffff';
33.    borderLeft = '1px solid #000000';
34.    borderTop = '1px solid #000000';
35.    borderRight = '1px solid #000000';
36.    borderBottom = '1px solid #000000';
37.    margin = '0px';
38.    padding = '0px';
39.   }
40.   element.id = "id" + strId;
41.   strtitre = new String(element.titre);
42.   strtitre = (strtitre.length > (Math.round(eval(element.width)/7) - 3))?strtitre.substring(0,(Math.round(eval(element.width)/7) - 3)):strtitre;
43.   var strWidth = new String(element.style.width);
44.   var strContenu = '<input type="hidden" id="txtContenu' + element.id + '"><table width="100%" height="100%" cellpadding="0" cellspacing="0">';
45.   strContenu += '<tr><td bgcolor="' + element.bgcolor + '" valign="top" width="' + (eval(strWidth.substring(0,strWidth.length - 2)) - 18) + '">';
46.   strContenu += '<table width="100%" height="20" bgcolor="' + element.hbarcolor + '" style="border-bottom:\'1px solid #000000\';font-family:\'verdana\';font-size:10px;">';
47.   strContenu += '<tr><td ID="idDynamicBox' + strId + '">' + strtitre + '</td></tr>';
48.   strContenu += '</table>';
49.   strContenu += '<table><tr><td id="idContenu' + element.id + '">' + element.innerHTML + '</td></tr></table>';
50.   strContenu += '</td><td width="18" bgcolor="' + element.vbarcolor + '" style="border-left:1px solid #000000;" align="center" valign="bottom">';
51.   strContenu += '<table>';
52.   if (element.parentElement.tagName == 'dynamiccontainer')
53.   {
54.    strContenu += '<tr><td><img src="haut.jpg" id="idHaut' + element.id + '" onclick="' + element.id + '.parentElement.deplacer(\'' + element.id + '\', \'h\');"></td></tr>';
55.    strContenu += '<tr><td><img src="bas.jpg" id="idBas' + element.id + '" onclick="' + element.id + '.parentElement.deplacer(\'' + element.id + '\', \'b\');"></td></tr>';
56.   }
57.   strContenu += '<tr><td><img src="reduire.jpg" onclick="' + element.id + '.parentElement.etat(\'' + element.id + '\', \'r\');"></td></tr>';
58.   strContenu += '<tr><td><img src="agrandir.jpg" onclick="' + element.id + '.parentElement.etat(\'' + element.id + '\', \'a\');"></td></tr>';
59.   strContenu += '</table>';
60.   strContenu += '</td></tr></table><input type="hidden" id="txtHeight' + element.id + '" value="' + element.style.height + '">';
61.   element.innerHTML = strContenu;
62. }
63. 
64. </script>

Finalement, voici le listing d'une page html qui utilise les composants. Remarquez aux lignes 21, 22, 25, 26 et autres que les composants sont traitées comme des balises HTML normal avec un préfixe espace nominal définit sur les lignes 1,2,3.

Listing 3.0 Page html
1. <HTML xmlns:ns>
2. <?import namespace=ns implementation=_htc/composant-boite-dynamique.htc />
3. <?import namespace=ns implementation=_htc/composant-contenant-dynamique.htc />
4. <head>
5. <title>HTC - A525G</title>
6. <style type="text/css">
7. texte{
8. font-family:arial;
9. font-size:8pt;
10. color:#777777;
11. }
12. titre{
13. font-family:arial;
14. font-size:10pt;
15. color:midnightblue;
16. text-align:center;
17. }
18. </style>
19. </head>
20. <body>
21. <ns:dynamiccontainer top="10" left="10" name="dc1">
22.   <ns:dynamicbox width="200" height="120" titre="Boite 1 contenant 1" left="0" top="0">
23.    <p class="titre">A525G</p>
24.    <p class="texte">A525G est un site d'information général sur divers sujets.</p>
25.   </ns:dynamicbox>
26.   <ns:dynamicbox width="200" height="130" titre="Boite 2 contenant 1" left="0" top="120">
27.    <p class="titre">A525G</p>
28.    <p class="texte">Catégories d'article :</p>
29.    <p class="texte">
30.     <select size="1">
31.      <option>Bande dessinée</option>
32.      <option>Intelligence artificielle</option>
33.      <option>progrmmation</option>
34.      <option>etc...</option>
35.     </select>
36.    </p>
37.   </ns:dynamicbox>
38.   <ns:dynamicbox width="250" height="100" titre="Boite 3 contenant 1" left="0" top="250">
39.    <p class="titre">A525G</p>
40.    <p class="texte">Les article publier son au nombre de 37 au moment ou j'écris se 38ieme article.</p>
41.   </ns:dynamicbox>
42. </ns:dynamiccontainer>
43. 
44. <ns:dynamiccontainer top="10" left="270" name="dc2">
45.   <ns:dynamicbox width="350" height="100" titre="Boite 1 contenant 2" left="0" top="0" hbarcolor="cornflowerblue" vbarcolor="goldenrod">
46.    <p class="titre">A525G</p>
47.    <p class="texte">Atelier sur les composants HTML</p>
48.   </ns:dynamicbox>
49.   <ns:dynamicbox width="350" height="100" titre="Boite 2 contenant 2" left="0" top="100" hbarcolor="cornflowerblue" vbarcolor="goldenrod">
50.    <p class="titre">A525G</p>
51.    <p class="texte">Un composant HTMl est un fichier avec l'extenssion .htc.</p>
52.   </ns:dynamicbox>
53. </ns:dynamiccontainer>
54. </body>
55. </html>

J'ai choisit de ne pas décrire les listings dans cet article, mis à part décrire la structure que peut avoir un composant. Le but de l'article n'est pas de donner un cours sur le JScript. Pour en savoir plus sur ce langage de script, visitez les autres pages du site A525G. Celui-ci renferme plusieurs autres articles se rapportant au JavaScript.

En terminant, pour voir un exemple du résultat des listings ci-dessus, cliquez ici.


| A525G | Catégorie - Programmation | Commentaire |
Par : Sylvain B.
Date de mise en ligne : 30 mai 2002