__    __    ________    __    __    __
           |  |  |  |  |        |  |  \  /  |  |  |
           |  |__|  |  |__    __|  |   \/   |  |  |
           |        |     |  |     |        |  |  |
           |   __   |     |  |     |  |\/|  |  |  |_____
           |  |     |     |  |     |  |  |  |  |        |
           |__|  |__|     |__|     |__|  |__|  |________|
                Cours sur le html, langage Internet



                         html.txt  25/08/2023
                            ultimecool

Sommaire


  CHAPITRE 1 - HTML
     1.1. Creation d'un document et syntaxe
     1.2. Balises d'en tete et corp de page
     1.3. mise en forme du texte
     1.4. Puces
     1.5. Images
     1.6. Liens
     1.7. Tableaux
     1.8. Multi fenetrage
     1.9. Formulaires
  CHAPITRE 2 - Feuille de styles CSS (Cascaded Style Sheet) 
     2.1. Syntaxe
     2.2. Definition du style
     2.3. Polices de style
     2.4. Mise en page
     2.5. Exemples de calques
     2.6. menus CSS
     2.7. Les sprites CSS
     2.8. Bootstrap
  CHAPITRE 3 - Référencement
     3.1. Les zones chaudes
     3.2. Les freins au référencement
  CHAPITRE 4 - Javascript
     4.1. Syntaxe
     4.2. Evenements
     4.3. Programmation objet
     4.4. Interactions
     4.5. Actions programmees
     4.6. Prototypes et héritage: les classes en Javascript
     4.7. Ajax avec XMLHTTPRequest
  CHAPITRE 5 - jQuery
     5.1. Fonctionnement
     5.2. Ajax et Formulaires
     5.3. DataTable
     5.4. DataTable : Chargement avec un Appel Ajax
     5.5. DataTable : Edition
     5.6. DataTable : Filtrage et total de colonne
  CHAPITRE 6 - Les pluggins

Introduction

html: Langage de mise en forme des donnees (1991, norme w3c). css: Feuille de script de mise en forme de pages. Java script: Dynamisme des pages cote client. asp,jsp,php: Creation des pages dynamiquement par le serveur (IIS,PWS,Apache).

L' html se constitut de balises contenant des attributs. C' est un langage multi - platformes qui necessite un navigateur internet (Mozzila, ie, netscape, opera). La creation d'une page ".html" peut se faire avec un simple editeur de texte tel que notpad, vi, ultraedit, homesite, visual interdev (asp). Il existe aussi des logiciels evoluees de generation automatique de pages tel que : - Front-Page generation de code ie uniquement - Dreamweaver generation abondante de code, valable sur tout navigateurs - GoLive generation propre de code mais validite non garanti - Netscape Composer generation de code Netscape uniquement

Le navigateur affiche la page apres l'avoir compile. Le XML permet de creer son prope langage de balisage basee sur la norme SGML qui englobe l'HTML.

Internet explorer et Netscape se livrent une lutte acharnee. - IE possede plus d'attributs que la norme w3c html4 - Nescape possede plus de balises que la norme w3c html4

CHAPITRE 1 - HTML

1.1. Creation d'un document et syntaxe

Un document html se compose d'un bloc html, d' un bloc d'en tete, et d'un bloc de corp. Chaque bloc est definit par des balises, qui ne tiennent pas compte de la case (maj/min). Le document html se sauvegarde sous un fichier .htm ou .html La page par defaut d'un site internet est default.html ou index.html

bloc commentaires: ex: bloc html: bloc d'en tete: bloc de corp:

Les navigateurs ignorent les espaces multiples, et les retours a la lignes du code html. Une balise erronee est ignorer par le navigateur. Les entitees sont des element speciaux. '&' entité ';' &nbsp; (espace supplementaire) &lt; (inferieur <) &gt; (superieur >) &#38; (caractere ascii en decimal &)

Syntaxe des attributs de balises: ... Il ne doit pas y avoir d'espaces entre attr1, le '=' et le '"'. Meme si la case est ignoree pour les balises, il faut la respecter pour les nom de fichiers, et pour les liens, car certains OS en tiennent compte. Les balises peuvent etre imbriquees les unes dans les autres.

Il existe des balises pour indiquer un titre (h1, h2…); des balises pour indiquer des listes (ul, ol,…); des balises pour indiquer un paragraphe (p), une citation (blockquote), un tableau de données (table), un bloc regroupant plusieurs contenus (div), etc. Respecter la sémantique des balises, donc encadrer un contenu avec la balise adéquate, permet tout d'abord de structurer le document correctement, indépendamment de la forme qu'il va prendre. Ceci permet aux programmes qui traiteront l'information contenue dans la page, de l'interpréter correctement, et donc de l'utiliser comme il se doit.

1.2. Balises d'en tete et corp de page


  <head>
    <title> Le titre </titre> <!-- apparait dans la bare de titre (3-5mots) -->
    <meta name="..........." content="...">
    <meta name="description" content="description de la page (max: 200 chr)">
    <meta name="keywords"    content="mots clef des moteurs de recherche(1000)">
    <meta name="author"      content="auteur de la page">
    <meta name="generator"   content="programme de creation de la page">
    <meta name="copyright"   content="&copy; annee detenteur">
                  >
    <meta http-equiv="expires" content="0"> temps avant rechargement
  </head>

  ex:  <head>
         <title>Entreprise - Test du titre </title>
         <meta name="author" content="nom_auteur">
         <meta name="keywords" content="html,htm,javascript">
         <meta name="description" content="premier" lang="FR">
         <meta name="copyright" content="&copy; 2003 auteur">
       </head>
 

Une page html contient obligatoirement un corp de page contenu entre les balises ouvrante et fermante "body"


  <body bgcolor="#rgb"
        background=""
        text="#rgb"
        link="#rgb"
        vlink="#rgb"
        bgproperties="fixed"
        leftmargin=x
        topmargin=y
        rightmargin
        marginwidth
 

Couleur de fond.                
Image de fond en mozaic.        
Couleur du texte.               
Couleur des liens.              
Couleur des liens visites.      
Fond d'ecran fixe ie uniquement.
Bordure de gauche ie uniquement.
Bordure du haut ie uniquement.  
 
 

1.3. mise en forme du texte


<br>
<nobr><wbr></nobr>
<code></code>
<kbd></kbd>
<samp></samp>
<tt></tt>
<p></p>
<h1></h1>
<pre></pre>
<div></div>
<hr>
 

saut de ligne
block sans saut de lignes
mot en chasse fixe (code informatique)
mot en chasse fixe (saisie au clavier)
mot en chasse fixe (exemple  de texte)
mot en chasse fixe (texte en teletype)
paragraphe sans mise en forme
titre de h1 a h6  ex:  <h1 align=...>titre</h1>
texte en chasse fixe
calques
ligne horizontale

Les 5 derniers elements possedent l'attribut align="left|right|center|justify"


<hr width="px|%"      px: en pixels     ex:  "100" ou "100px"
    size="px"         %:  en pour cents ex:  "10%"
    color="#rgb"      code rgb:   red   green blue   "#FFFFFF"="white"
    align=...         ~~~~~~~~  #  FF    FF    FF    "#000000"="black"
    noshade>          Utilisez plutot des feuilles de style hr.

<b>texte</b> texte en gras           <small>texte</small>   texte en petit
<i>texte</i> texte en italique       <big>texte</big>       texte en gros
<u>texte</u> texte souligne          <sup>texte</sup>       texte en exposant
<strike>texte</strike> texte barre   <sub>texte</sub>       texte en indice

<font face="nom de la police"  ex: "Arial Black", "Garamond Bold"
      size="1...6"   3=T; 4=T+2; 2=T-2; T: Taille utilisateur
      color="#rgb"> ... </font>

1.4. Puces

Puces nom numerote:


<ul type="disc|circle|square" scr="souce de l'image png, jpg jpeg, gif">
  <li> puce 2 </li>
  <li> puce 2 </li>
</ul>
 

Puces numerote:


<ol type="1|a|A|i|J" start="3">  <!-- le start tjs numerique -->
  <li> ... </li>
</ol>
 

Listes de definition


<dl>
  <dt>Nom1<dd>Def1</dt>
  <dt>Nom2<dd>Def2</dt>
</dl>
 

1.5. Images

Les images transparentes permettent une mise en page complexe, car ces images ne sont pas forcement rectangulaires. Une image transparente peut s'obtenir dans le format gif ou png . Utiliser Photoshop ou Paint Shop Pro pour creer vos images. Pour les grandes images utilisez plutot le jpg, et le gif pour les petites. Pour creer des images animees utilisez GIFBuilder ou PaintShopPro. Les banieres sont des gif animees de 450px par 100px de moins de 72 ppp. Palette elementaire de 216 couleurs pour moniteurs 8 bits. Une attenuation d'un jpg permet d'ameliorer la compression.


<img src="source"
     height="px"
     width="px"
     border="1"
     alt="info"
     align="..."

     hspace="px"
     vspace="px"
     lowsrc="">
 

Source de l'image png, jpg jpeg, gif.
Hauteur obligatoire.
Largeur obligatoire.
Bordure de l'image obligatoire.
Info bulle obligatoire.
Alignement par rapport au texte "left|right|center|top|middle
|bottom|texttop|Absmiddle|Absbottom"
Marge horizontale entre l'image et le texte.
Marge verticale entre l'image et le texte.
Source basse resolution. A eviter.

Utilisez des feuilles de style, ou des tableau, pour la mise en page des images. Sinon utiliser align et

1.6. Liens

Lien normal


<a href="..."        Reference: url, java script, ancre, ...
   target="_blank">  Cible du lien. Dans une nouvelle fenetre avec _blank
texte du lien </a>   Ca peut aussi etre une image.

Ancre


<a name="nom"        Nom de l'ancre.
   tabindex=n        Index de tabulation.
   accesskey=x       Alt-x

       <a href="../index.html">home</a>
       <a href="mailto:toto@isp.com?cc=...&cci=...&subject=...&body=...">...</a>
       <a href="javascript:alert('coucou');"> coucou </a>
       <a name="intro">  Definit une encre.
       <a href="file:///c|/chemin/"> ... </a> lance c:\chemin\default.html
       <a href="page.htm#intro"> ... </a>
       <a href="#">  Recharge la page.
       <a href="#debut|#haut"> ... </a>
 

1.7. Tableaux


<table> <!-- Cadre exterieur -->
  <tr>  <!-- table raw: ligne -->               _________________________
    <td> cellule1 </td>  <!-- cellule -->      |            |            |
    <td> cellule2 </td>                        |  cellule1  |  cellule2  |
  </tr>                                        |            |            |
  <tr>                                         |____________|____________|
    <td> --- </td>                             |            |            |
    <td> +++ </td>                             |    ---     |    +++     |
  </tr>                                        |            |            |
</table>                                       |____________|____________|

<table height="px|%"
       width="px|%"
       align="..."
       border="1px"
       bordercolor="#rgb"
       bgcolor="#rgb"
       cellspacing="1px"
       cellpadding="2px">

<tr    align="..."
       valign="...">

<td    height="px|%"
       align="..."
       bordercolor="#rgb"
       bgcolor="#rgb"
       rowspan="1"
       colspan="1"
       nowrap>
 

Hauteur du tableau.
Largeur du tableau (obligatoire)
Alignement "left","right","center"
Epaisseur de la bordure.
Couleur de la bordure.
Couleur de fond (ie: tout le tableau et les cellules)
Espacement des cellules (obligatoire).
Marge entre le bord et le contenu (obligatoire).
 
Alignement horizontal "left","right","center".
Alignement vertical "top|middle|bottom".
 
Hauteur de la cellule.
Alignement "left","right","center"
Couleur de la bordure (sur certain navigateurs).
Couleur de fond (ie: tout le tableau et les cellules)
Nombre de lignes de la cellule.
Nombre de colones de la cellule.
Sur une ligne (ou &nbsp).

1.8. Multi fenetrage

Il existe deux methodes pour faire du multifenetrage: - faire un tableau, ou des calques ce qui implique des frames (fenetres) dynamiques: bonne méthode (voir le chapitre CSS). - partager l'ecran du navigateur entre plusieurs pages html, ce qui implique des frames statique pour le menu et le titre; mauvaise méthode.

Pour partager l'ecran il faut definir des zones pour les frames avec 'frameset'. Il est possible de combiner le frameset horizontal et le frameset vertical en imbriquant ces deux frameset. Apres avoir remplit les zones, on attribut a chaque zone une page html avec des balises 'frame'. Il faut une balise pour une zone.


<frameset
       rows="..."
       cols="..."
       border="0"
       bordercolor="#rgb"
       framespacing="px">

<frame name="..."
       src="..."
       scrolling=".."
       noresize
       marginheight=""
       marginwidth=""
 

 
"80,*" pour 80px, puis le reste de la page.
"80,*,5%" pour 80px a gauche, 5% a droite.
Taille de la bordure entre frames.
Couleur de la bordure (suivant navigateur).
Espacement entre frames (suivant navigateur).
 
Nom de la frame.
Source de la frame (page html).
Ascensseurs: "yes","no","auto".
Pour ne pas redimentionner.
Marge (obligatoire)
Marge

ex:


<html>
<head><title> index.html </title></head>
<frameset rows="150,*" border="2" framespacing="2" bordercolor="black">
  <frame name="titre" src="titre.htm" scrolling="no" noresize >
  <frameset cols="200,*" border="2" framespacing="2" bordercolor="black">
    <frame name="menu" src="menu.htm" scrolling="auto" >
    <frame name="home" src="home.htm" scrolling="auto" >
  </frameset>
</frameset>
</html>

<html>
<head><title> menu.html </title></head>
<body>
  <a href="page1.html" target="home"> page 1 </a>
</body>
</html>
 

1.9. Formulaires

Les formulaires sont des espaces de saisie utilisateur.


<form action=""       par defaut sur la page elle meme. Sinon page asp.ou php
      method="">      par defaut get "get","post"
  ... elements du ...
  ... formulaire ...
</form>

Elements du formulaire:


  Element texte:
  ~~~~~~~~~~~~~
    <input type="..."         "text|password|hidden"
           name=""            Nom de l'element.
           size=""            Taille de la case.
           maxlength=""       Longeur maximum de la chaine.
           value=""           Valeur du champ.
           disabled           Verouiller.
           readonly>          Lecture seule.

  Zone de texte:
  ~~~~~~~~~~~~~
    <textarea name=""         Nom de l'element.
              rows=""         Nombre de lignes de la zone.
              cols=""         Nombre de colones de la zone.
              disabled        Verouiller.
              readonly>       Lecture seule.
      ... contenu ...
    </textarea>

  Case a cocher:
  ~~~~~~~~~~~~~
    <input type="..."         "radio|checkbox"
           name=""            Meme nom pour les radio du meme groupe.
           value=""           Valeur retourne si selectionne.
           disabled
           checked>

  Listes deroulantes:
  ~~~~~~~~~~~~~~~~~~
    <select name=""           Nom de la liste deroulante.
            size=""           Nombre de lignes affichees de la liste.
            disabled          Verouiller.
            multiple>         Multicritaire autorise.
      <option value=""            Valeur retourne (val1,val2,val3 en multi).
              selected>           Seleclionne par defaut.
        ... contenu ...
      </option>
      <option ...
    </select>

  Boutons:
  ~~~~~~~
    <input type=""            "button|submit|reset"
           name=""            Nom du bouton.
           value=""           Texte du bouton.
           disabled>          Verouiller.

Regroupement d'elements 

    <fieldset>                Regroupement en catégories logiques (thématiques),
    <legend>Titre</legend>
    elements...               Rend les contrôles  plus compréhensibles,  et plus
    </fieldset>               accessibles aux handicapées.

1.10. Mapage

Le map correspond a une zone cliquable d'une image.


<map name="nommap">
  <area shape="rect|circle|poly"
        coords="x1,y1,x2,y2"         rect:   rectangle
               "x,y,r"               circle: cercle
               "x1,y1,...,xn,yn"     poly:   polygone
        href=""
        target=
        nohref
        accesskey=x>
  <area ...
</map>
<img src="..." usemap="#nommap"
 

CHAPITRE 2 - Feuille de styles CSS (Cascaded Style Sheet)

Les styles offrent plus de controles que les balises HTML, et sur tout type de navigateur. Ils permettent de predefinir des attributs sur une balise, et de les appliquer a une section de page ou a toutes les pages d'un site. La liste des definitions de style est trop consequente, pour les enumerer. Pour les obtenir, le mieu est d'utiliser l'utilitaire TopStyle. A terme, les balises de formatage du texte devraient laisser la place aux style.

2.1. Syntaxe


<Balise id=id class=class>             <P>                     <P id=intro>

Balise[#id|.class]  {           ex:    P  {                    P#intro  {
  definition1 : valeur1  ;               text-align:justify;     color:black;
  definition2 : valeur2  ;               text-indent:8pt;        font-size:10;
  definitionN : valeurN (;)              color:red             }
}                                      }

Il est possible de definir plusieurs balises en meme temps: P, H1 { ... }. Les unites sont exprimees en px (pixels), pt (points), % (pourcentages). D'autres nouvelles unités rendent possible le fait de spécifier des tailles relatives à la fenêtre du lecteur, ce sont les unités vw and vh. Le vw équivaut à 1/100e de la largeur de la fenêtre et le vh équivaut à 1/100e de sa hauteur. Il y a également vmin, qui sélectionne la plus petite valeur entre vw et vh. Et vmax.

2.2. Definition du style

Localement, le style définit s' applique seulement à la balise. Le nom de la balise doit être enlevé.


    texte normal
    <p style="font-size:12pt;color:red">
    texte de fonte 12, en rouge.
    </p> texte normal
 

Les styles qui s'appliquent à la page entière, à une classe d'éléments (class), ou à un élément (id) se placent dans l'en tête. Pour faciliter la lecture du code donnez un id à votre body (ancre), à votre bloc en-tete, bord gauche ... L'id permet d'appeler les objets et calques avec getElementById (javascript), ce qui facilite la compatibilité entre tous les navigateurs.


  CLASS                      ID                         SPAN

  <head><style>              <head><style>              <head><style>
  P { }                      BODY#top { }                SPAN.maj {  }
  P.intro { }                </style></head>            </style></head>
  </style></head>            <body id="top">            <body>
  <body>                     ...                        <span class=maj>
  <p class=intro>txt</p>     <a href="#top"></a>        </span>
  </body>                    </body>                    </body>

Les styles qui s'appliquent a plusieurs pages peuvent etres mis dans un fichier externe, avec l'extension .css ( ex: style.css ). Elle se charge par un lien. Attention le style sera chargé après la page.


    <head><link rel="stylesheet" type="text/css" href="style.css"></head>
 

2.3. Polices de style

Le choix d'une police se fait avec la definition "font-family"


    font-family: fonte desiree, fonte de rechange1, ...
    font-family: "News Gothic MT", "Lithos Regular"
    H2 {font: small-caps bold 16pt times; color: #0000FF}
    Body {background: black url(text.jpg) repeat-x scroll center top}

petite liste de fontes: Times, Arial nom generiques: serif, sans-serif, cursive, fantasy, monospace

Inclusion d'une police au format eot dans une feuille css:


    <style>
    @font-face { font-family: "NewsGoth";
                 src: url (NewsGoth.eot)  }
    </style>
 

Modification du style des liens:


    A:link , A:visited, A:active, A:hover { }

2.4. Mise en page

Il est possible de placer un calque n'importe ou dans la page, example:


<div id="Layer1" style="position : absolute;
                        width : 469px;
                        height : 324px;
                        z-index : 1;
                        left : 267px;
                        top: 271px"
>contenu</div>
 

Le style définit l'emplacement du calque sur la page. Le calque se compose ensuite comme une page normale (les

remplacent les ).


position:relative|absolute;
top:pt; right:pt; bottom:pt; left:pt; width:px|%; height:px%;
clip:rect(h d b g); capture un rectangle sur l'element.
                    hdbg haut, droite, bas, gauche du rectangle
z-index:-1; niveau dans la pile d'objets
display:none|block|inline|list-item(comme li)

border, border-top, border-bottom, border-left, border-right, border-color,
border-left-width, ...
border:thin|medium|thick|4px
border:none|dotted|thick|solid|double|groove|ridge|inset|outset

padding, padding-top, padding-bottom, padding-left, padding-right
padding: hdbg (haut et droite et bas et gauche) en pt ou %
padding: h d b g (haut, droite, bas, gauche)
padding: hb dg (haut et bas, droite et gauche)
padding: h dg b (haut, droite et gauche, bas)

margin, margin-top, margin-bottom, margin-left, margin-right
margin: hdbg (haut et droite et bas et gauche) en pt ou %
margin: h d b g (haut, droite, bas, gauche)
margin: hb dg (haut et bas, droite et gauche)
margin: h dg b (haut, droite et gauche, bas)

vertical-align:
    baseline|    aligne le centre sur la ligne de base
    middle|      aligne le centre sur le milieu
    sub|         en indice
    super|       en exposant
    text-top|    aligne le haut sur le haut du texte de la ligne
    text-bottom| aligne le bas sur le bas du texte de la ligne
    top|         aligne le haut sur le plus haut de la ligne
    bottom       aligne le bas sur le plus bas de la ligne

float:left|right equivaut a align=left et align=right en html
clear:left|right|both|none equivaut a la balise clear

color:#rgb ou color:rgb(r, g, b) ou color:rgb(r%, g%, b%)
background:transparent|#rgb|red
background url()|repeat|repeat-x|repeat-y|noreapeat|fixed|scroll|x y
x peut etre: top, center, bottom
y peut etre: left, center, right
overflow:visible|hidden|scroll

list-style:disc|circle|square
list-style:decimal|lower-alpha|upper-alpha|lower-roman|upper-roman|url()
list-style:outside|inside
page-break-after:always|auto
page-break-before:always|auto

2.5. Exemples de calques

Il existe de multiples balises pour faire des calques :


<div>, <p>, <ul>, <li>, <h1>...<h6>, <blockquote>...

Deux blocs l'un en-dessous de l'autre avec un espace de séparation :

Partie HTML :


<div class="bloc1">bla bla bla</div>
<div class="bloc2">bli bli bli</div>
 

Et la CSS correspondante :


.bloc1 { height: 50px; background-color: blue; }
.bloc2 { height: 50px; background-color: green; margin-top: 20px; }
 

Trois blocs côte-à-côte :

Partie HTML :


<div class="bloc1">bla bla bla</div>
<div class="bloc2">bli bli bli</div>
<div class="bloc3">blu blu blu</div>
 

Et la CSS correspondante :


.bloc1 { height: 50px; width: 100px; float: left; background-color: blue; }
.bloc2 { height: 50px; width: 100px; float: left; background-color: green; }
.bloc3 { height: 50px; width: 100px; float: left; background-color: red; }
 

Un bloc contenu dans un autre :

Partie HTML :


<div class="conteneur">
  <div class="bloc">bli bli bli</div>
</div>
 

Et la CSS correspondante :


.conteneur { background-color: blue; height: 100px; width: 100px; }
.bloc { background-color: yellow; height: 50px; width: 50px;
        margin-left: 20px; margin-top: 40px; }
 

Une image alignée à droite d'un texte :

Partie HTML :


<div class="conteneur">
<img class="image" src="..." alt="" />
<p>bla bla bla bla bla bla bla bla bla bla ...</p>
</div>
 

Et la CSS correspondante :


.conteneur { width: 40%; background-color: yellow; }
.image { float: right; }
 

Une mise en page:


<html>
<head>
  <style>
.bloc0 { height: 0px; width: 0px; }
.bloc1,.bloc2,.bloc3,.bloc4,.bloc5 { float: left; }
.bloc1 { height: 50px;  width: 100px; background-color: blue;  }
.bloc2 { height: 50px;  width: 100px; background-color: green; }
.bloc3 { height: 50px;  width: 100px; background-color: red;   }
.bloc4 { height: 200px; width: 50px;  background-color: red;   }
.bloc5 { height: 200px; width: 250px; background-color: black; }
  </style>
</head>
<body marginwidth="0" marginheight="0" topmargin="0" leftmargin="0">
<div align="center">
<table width="305" border="0" cellpadding="0" cellspacing="0"><tr>
<td width="305">
  <div class="bloc1">logo</div>
  <div class="bloc2">titre</div>
  <div class="bloc3">pub</div>
  <div class="bloc0"></div>
  <div class="bloc4">menu</div>
  <div class="bloc5">bla bla bla
  </div>
  <div class="bloc0"></div>
</td></tr>
</table>
</div>
</body>
</html>
 

Une page html en fond d'ecran:


<div style="position:absolute;-moz-opacity:0.2;width:98%;margin-left:1%;">
 <h1>FOND ECRAN</h1>
 <img src="logo.png" style="width:100%;" />
      blablabla
</div>
<div style="position:absolute;width:98%;margin-left:1%;">
    <table width="100%" style="-moz-opacity:0.8;">
    </table>
</div>
 

2.6. menus CSS


<html>
<head>
  <style>
body {font: 14px Verdana, Arial, sans-serif;}

ul {
list-style-type: none; /* on supprime les puces, inutiles */
width: 100%; /* précision pour Opera */
}
li { float: left;} /* on aligne les listes sur la gauche */

.menu a {
     margin: 0 2px;
     width: 100px; /* on définit la taille du bouton de menu */
     height: 20px;
     float: left;
     display: block;
     text-align: center;
     border: 1px solid gray;
     text-decoration: none;
     color: #000;
     background: #fff;
     }
 
.menu a:hover {
     background: #ccc;
     border: 1px solid gray;
     }

.menu a:active {
     background: gray;
     border: 1px solid gray;
     color: #fff;
     }
  </style>
</head>
<body>
<ul class="menu">
<li><a href="...">Menu 1</a></li>
<li><a href="...">Menu 2</a></li>
<li><a href="...">Menu 3</a></li>
<li><a href="...">Menu 4</a></li>
</ul>
</body>
</html>
 

2.7. Les sprites CSS

Les sprites sont utilisées dans de nombreuses applications web où de multiples images sont utilisées. Au lieu d'avoir une image par fichier, on économise de la bande passante et de la mémoire en les envoyant toute dans le même fichier, ainsi, le nombre de requêtes HTTP diminue. On utilise alors background-position pour choisir l'image qu'on souhaite utiliser.


<style>
.toolbtn {
  background: url("myfile.png");
  display: inline-block;
  height: 20px;
  width: 20px;
}

#btn1 {
  background-position: 0px 0px;
}

#btn2 {
  background-position: -20px 0px;
}

#btn3 {
  background-position: -40px 0px;
}
</style>
 

2.8. Bootstrap

réf:
https://devstory.net/11975/bootstrap-modal
réf:
http://www.trucsweb.com/tutoriels/javascript/bootstrap4-modal_dynamique/

CHAPITRE 3 - Référencement

3.1. Les zones chaudes

Zone chaude n°1: Optimiser ses titres

En terme de référencement, le critère auquel les moteurs de recherche apportent le plus d'importance est le titre. Vous devez donc soigner au mieux le titre de chacune de vos pages. Chaque page doit comporter un titre différent au risque de se retrouver en "Duplicate content" soit du contenu dupliqué dans les résultats de recherche. En somme vos titres doivent suivre les règles suivantes:

  • Un bon titre doit comporter au maximum 10 mots (sauf le, la, des, ou,…) ou 100 caractères maximum
  • Il ne doit y avoir plus de deux mots clés similaires dans votre titre et doivent être séparé par 3 mots environ
  • Comporter des mots clés en rapport avec le sujet traité

Zone chaude n°2: Optimiser la zone de texte

Quand les moteurs de recherche indexent vos pages, ils vérifient et lisent la totalité du texte présent sur les pages. Pour être crédible, vous devez placer les mots clés les plus importants le plus près de la balise . Le moteurs de recherche privilégient les 3 premières lignes de texte visible plutôt que les dernières lignes les plus en bas pour leurs critères de référencement:

Vous devez également mettre en exergue vos mots clés importants.

Voici quelques conseils à savoir pour rendre vos mots clés réactifs:

  • Utilisez les balises h1 et h2, pour faire ressortir vos titres de paragraphe.
  • Mettre en valeur vos mots clés avec la balise strong, ce qui a pour effet de mettre en gras votre expression (+++).
  • Idem pour la balise b (+).
  • Les balises em permettent de passer votre texte en italique.

<h1>Vos mots  clés  ici</h1> ,  <h2>Vos mots clés ici</h2>
<strong> Vos mots clés ici !</strong>
<b>Vos mots clés ici!</b>
<em>Texte</em>
 

Préférer la balise "strong" à la balise "b". Pour éviter tous problèmes de "blacklistage", vous ne devez en aucun cas cacher du texte sur votre page (exemple: texte blanc ou jaune très clair sur fond blanc). Les moteurs ne pardonneront pas ce genre de technique et supprimeront sans préavis votre site de leur index.

Il existe également un critère que l'on appel IDM (Indice de mot clé). Cette IDM permet de calculer en pourcentage l'occurrence d'un mot présent dans la zone de texte. Voici un exemple:

3 mots clés / 100 mots dans la zone de texte = 3%

Certains référenceurs préconisent un IDM maxi de 5% par page, mais cette information est à prendre avec précaution. Beaucoup de sites utilisent des IDM atteignant 10 à 15% et sont très bien référencés.

Note très importante, il vaut mieux créer de petites pages décrivant bien le thème abordé plutôt que de grands documents parlant de plusieurs thèmes à la fois. Les moteurs sont très sensibles à ce sujet et feront donc la différence lors des résultats de recherche.

Zone chaude n°3: Optimiser les adresses URL des pages

Les liens internes ou externes sont des critères important pour les moteurs de recherche. En somme, les moteurs adorent les mots "cliquables", car vous pouvez insérer des mots clés à l' intérieur des ces mêmes liens. Pensez donc à bien soigner vos ancres pour un maximum de réactivité. Voici un très bon lien:


<a href="https://www.referencement-gratuit.com">referencement gratuit</a>
 

Dans cette exemple les mots "referencement gratuit" sont très réactifs pour une recherche sur les moteurs. A noter que le "-" (tiret) et "_"(l'underscore) dans les adresses sont considérés pour les moteurs comme un espace. N'hésitez donc pas à placer un maximum de mots clés entre ces balises.

Les liens dans une images

Vous pouvez insérer des liens internes ou externes dans une image, les liens seront très bien suivi par les moteurs. Voici un exemple:


<a href="http://www.referencement-gratuit.com"><img src="images.jpg"
alt="Référencement gratuit sur les annuaires">
 

l'attribut alt de la balise est pris en compte par Google.

Zone chaude n°4: Les backlinks

Comme vous avez pu le constater, les moteurs de recherches attachent une grande importance à la qualité des URL de lien. Cependant, il existe un autre critère de référencement qui est basé sur l'échange de liens. Plus vous effectuerez d'échange de liens avec d'autres sites internet, plus votre site aura tendance à monter dans les résultats de recherche.

Pour que les moteurs puissent apporter une importance sur vos échanges de liens, vous devez respecter les conditions suivantes:

  • Les liens doivent contenir les mots clés essentiel
  • Les sites doivent avoir un thème commun entre eux
  • Les pages sur lesquels se trouve le lien doivent être référencées sur les moteurs pour que le lien soit pris en compte
  • Les liens ne doivent pas être cachés

Evitez les pages qui comportent trop de liens (compter 10 liens externe maxi par page). Si vous souhaitez connaitre le nombre de backlinks pointant vers votre site, vous devez utiliser la commande suivante dans la zone de recherche des moteurs:

link:www.votre-site.com (sur Google et msn) linkdomain:www.google.fr (sur Yahoo)

Meme si Google n'affiche pas la totalité des liens pointant vers votre site, les autres liens sont bien pris en compte.

Zone chaude n°7: Les balises méta

Les balises sont de moins en moins utilisées de nos jours. Certains moteurs les utilisent encore mais la plupart des grands moteurs ne le font plus. Cependant, il ne faut pas non plus les ignorées pour autant. Nous allons les détaillés ici:


<meta http-equiv="Content-Type"  content="text/html; charset=windows-1252"  />
 

Cette balise permet de préciser le codage du texte. Elle est juste utilisé par les moteurs pour définir le type de codage. Cette balise doit être renseignée.


<title>Referencement-conseil.net - Les balises méta</title> : La balise </title>
 

est quand à elle vitale pour les moteurs. Sans elle, les pages de votre site porteraient toutes le même nom "untitle" (duplicate content). Elle ne doit pas dépasser environ 10 mots ou 100 caractères. Cette balise doit se trouver la plus haute possible dans votre code (au plus proche de la balise par exemple). Si ce n'est pas le cas, faites le!


<meta name="description" content="Referencement-conseil.net - Les balises méta">
 

Cette balise permet de résumer en quelques mots le contenu du site, si celui-ci ne comporte pas de zone de texte (site en Flash ou avec des frames par exemple). Nous vous conseillons de remplir cette balise. Elle ne doit pas dépasser environ 20 mots ou 200 caractères. Cette balise doit se trouver sous la balise "title".


<meta name="keywords" content="mot clé 1, mot clé 2, etc...">
 

Cette balise ne sert quasiment plus aux moteurs de recherche. Il est cependant conseillé de placer quelques mots clés séparés par une virgule. Placer également les formes singuliers/pluriels, miniscules/majuscules des occurences dans cette balise. Cette balise ne doit pas dépasser les 1000 caractères soit une centaine de mots clés.


<meta name="robots" content="index,follow">
 

Cette balise doit être renseigné. Elle spécifie si le moteur doit ou non indéxer la page et suivre les liens présent sur celle-ci: "index, follow" pour indexer et suivre les liens "noindex, nofollow" pour ne pas indéxer et suivre les liens de cette page. Si cette balise est absente, la page sera indéxé et les liens seront suivi par défaut.

Zone chaude n°8: Attributs alt et title

Beaucoup de webmaster inclus les balises alt et title pour l'affichage de texte alternatif en l'absence d'images et dans les liens textuels de leurs pages. Voici 2 exemples de code:


<img src="http://www.mon-site.com/images/logo.gif" alt="Mots clés ici"> image

<a href="http://www.mon-site.com" title="Mots clés ici"> pour un lien textuel
 

Les attributs alt et title sont pris en compte par Google

Les autres critères du référencement

Fréquence de mise à jour des pages: Plus les pages sont mises à jour, plus le site sera considéré comme réactif

Date de création du document: Plus un document est ancien dans l'index du moteur, plus son poids pourrait être considéré comme fort

Nombre de pages du site: Plus un site comportent de pages, plus sa notoriété sera considéré par le moteurs

Validité W3C: Un code HTML propre peut permettre aux spiders des moteurs de mieux comprendre votre code. Cette étape n'est pas obligatoire. Vous pouvez vérifier la validité de votre site en cliquant sur ce lien: Validateur W3C
http://validator.w3.org/

Notion de TrustRank: Algorithme permettant de repérer des tentatives de spam sur Google en analysant les liens du web tout en partant de pages de référence choisies par des humains. Très peu d'informations sont encore disponibles sur cette méthode.


http://www.referencement-conseil.net/referencement/optimisation/zone-de-texte.php

3.2. Les freins au référencement

Les sites en Flash

Les moteurs ne savent pas lire les textes inclus dans les animations Flash, par contre, il lisent les pages HTML qui lancent les animations. Il faut donc optimiser la page HTML en renseignant :

  • La balise "TITLE" : inclure des mots clés et un descriptif ;
  • La balise "META" : inclure des mots clés et un descriptif ;
  • La balise "NOEMBED" : c'est la balise d'insertion des animations Flash dans les pages HTML, il faut ajouter du texte descriptif sans abuser.

Il faut éviter les sites réalisés entièrement en Flash ou doubler ses pages Flash avec des pages HTML ou encore : présenter quelques pages optimisées pour être indexé par les moteurs.

Le langage Javascript

En arrivant sur l'index ou page d'accueil d'un site, le robot va tenter de suivre les liens présents sur cette page afin d'indexer toutes les pages.

Un lien en JavaScript pose problème si il est du type : lien

Les liens en JavaScript sont pris en compte par les robots, mais pour cela ils doivent être compatibles avec les robots ou spiders.

En intégrant l'URL de destination dans la zone "href", le robot va la reconnaître et la suivre pour indexer le document – cette URL est ensuite suivie du code propre à l'action proprement dite.

Un lien en JavaScript compatible est du type : lien

Attention! au placement JavaScript dans la partie des pages: les moteurs accordent plus de poids au texte situé en début de page ; il est essentiel de placer tout contenu optimisé le plus haut possible dans la page.

Les sites dynamiques et les URL sans contenu lexical

L'adresse URL générée lors de la création «dynamique» de pages présente les caractères bloquants ? et & . Les URL contenant jusqu'à 3 paramètres (2 &) ne posent pas de problème aux moteurs. Mais si les URL atteignent un nombre élevé de paramètres (plus de 4 paramètres, soit 3 &), elles constituent un frein.

Que faire ?

  • Optimiser les pages Web qui ne nécessitent pas de paramètres (page d'accueil, de présentation, le plan du site, présentation générale des produits, etc.) et les présenter avec des URL simples.
  • Passer par un référencement payant.
  • Pratiquer l'URL rewriting pour présenter des URL "propres" aux robots.

Les identifiants de session – Session ID (SID)

Les identifiants de session permettent de conserver des informations sur un internaute tout au long de sa visite sur un site. Ils permettent de connaître le parcours des internautes sur un site Web, de gérer un panier d'achats sur un site e-commerce, de rester identifié sur un forum, etc.

Ces données changent à chaque visite et posent problème aux robots qui considèrent cette adresse comme une nouvelle URL à chaque fois qu'ils visitent le site.

Que faire ?

  • Eviter les identifiants de session en page d'accueil et les garder pour la navigation profonde du site.
  • Pratiquer l'URL rewriting.
  • Créer des pages statiques pour la présentation de produits qui ne nécessitent pas d'identifiants de session.
  • Utiliser les cookies (moins problématiques) plutôt que les identifiants de session.

Les cookies (biscuit, témoin de connexion)

Les cookies sont des fichiers enregistrés sur l'ordinateur de l'internaute ; ils stockent des informations sur le disque dur de l'utilisateur afin de l'identifier lors d'une prochaine connexion.

Les cookies sont destinés aux navigateurs et ils ne sont pas acceptés par les robots ; ce qui constitue un frein au référencement. Il faut donc présenter une autre information aux robots afin qu'ils puissent accéder aux pages du site et les indexer.

Notons que certains utilisateurs n'acceptent pas les cookies non plus : il faut bien évidemment prévoir ce choix de navigation et tout comme pour les robots, présenter une autre information afin qu'ils puissent accéder aux pages du site.

Les accès par mot de passe

Un site accessible par mot de passe en page d'accueil ne permet pas aux robots

d'indexer vos pages (ils n'ont pas de mot de passe).

La solution :

  • Proposer des pages grand public pour acquérir une visibilité minimale et supprimer le mot de passe d'entrée de jeu.
  • Créer une zone protégée par mot de passe pour les membres.

Les tests en entrée de site

Les tests à l'entrée du site vérifient certains paramètres : la langue, la résolution d'écran, etc. Ils ne posent pas de problème, mais il faut prévoir le cas du passage des robots et mettre en place un script afin de leur permettre d'indexer les pages.

Les redirections

La redirection 301 (Moved Permanently) permet de diriger le robot vers une nouvelle adresse URL, soit d'indiquer au robot qu'une page a été déplacée. L'avantage de la redirection 301 est qu'elle permet de récupérer le PageRank qui est alors transféré vers la nouvelle page. Ce code peut être placé dans un fichier .htaccess à la racine du site et se présente comme tel :

Code :

RewriteEngine on RewriteRule ancien_fichierl.htm http://www.nouveau-site.com/fichier.htm [R=301] En crawlant vos pages, le robot va recevoir cette information et va suivre la redirection. Il faut que l'utilisation du fichier .htaccess soit possible par l'hébergeur.

L'hébergement

L'hébergement de votre site peut être un facteur bloquant; tenir compte de :

  • La réputation de l'hébergeur : Si vous êtes sur un serveur mutualisé, donc partagé par plusieurs sites, vous pouvez être pénalisé par un moteur de recherche qui bloque l'adresse IP d'un site ayant trop spammé son index. Une solution : passer du serveur mutualisé au serveur dédié.

  • L'accessibilité du serveur et la fiabilité : Votre site doit être accessible en permanence pour être visible, notamment lors du passage des robots. Mais d'autres critères doivent être pris en compte pour assurer une continuité du service d'hébergement : l'ancienneté, la réactivité et l'évolutivité. Il faut donc vérifier la garantie sur la disponibilité du serveur proposé.

  • Un hébergement gratuit n'est pas un frein majeur mais il peut en revanche s'avérer problématique pour réaliser une opération telle que l'URL Rewritting; il pose également le problème de la pérennité avec le risque de fermeture du service.

Robots.txt

Un Robots.txt impose des limitations aux robots des moteurs de recherche en les empêchant d'accéder à certaines pages.

Des directives sont incluses dans les fichiers Robots.txt ou les balises meta “robots” pendant la phase de développement afin que les moteurs n'indexent pas une page (« noindex »), un répertoire ou le site ; lors de la mise en ligne pour le grand public, ces directives ne sont pas supprimées et nuisent au référencement du site.

Les menus déroulants et formulaires

Les menus déroulants et formulaires présentent du contenu visible aux robots, mais ces robots ne savent pas suivre ces liens, car ils ne sont pas « spider compatible ». Or, les robots ou spiders se basent sur les liens pour indexer les pages.

Seule solution donc pour contrer cet obstacle au référencement : offrir un plan du site ou passer par des services tels que Google Sitemap

Les cadres ou frames

La gestion des cadres est mal prise en compte, car chaque page est divisée en plusieurs parties : la page « mère » et les pages « filles ». Les spiders considèrent souvent ces pages comme des pages distinctes et ne font pas le lien entre les pages – ils affichent alors une page orpheline, indépendamment des autres.

Si vous utilisez les frames, il faut :

  • Optimiser la page « mère » :
    1. Balise TITLE riche en mots clés.
    2. Balises META descriptives et riches en mots clés.
    3. Balise NOFRAMES incluant des mots clés et un descriptif du site.
    4. Ajouter un lien vers les fichiers des pages « filles » en l'incluant entre les balises A (la balise lien).
  • Optimiser les pages « filles » :
    1. Etablir le lien avec la page « mère » en ajoutant un code javascript dans les pages « filles ».
  1. Inclure des titres riches en mots clés.
  2. Rédiger des META riches en mots clés.

Spamdexing (ou la fraude au référencement)

Le spamdexing est sanctionné par les moteurs de recherche, il s'agit de :

  • La création de pages spécifiques pour le référencement : «pages alias», «pages satellites», «doorway pages» ou «pages fantômes». Ces pages sont optimisées pour les moteurs. Elles sont présentées lors de la visite de l'internaute et contiennent une redirection vers le vrai site.

  • La création de texte et liens cachés dans les pages. Ce sont les fonctions “visibility:hidden” ou “display:none”, l'utilisation de balises “noscript” n'ayant aucun rapport avec la balise “script” qu'elles accompagnent.

  • La pratique du cloaking (camouflage) qui consiste en la création d'une page satellite qui est présentée lors de la visite du robot. Le site Web peut envoyer différents contenus selon si la page est demandée par un utilisateur ou par un moteur de recherche.

  • Spam de recherche: il s'agit de la création d'un grand nombre de pages sans contenu réel mais dont le but est d'entrer dans les moteurs de recherche, quel que soit le mot clé demandé.

  • Spam de commentaires: c'est l'envoi d'un nombre massif de commentaires sur les blogs, forums ou autres espaces Web mentionnant un lien vers le site de l'auteur afin de faire monter sa position.

  • Réaffectation d'un domaine: achat d'un site Web qui possède une bonne quotation dans les moteurs de recherche et le remplacement du contenu existant par un autre contenu tout à fait différent.

CHAPITRE 4 - Javascript

Le javascript est un langage de programmation évolué, qui est interprété par le navigateur et procure un dynamisme des pages coté client. Il s'agit d'un script qui s'integre dans la page html, et qui permet de lancer tout type de commandes, de modifier ou de générer la page en cours. Seul les liens ne doivent pas être générés pour être vus par le robot du moteur de recherche (ex: google). Il faut très peu de temps pour tester le code via un interpréteur en ligne, par exemple:
https://jseditor.io/
(mon préféré), https://codepen.io/pen/, ou encore
https://code-basics.com/#courses

4.1. Syntaxe

Javascript utilise les conventions du langage c; la case est importante, les structures de controle sont les meme, ainsi que les operateurs. conventions: ; { } ( ) \" \b \n operandes: + - * / % = += -= = /= %= == < <= > >= != ? : || && ++ -- binaire: & | >> << commentaires: // / */ structures: if else for while break continue return

L'inclusion d'un script peut se faire de plusieurs maniere. Le code javascript peut se metre n'importe ou. En general on place les fonctions dans le head.


<script language="Javascript"> </script>
<script language="Javascript" src="url/script.js" > </script>
<a href="Javascript:alert('coucou');"> coucou </a>

  ex:  <html>
         <head>
           <script language="Javascript">
             var global1;            // variable globale
             function mult(x, y, mess) {
                 global2 = "toto"    // variable globale
                 var resultat = -1;  // variable locale
                 resultat = x * y;
                 document.write("<B>Le resultat est: " +mess +resultat + "</B>")
                 return resultat;    // retour de la fonction
             }
           </script>
         </head>
         <body onLoad="mult(3,5,'3*5=')">
         <script language="Javascript">
             alert("Terminer");
         </script>
         </body>
       </html>
 

Les variables ne sont pas typées à la déclaration, elles prenent le type de leur contenue. Les operateurs === et !== permettent de prendre en compte le type.

  • boolean : true false 2 === '2' -> false
  • number : 2.5 2 == 2 -> true
  • string : 'toto'
  • object : null, { name:'zz', age:22 }
  • function : function(){}
  • undefined

Une variable non déclarée ou non affectée, prend la valeur undefined. Une var peut être affectée à null, en tant qu'objet sans valeur. undefined et null sont deux types distincts: undefined est un type indéfini, null est un objet.


  var maVoiture = new Object();
  maVoiture.fabricant = "Ford";
  maVoiture['modele'] = "Mustang";
  maVoiture.annee = 1969;
 

Pour connaitre le type d'une variable on a la fonction typeof(toto); Les tableau sont aussi de type object. Pour différencier les objets des tableaux utiliser la méthode Array.isArray ou Object.prototype.toString.call

Vous pouvez stocker divers types de données dans un élément Array, y compris les nombres, les chaînes, les objets et même d'autres tableaux. Vous pouvez créer un tableau multidimensionnel en concevant un tableau indexé et en affectant à chacun de ses éléments un tableau indexé différent.


var a = new Array(); a=Array("a","b","c"); a=Array(3); a.length; // 3
a[4]="d"; a.length; // 4
 

Méthodes disponibles :

at(), concat(), every(callback:Function, thisObject:* = null) fill(), filter(), find(), findIndex(), flat(), flatMap(), forEach() includes(), indexOf(), join(), keys(), lastIndexOf(), map(), pop(), push(), reduce(), reduceRight(), reverse(), shift(), slice(), some(), sort(), splice(), unshift(), values(), ...

ex: data.forEach(function (item) { item.type = 2; });

Le format JSON permet de créer des objets avec des méthodes.


  var vehicule2 = {
    "marque" : "Toyota",
    "modele" : "Aygo",
    "puissance" : 48,
    "annee" : 2012,
    "age" : function() {
      /* La méthode age retourne l'age à partir de l'année du véhicule */  
      var dt=new Date();
      var age=dt.getFullYear()-this.annee;
      return age;
    }
  };
  document.write("Ce véhicule a " + vehicule2.age() + " ans");
 
  /* Détail du format de l'objet dans la console */
  console.log(vehicule2.constructor.name);
  console.log(vehicule2);
 

4.2. Evenements

Javascript integre une dizaine d'evenements exploitables. Associes aux fonctions, aux balises et aux formulaires, ces evenements permettent une reelle interactivite de vos pages.

onLoad, onUnload creation d'un evenement: onmouseOver, onmouseOut onevenement="fonction()" onFocus, onBlur onchange, onselect, onsubmit onClick


  <button class="btn">Afficher un message</button>
 

  const btn = document.querySelector('.btn');
  function showMsg() {
    console.log("Bonjour");
  }
  btn.addEventListener("click", showMsg);
  btn.removeEventListener("click", showMsg);
 
  mouseOverTarget.addEventListener('mouseover', function () {...});
 

4.3. Programmation objet

Javascript est un language objet. Il regroupe des objets contenant des attributs et des methodes. Les objets sont organises en arborescence. Par defaut c'est l'objet window qui est utilise. le lancement d'une methodes js se fait ainsi: objet.methode() ou methode() si l'objet est window ex: alert()

 #- window                  fenetre avec barre d'etat
 |    |- history                historique de la fenetre
 |    |- location               url actuelle, protocole, ...
 |    #- document               corp du texte (body)
 |    |    #- form                  formulaire (form)
 |    |    |    |- button               elements du formulaire
 |    |    |       ...
 |    |    |- image             images (img)
 |    |    |- images
 |    |    |- link              liens (a)
 |    |
 |    |- frame                  frames
 |
 #- navigator               Navigateur
 |    |- plugin
 |
 |- Date                    Date
 |- Math                    Math
 |- String                  String

4.4. Interactions

A travers les objets, javascript peut lire et modifier les attributs des balises contenus dans le document.


  ex:  <img src="Image.gif" name="nomImage" width=100 height=50 >
       document.images["nomImage"].src = "nouvelleImage.gif";
       document.images["nomImage"].width = 110;
 

L'utilisation la plus courante, est sur les formulaires:


       <form name="nomform">
       <input type="text" name="input" value="">
       <input type="button" name="bouton" value="Controler" onClick="fct()" >
       <input type="radio" name="choix" value="1" id="RD1">
       <select name="nationalite" size="1"> ...
       </form>
 

       document.nomform.input.value = "toto";
       document.forms[0].elements["input"].value = "toto";
       // ici forms[0] se refere au premier formulaire de la page.
       document.nomform.choix[0].checked = False;
       document.forms[0].elements["RD1"].checked = False;
       document.nomform.selectedIndex = 0;
       document.forms[0].elements["nationalite"].selectedIndex = 0;
 

4.5. Actions programmees

Il est possible de programmer des actions qui serons exécutées après un certain temps


function winClose() { myWindow.close() }
myWindow = window.open("", "tinyWindow", 'width=150, height=110')
myWindow.document.write("Fermeture dans 5 secondes.")
const myTimeout = self.setTimeout('winClose()', 5000);
function myStopFunction() {
  clearTimeout(myTimeout);
}
 

4.6. Prototypes et héritage: les classes en Javascript

JavaScript est un langage basé sur des prototypes, et chaque objet en JavaScript possède une propriété interne cachée appelée [[Prototype]] qui peut être utilisée pour étendre les propriétés et les méthodes des objets. Nous pouvons accéder au [[Prototype]] d'un objet avec la méthode Object.getPrototypeOf().

Jusqu'à récemment, les développeurs industriels utilisaient des fonctions de constructeur pour imiter un modèle de conception orienté objet en JavaScript. La spécification de langage ECMAScript 2015, souvent appelée ES6, a introduit des classes dans le langage JavaScript. Les classes en JavaScript n'offrent pas réellement de fonctionnalités supplémentaires, et sont souvent décrites comme fournissant du « sucre syntaxique » par rapport aux prototypes et à l'héritage, en ce sens qu'elles offrent une syntaxe plus propre et plus élégante. Comme d'autres langages de programmation utilisent des classes, la syntaxe des classes en JavaScript permet aux développeurs de passer plus facilement d'un langage à l'autre.

Une classe JavaScript est un type de fonction. Les classes sont déclarées avec le mot-clé class. Nous utiliserons la syntaxe d'expression de fonction pour initialiser une fonction et la syntaxe d'expression de classe pour initialiser une classe.


  // Initializing a function with a function expression
  const x = function() {}
  Object.getPrototypeOf(x); // ƒ () { [native code] }

  // Initializing a class with a class expression
  const y = class {}
  Object.getPrototypeOf(y); // ƒ () { [native code] }

L'opérateur  instanceof permet de tester si un objet possède,  dans sa chaîne de
prototype, la propriété prototype d'
un certain constructeur.

  function Car(make, model, year) {
    this.make = make;
    this.model = model;
    this.year = year;
  }
  const auto = new Car('Honda', 'Accord', 1998);
 
  console.log(auto instanceof Car);
  // expected output: true
 
  console.log(auto instanceof Object);
  // expected output: true
 

constructeur:

Les codes déclarés avec function et class renvoient tous deux une fonction [[Prototype]]. Avec les prototypes, toute fonction peut devenir une instance de constructeur en utilisant le mot-clé new.


  const x = function() {}  const y = class {}
  const xx = new x();      const yy = new y();
  console.log(xx);         console.log(yy);
  // x {}                  // y {}
  // constructor: ƒ ()     // constructor: class
 

Une fonction de constructeur est initialisée avec 0 à n paramètres, qui seraient attribués comme propriétés de this, en référence à la fonction elle-même. La première lettre de l'identifiant serait en majuscule par convention.

La pratique courante avec les fonctions de constructeur est d'assigner les méthodes directement au prototype plutôt que dans l'initialisation, comme on le voit dans la méthode greet() ci-dessous.


  function Hero(name, level) {            class Hero {
    this.name = name;                       constructor(name, level) {
    this.level = level;                       this.name = name;
  }                                           this.level = level;
                                            }
  Hero.prototype.greet = function() {       greet() {
    return `${this.name} says hello.`;        return `${this.name} says hello.`;
  }                                         }
                                          }

  function Global() {
    this.constructor = function() {
    }
    this.constructor();
    // Fonctions Privées ne pouvant pas appeler d'autre references de la classe
    function lireFichier(sUrl) {
    }
    // Fonctions Publiques inaccessible en amont
    this.TraitementFichierXML = function (sNnFnXML) {
    }
  }
  var _root = new global();
 

héritage

De nouvelles fonctions de constructeur peuvent être créées à partir du parent en utilisant la méthode call(). Cela revient a créer une classe qui hérite de Hero:


  function Mage(name, level, spell) {   class Mage extends Hero {
    Hero.call(this, name, level);          constructor(name, level, spell) {
    this.spell = spell;                      super(name, level);
  }                                          this.spell = spell;
                                           }
                                         }
const hero2 = new Mage('Lejon', 2, 'Magic Missile');
 

réf: Comprendre les classes en JavaScript
https://www.digitalocean.com/community/tutorials/understanding-classes-in-javascript-fr
réf: Promesses
https://smnarnold.com/cours/javascript/promesses

4.7. Ajax avec XMLHTTPRequest

AJAX (Asynchronous JavaScript and XML) permet de mettre à jour certaines parties d'une page sur base d'évènements déclenchés par l'utilisateur sans recharger la page. L'objet XMLHttpRequest permet d'échanger des informations sous différents formats (dont XML, HTML ou texte). La page générant les données sera faite ici en php, mais elle aurai très bien put etre en asp.

Fichier ajax.js


function ajaxXmlHttp() {
  var xmlhttp = false;
  /* Compilation conditionnelle d'IE */
  /*@cc_on
  @if (@_jscript_version >= 5)
    try {
      xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (E) {
        xmlhttp = false;
      }
    }
  @else
    xmlhttp = false;
    @end @*/


  /* on essaie de créer l'objet si ce n'est pas déjà fait */
  if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
    try{
      xmlhttp = new XMLHttpRequest();
    } catch (e) {
      xmlhttp = false;
    }
  }
  return xmlhttp ;
}
 

Pour déclarer ce qui se produit lorsque la réponse est reçue:


httpRequest.onreadystatechange = function() { // traitement de la réponse };
 

Pour lancer effectivement la requête serveur, il faut appeler les méthodes:


httpRequest.open('GET', 'http://www.example.org/some.file', true);
httpRequest.send();
 

Pour des raisons de sécurité, il n'est pas possible d'appeler des pages sur un autre domaine. Les données doivent être sous la forme d'une chaîne de requête : nom=valeur&autrenom=autrevaleur&ainsi=desuite

Pour envoyer des données avec la méthode POST, il faut changer le type MIME:


httpRequest.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
 

Quand la réponse est reçu, la fonction déclarée doit vérifier l'état de la requête. Si cet état a une valeur de 4, cela signifie que la réponse du serveur a été reçue dans son intégralité et qu'elle peut maintenant être traitée. La 2nd vérification concerne le code d'état de la réponse HTTP du serveur (200=OK).

Pour accéder à ces données la fonction dispose de deux méthodes: * httpRequest.responseText — chaîne de texte * httpRequest.responseXML — objet XMLDocument qui se traite avec des fonctions DOM de JavaScript.

Fichier cp.html


<html>
  <head>
    <title>Ville par cp </title>
    <script type="text/javascript" src="ajax.js"></script>
    <script type="text/javascript">
    <!--
   /* Appel Ajax */
   function maj_ville(cp)
   {
     // recuperation de l'objet
     var xmlhttp=ajaxXmlHttp();
     xmlhttp.open("GET","ville.php?cp="+escape(cp),true);
     // traitement le la reponse du serveur
     xmlhttp.onreadystatechange=function(){
       try { // reponse terminée et statut OK
         if((xmlhttp.readyState==4)&&(xmlhttp.status==200))
         {
           var elt= document.getElementById("commune");
           elt.innerHTML=xmlhttp.responseText;
           document.getElementById("wait").style.visibility="hidden";
         }
       }
       catch( e ) {
         alert("Une exception s'est produite : " + e.description);
       }
     }
     document.getElementById("wait").style.visibility="visible";
     xmlhttp.send(null);
   }
   
   function maj_dpt(cp)
   {
     // recuperation de l'objet
     var xmlhttp=ajaxXmlHttp();
     var html;
     xmlhttp.open("GET","dptx.php?dpt="+escape(cp),true);
     // traitement le la reponse du serveur
     xmlhttp.onreadystatechange=function(){
     if((xmlhttp.readyState==4)&&(xmlhttp.status==200))
     { // reponse terminée et statut OK
       if(typeof XSLTProcessor != 'undefined') {
         var transfo = new XSLTProcessor();
         var donnees=xmlhttp.responseXML;
         xmlhttp.open("GET", "dpt.xsl", false);
         xmlhttp.send(null);
         // chargement du xsl dans la moulinette
         transfo.importStylesheet(xmlhttp.responseXML);
         // lancement transformation
         html = transfo.transformToDocument(donnees);
       }
       else {
         var style=new ActiveXObject("Microsoft.XMLDOM");
         style.async = false;
         style.load("dpt.xsl");
         html=xmlhttp.ResponseXML.transform(style);
       }
       
       var elt= document.getElementById("departement");
       elt.innerHTML=html;
       document.getElementById("wait").style.visibility="hidden";
       }
     }
     document.getElementById("wait").style.visibility="visible";
     xmlhttp.send(null);
   }
   -->
    </script>
 
  </head>
  <body>
    <label for="cp">Code postale </label>
    <img  id="wait" src="wait.gif" style="visibility:hidden"/>
    <input type="text" id="cp" onchange="maj_ville(this.value)"/>
    <br>
    <label for="dpt">Departement </label>
    <input type="text" id="dpt"  onchange="maj_dpt(this.value)"/>
    <br>
    <span id="commune"></span>
    <br>
    <span id="departement"></span>
  </body>
</html>
 

Fichier dpt.xls


<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" />
 
  <xsl:template match="departement"> <!-- expression xpath -->
    <tr><td><xsl:value-of select="@nom"/></td></tr>
  </xsl:template>
 
  <xsl:template method="/">
    <table border=1 sumary="Departements resultat">
    <tr><th>Departements</th></tr>
    <xsl:apply-template />
  </table>
  </xsl:template>

</xsl:stylesheet>
 

Si vous envoyez une requête vers un bout de code dynamique qui renvoie du XML, plutôt que vers un fichier XML statique, vous devez définir certains en-têtes de réponse pour que votre page fonctionne; Content-Type: application/xml

Fichier ville.php


<?php
  require_once('lib/db.inc.php');
  header("Pragma:no-cache");
  header("Expires:0");
 
  if(isset($_REQUEST['dpt']))
  {
    $result=mysql_query("SELECT distinct dpt FROM villes WHERE dpt like '"
      .addslashes($_REQUEST['dpt'].'%')."' ");
    if ($result) {
      $json = '{ "resultats" : [';
      $sep='';
      while($row=mysql_fetch_array($result)) {
        $json = $json.$sep."\"".$row['dpt']."\"";
        $sep = ',';
        //sleep(5); // Pour voir la temporisation
      }
      $json = $json."] }";
    }
    echo $json;
  }
?>
 

Fichier dpt.php


<?php
  require_once('lib/db.inc.php');
  header("Pragma:no-cache");
  header("Expires:0");

  if(isset($_GET['cp']))
  {
   
    $result=mysql_query("SELECT commune FROM villes WHERE cp like '"
      .addslashes($_GET['cp'])."' LIMIT 0,1");
    //select distinct dpt from villes where dpt like "%"
    if($result &&($row=mysql_fetch_array($result))) {
      echo "<br>".$row['commune'];
      //sleep(5); // Pour voir la temporisation
    }
    else
      echo "non";
  }
?>
 

CHAPITRE 5 - jQuery

5.1. Fonctionnement

jQuery est une librairie Javascript libre qui fait interagir javascript et HTML, et dont l'intérêt est de simplifier les commandes les plus utilisées. Permet de:

  • parcourir et de modifier le DOM,
  • d'attribuer des actions à des évènements,
  • d'implémenter des effets visuels / animations,
  • de manipuler le CSS, d'implémenter Ajax facilement, etc.

Sélecteurs d'élément :

jQuery utilise des sélecteurs CSS pour sélectionner des éléments HTML.


$(this) Élément HTML actuel 
$("p") sélectionne tous les éléments  <p>.
$("p.intro") sélectionne tous les éléments <p> de classe = « intro »
$("p#intro") sélectionne tous les éléments  <p> avec l'id = « intro ».
$("p#intro:First") Le premier élément  <p> avec l'id = « intro »
$(".intro") Tous les éléments de classe = « intro »
$("#Intro") Le premier élément avec id = « intro » 
$("ul li:first") Le premier élément <li>  de  chaque liste <ul> 
$("div #intro .head") elmts de classe = « head » dans un élément <div> avec l'id

^ element qui commencent par
$ elements qui terminent par
* element contenant

Sélecteurs d'attribut :

jQuery utilise les expressions XPath pour sélectionner les éléments ayant des attributs donnés.


$("[href]") sélectionner tous les éléments avec un attribut href.
$("[href='#']") sélectionner tous les éléments avec une valeur de href à "#".
$("[href!='#']") sélectionner elmts avec un attribut href différent de "#".
$("[href$='.jpg']") sélectionner elmts avec href qui se termine par ".jpg".

Sélecteurs CSS :

Les sélecteurs CSS jQuery permet de modifier les propriétés CSS pour les éléments HTML. Ex: modifie la couleur d'arrière-plan des éléments p :


  $(document).ready(function(){
    $("button").click(function(){
      $("p").css("background-color","#FFFF00")
    })
  })
 

Sélecteur personnalisé :


  <!doctype html>
  <html lang="fr">
  <head>
  <meta charset="utf-8">
      <title>Sélecteur personnalisé jQuery</title>
  <style>
      *{
          padding: 5px;
      }
  </style>
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <script>
  $(document).ready(function(){
    // Lignes de tableau apparaissant à des places impaires */
    $("tr:odd").css("background", "yellow");
 
    /* Lignes du tableau qui apparaissent à des places paires*/
    $("tr:even").css("background", "orange");
 
    /* Le premier paragraphe*/
    $("p:first").css("background", "red");
 
    /* Le dernier élément du paragraphe*/
    $("p:last").css("background", "green");
 
    /* Tous les éléments de saisie de type texte dans un formulaire*/
    $("form :text").css("background", "purple");
 
    /* Tous les éléments de saisie avec le type password dans un formulaire*/
    $("form :password").css("background", "blue");
 
    /* Tous les éléments d'entrée avec le type submit dans un formulaire*/
    $("form :submit").css("background", "aqua");
  });
  </script>
  </head>
  <body>
      <table border="1">
          <thead>
              <tr>
                  <th>No.</th>
                  <th>Nom</th>
                  <th>Email</th>
              </tr>
          </thead>
          <tbody>
              <tr>
                  <td>1</td>
                  <td>John Carter</td>
                  <td>johncarter@mail.com</td>
              </tr>
              <tr>
                  <td>2</td>
                  <td>Peter Parker</td>
                  <td>peterparker@mail.com</td>
              </tr>
              <tr>
                  <td>3</td>
                  <td>John Rambo</td>
                  <td>johnrambo@mail.com</td>
              </tr>
          </tbody>
      </table>
      <p>C'est un paragraphe.</p>
      <p>C'est un autre paragraphe.</p>
      <p>C'est un paragraphe de plus.</p>
      <form>
          <label>Nom: <input type="text"></label>
          <label>Password: <input type="password"></label>
          <input type="submit" value="Sign In">
      </form>
  </body>
  </html>
 

désactiver un bouton:


$("#save_config").prop('disabled', (!isValid || isLockedConfig));
 

désactiver des champs:


var communIdToDisable = '#booking_form_datepicker, #heureDebutRdv, #dureeRdv,'
        + ' #civilite-mr, #civilite-mme, #fp-nom, #fp-prenom, #fp-naissance-j'
        + ' #fp-blacklist-free, #fp-blacklist-blocked, #fp-addrdvbtn';
$(communIdToDisable).prop("disabled", true);
 

jQuery possèdes des fonction de manupulation du DOM : - append, appendTo pour ajouter un élément enfant à la fin d'un élément - prepend, prependTo pour ajouter un élément enfant au début d'un élément - remove pour supprimer un élément du DOM ex : $('.dup').remove() - wrap pour encapsuler un élément dans un autre - hasClass, addClass, toggleClass, removeClass pour ajouter / inverser une class


  $('<span>(bureau)</span>').appendTo('.telBureau');
  $('.telBureau').append('<span>(bureau)</span>');
  $('<span>Tel:</span>').prependTo('.tel');
  $('.tel').prepend('<span>Tel:</span>');

  <div class="pomme">Golden</div>
  $('.pomme').wrap('<div class="fruitslegumes" />');
  // Resultat
  <div class="fruitslegumes">
    <div class="pomme">Golden</div>
  </div>
 
  $('p').removeClass('class1 class2');
 

jQuery permet de parcourrir des éléments sélectionnés du DOM, ou les éléments enfants d'un div :


  $('div').each(function(index) {         $('div').each(function(index, elem) {
    alert(index + '=' + $(this).text());    alert(index + '=' + $(elem).text());
  });                                     }); // elem = this
 
  <div id="section">
    <input type="checkbox" name="name-1" id="name-1">
    <input type="checkbox" name="name-2" id="name-2">
    <input type="checkbox" name="name-3" id="name-3">
  </div>
 
  $("#section").children('input').each(function () {
    $(this).prop("disabled", true);
  });
 

jQuery permet de definir des évenements : click, changemouseenter, mouseleave...


  $('#cible').click(function (e) { alert($(e.target).attr('id')); });
  $('#cible').off(); // detacher l'evenement précédemment attaché
  $('#cible').off('click'); // detacher l'evenement click
  $('#cible').on('mouseenter mouseleave', function () { ... });
  $('#cible').on('click', 'tr', function (e) { ... });
  // les deux commandes suivantes sont equivalentes :
  $('#cible').on({ mouseenter: function () {}, mouseleave: function () {}});
  $('#cible').hover(function () {}, function () {});
 

jQuery permet d'attacher des événements a un type d'élement, ainsi l'action est déclenché même sur les nouveaux éléments ajoutés dans le DOM.

$('#table tbody').on('click', 'tr', function (e) { ... });

réf: jQuery c'est quoi?
https://creersonsiteweb.net/page-apprendre-jquery
réf: les sélecteurs jQuery
http://www.oujood.com/jquery/selecteurs-jQuery.php

5.2. Ajax et Formulaires


  <HEAD>
      <link href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" rel="stylesheet">
      <link rel="stylesheet"  href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css">
  </HEAD>
  <body>
  <form id="saveForm" data-action-save="api/Save" action="" method="post">
    <input type="hidden" name="idPatient" />

    <label for="selectMode"><b>Mode de paiement</b></label>
    <select name="selectMode" class="vdInput cLeftPannel"></select>

    <label for="quotationName">NOMDEVIS</label>
    <input type="text" name="quotationName" class="vdInput cLeftPannel" />

    <label for="payor">PAYEUR</label>
    <input type="text" name="payor" class="vdInput cLeftPannel" />

    <label for="amount">MONTANT</label>
    <input type="number" name="amount" class="vdInput cLeftPannel" required />

    <label for="dpDate" style="position: relative;top: 25px;">Date</label>
    <a href="#" class="input-modal btnDatePicker"
    onclick="openDatePicker(event)" style="left: 96px;position: relative;"></a>
    <input style="width:125px;" name="dpDate" type="text"
     class="vdInput datepicker hasDatepicker" data-date
     placeholder="Ex : 01/01/2017"
     data-validate-hint="Date de d&eacute;but invalide!"
     data-date-start-date="0d" required>

    <div style="width:225px;"  class="form-group">
      <div class="datepicker date input-group">
        <input type="text" placeholder="Choisir une date" class="form-control" id="reservationDate">
        <div class="input-group-append"><span class="input-group-text px-4"><i class="fa fa-calendar"></i></span></div>
      </div>
    </div>

    <label for="numberPayments">ECHEANCES</label>
    <input type="number" min="1" name="numberPayments" class="vdInput cLeftPannel" required />

    <label for="periodicity">PERIODICITE</label>
    <select name="periodicity" class="vdInput cLeftPannel">
        <option value="1">1 semaine</option>
        <option value="2">2 semaines</option>
        <option value="10">1 mois</option>
        <option value="20">2 mois</option>
        <option value="30">3 mois</option>
        <option value="60">6 mois</option>
        <option value="120">1 an</option>
    </select>

    <input class="vdBtn btnForm blue" type="submit" value="+" />
  </form>

  <script type="text/javascript">
 

    //Affichage du datepicker
    function openDatePicker(event) {
        $($(event.target).next()).datepicker("show");
    }

    $(document).ready(function () {
      $('.datepicker').datepicker({
        language: "fr",
        todayHighlight: true,
        showOnFocus: false,
        autoclose: false,
      });
      $('form#saveForm').submit(create);
    });
   
    function create(e) {
      e.preventDefault();
      var $form = $("form#saveForm");
      if (!$form.valid()) return false;
      //var formData = new FormData($('#uploadForm')[0]);
      var action = $("#saveForm").attr("data-action-save");
      $.ajax(action, {
        type: "POST",
        data: $("form#saveForm").serialize(),
        success: function (result) {
          if (result.success) {
            console.log(result.data);
          } else {
            alert(result.msg);
          }
        }
      });
    }
 

  </script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js"></script>
  </body>
  </html>
 

  [httpPost]
  public JsonResult Save(int patientId, int? selectMode, string quotationName,
    string payor, decimal amount, DateTime dpDate, int numberPayments,
    int periodicity)
  {
    return Json(new { success = true, data = "OK" });
  }
 

jQuery permet de factoriser le code en appliquant a tout un ensemble d'élement un comportement particulier. En voici un exemple pratique pour le datePicker :


  function ValidateDate(date) {
    return
      /^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-]\d{4}$/.test(date);
  }

  function formatInputDate(elem) {
    if (!ValidateDate(val)) {
      $.Notify({
        caption: 'Erreur',
        content: $(elem).attr('data-validate-hint'),
        type: 'alert',
        timeout: 0,
        keepOpen : true
      });
    }
  }

  $("[data-date]").focusout(function () {
    var _input = this;
    setTimeout(function () { formatInputDate(_input); }, 100);
  });
 

réf: How to Use jQuery Validator for Your Form Validation
https://www.solodev.com/blog/web-design/how-to-use-jquery-validator-for-your-form-validation.stml

5.3. DataTable

Pour utiliser DataTables, vous devez tout d'abord inclure, dans le fichier html, les bibliothèques jQuery et DataTables dans l'en-tête de la page html (head), ainsi que le fichier de style CSS de DataTables :

Le tableau html doit contenir l'élément thead, et l'élément tbody : Eventuellement utiliser un style CSS .tableHeader {display: table-row-group;}


  <body>
    <table id='tab' class='display'>
      <caption>Fromages</caption>
      <thead class="tableHeader">
        <tr><th>Nom</th><th>Lait</th><th>Prix</th></tr>
      </thead>
      <tbody>
        <tr> <td>Roquefort</td> <td>brebis</td> <td>4</td> </tr>
        <tr> <td>Morbier</td>   <td>vache</td>  <td>1</td> </tr>
        ...
      </tbody>
    </table>
  </body>
  </html>
 

Dans le javascript, associez DataTables au tableau dont l'id a la valeur tab :


  // fichier tableau.js
  $(document).ready(function () {
    $('#tab').DataTable({
      "paging":   false,
      "ordering": false,
      "info":     false,
      dom: 'lftrip',
      language: {
        url: "http://cdn.datatables.net/plug-ins/1.10.9/i18n/French.json"
      }
    });
  });
 

L'option dom de DataTables permet de définir les éléments de contrôle du tableau qui seront affichés ainsi que leur ordre dans la page. Ci dessous, les contrôles disponibles pour cette option :

  • l Affiche le select indiquant le nombre de lignes à afficher par page
  • f Affiche le champ permettant de filtrer les données du tableau
  • i Affiche des informations
  • p Affiche le menu de pagination
  • t Indique l'emplacement du tableau par rapport aux contrôles
  • r Affiche un message de traitement

Par défaut la valeur de dom est lftrip. Il est possible d'utiliser plusieurs fois la même lettre pour dupliquer un contrôle.

Quelques options de base des DataTables :

  • pagingType: "simple", lengthMenu: [5, 10, 15], pageLength: 3
  • order:[[1,'desc'], [0, 'asc']]
  • fixedColumns: true
  • scrollY = 20vh et scrollCollapse: true pour limiter la hauteur du tableau.
  • scrollX = true: pour etiter l'extention du tableau.
  • "lengthMenu": [20, 50, 100, 500, 1000],
  • "lengthChange": true,

L'option columns, permet entre autre de définir le type de la colonne. Le type de la colonne sera pris en compte pour le tri. Une cellule peut contenir des éléments html (dont des input). Pour ignorer les balises html du trie, il faut donner le type html. Quelques options de base des Colonnes :

  • width
  • visible
  • render

  columns: [
          {type:"text"},
          {type:"html"},
          {type:"num"},
          {orderable:false}
  ]
 

Le style du tableau est contrôlé par une ou plusieurs classes de style prédéfinies (voir tableau ci-après), placées dans l'attribut class de l'élément table :

  • cell-border Encadre les cellules
  • row-border Encadre les lignes
  • stripe Alterne les couleurs de fond des lignes
  • hover Change la couleur de fond de la ligne survolée par la souris
  • order-column Change la couleur de fond des colonnes triables
  • display Raccourci pour stripe, hover, row-border, order-column
  • nowrap Désactive le passage à la ligne dans une cellule
  • compact Diminue les espaces dans les cellules

  <table id='tab' class='display compact cell-border'>
 

DataTables supporte les thèmes bootstrap, jQuery UI, ThemeRoller UI. Pour personnaliser le thème par défaut on a l'interface de création de thème :
https://www.datatables.net/manual/styling/theme-creator
. Il y a une grande variétés de add-ons (TableTools, FixedHeader, KeyTable…), La possibilité de copier, imprimer ou d'exporter votre tableau sous format PDF, CSV ou Excel.

DataTables est livré avec une API étendue, qui est utilisée pour manipuler les informations sur les DataTables sur une page. Une fois l'objet défini, vous pouvez appeler n'importe laquelle des fonctions de l'API sur cet objet. L'API est accessible de 3 manières :


  var table = $('#tableid').DataTable(); //DataTable() returns an API instance
  var table = $('#tableid').dataTable().api(); //dataTable() returns a object
  var table = new $.fn.dataTable.Api('#tableid');
  var columns = table.columns();
  table.rows.add( [ { }, { } ]).draw();
 

pour affecter les données d'une datatable:


  var newdata = $('#tab').DataTable().rows().data();
  $('#tabCopy').DataTable().clear();
  $('#tabCopy').DataTable().rows.add(newdata).draw();

  // Initialise un dataset de test
  var dataset = [];
  for (let i = 0; i < 250000; i++) {
    var arr =
      [i, "Donnee de test: " + i, Math.random()];
    dataset.push(arr);
  }
 

C'est le code pour filtrer les Datatables [1.10.7] par valeur par programmation, vous pouvez le trouver sur la documentation officielle.


  function setFilterValue(datatable, value){
    if(datatable !== undefined){
      datatable.columns(0).search(value).draw();
    }
  }
 

C'est le code pour obtenir la valeur par la recherche précédente. Cette approche est utile lorsque le cache est actif ( "stateSave": true ), et que vous devez connaître la valeur de recherche précédente après avoir rechargé la page.


  function getFilterValue(datatable){
    var value;
    if(datatable !== undefined){
      value = datatable.settings()[0].oSavedState.columns[0].search.search;
    }
    return value;
  }
 

Utilisation de la fonction API Datatables intégrée fnFilter : Nous passons deux paramètres à cette méthode - la chaîne de requête et l'index de la colonne à filtrer. Dans ce cas, la valeur de la case à cocher sera «Checked» si elle est sélectionnée dans l'interface utilisateur et l'index de la colonne contenant les cases à cocher est 8. Nous passons donc «Checked», et 8 en tant que pamaeters à la fonction fnFilter. On peut trouver sur d'anciennes version de DataTable la méthode search à la place de la méthode fnFilter.


  <a href="#" class="show_selected">eeee</a>

  $(document).ready(function ()
  {
    $('.show_selected').click(function() {
      $('.show_selected').text(function(_,txt) {
        var checked = 0;
        var ret='';
        var dataTable = $("#report_table").dataTable();
        if ( txt == 'Show Selected Reports' ) {
          dataTable.fnFilter('Checked',8);
          ret = 'Show All Reports';
        }else{
          dataTable.fnFilter('',8);
          ret = 'Show Selected Reports';
        }
        return ret;
      });
    });
  });
 

Quand une dataTable est réactualisée, elle reviens sur la page 1. Pour garder sélectionné le numéro de page et de revenir après l'actualisation.


  $('#offersTable').dataTable({
    "bStateSave": true,
    "fnStateSave": function (oSettings, oData) {
      localStorage.setItem('offersDataTables', JSON.stringify(oData));
    },
    "fnStateLoad": function (oSettings) {
      return JSON.parse(localStorage.getItem('offersDataTables'));
    }
  });
 

Ou dans les tables de données 1.10 : table.row(index).data(data).draw(false); Ou avec ajax: $('#YOUR_TABLE_ID').DataTable().ajax.reload(null, false);

réf: DataTables : interagir avec les tableaux HTML
https://connect.ed-diamond.com/GNU-Linux-Magazine/glmf-189/datatables-interagir-avec-les-tableaux-html
réf: datatables - RIP Tutorial
https://riptutorial.com/Download/datatables-fr.pdf
réf: Garder sélectionné le numéro de page après le rappel
https://askcodez.com/datatables-garder-selectionne-le-numero-de-page-apres-le-rappel.html

5.4. DataTable : Chargement avec un Appel Ajax

La propriété ajax de la dataTable, permet d'exécuter un appel ajax directement pour alimenter la table. deferLoading: 0, permet de différer le chargement de la table, après le choix de filtres de recherche par exemple.


  "ajax": {
      "url": "/loadGoodsDestroyed",
      "type": "POST",
      "dataType": "json",
      "dataSrc": "data",
      "data": {start_date: start_date, end_date: end_date}
  },
 

Voici un exemple d'appel ajax


  $(document).ready(function () {
    $.ajax({
      type: "POST",
      url: "DatatableGrid.aspx/GetData",
      contentType: "application/json; charset=utf-8",
      data: "{'startIndex' :" + "0" + ",'maximumRows' :" + "100" + "}",
      dataType: "json",
      success: function (response) {
        LoadData(response.d, "#grid");
      },
      failure: function (errMsg) {
        $('#errorMessage').text(errMsg); //errorMessage is id of the div
      },
      error: function (errMsg) {
        alert("Error!!");
      }
    });
  });
  function LoadData(result, grid) {
    var dtData = [];
    if (grid == "#grid") {
      $.each(result, function () {
        var date = this.BirthDate;
        var newdate = ConvertJsonDateString(date);
        this.BirthDate = newdate;
        dtData.push([ this.EmployeeID, this.FirstName ]);
      });
      var table; var data;
      table = $(grid).dataTable({  //grid is the id of the table
          'aaData': dtData
      });

      table.$('tr').click(function () {
          $(this).toggleClass('selected');
      });
    }
  }
  // Convert data of selected row of datatable in Json form
  function GetSelectedRow() {
    var table = $('#grid').Datatable();
    var data = table.rows(['.selected']).data().toArray();
    var json = JSON.stringify( data );
    alert(json);
  }
 

réf: Create Json string From datatab
https://datatables.net/forums/discussion/36669/create-json-string-from-datatable-selected-selected-row

5.5. DataTable : Edition

Le controller du back end renvoit au format Json un tableau d'objects. Ce type d'objet inclut différents formats de type dateTime par exemple.

public JsonResult LoadDocuments(int patientId)

Le HTML


  <head>
  <script language="Javascript"
  src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js"></script>
  <link rel="stylesheet" type="text/css"
  href="https://cdn.datatables.net/1.11.5/css/jquery.dataTables.min.css">
  </head>
  <body>
  <table class="vdFTable" data-auto-width="false" id="tableDocument"
      data-action-load="api/loadDocuments">
    <thead class="vdFTableHeader">
        <tr>
            <th>Nom du fichier</th>
            <th>Dossier</th>
            <th>Date</th>
            <th>Type</th>
            <th></th>
        </tr>
    </thead>
    <tbody class="vdFTableBody"></tbody>
  </table>
  </body>
 

Le javascript


  <script language="Javascript">
  // Donnees de test
  var demo = true;
  var dataset = [];
  var dates = ["/Date(1253034567877)",
    "/Date(1293034567877)", "/Date(1223034567877)"];
  for (let i = 0; i < 1000; i++) {
    dataset.push({
      "id" : i,
      "name" : "Donnee de test: " + Math.random(),
      "date" : dates[i % 3],
      "location" : "C:\\"
    });
  }

  /**
   * à partir d'un objet date, retourne la date sous forme "dd/mm/yyyy"
   **/

  Date.prototype.getStringDate = function () {
    return [
      (this.getDate()    ) < 10 ? '0' + this.getDate()      : this.getDate(),
      (this.getMonth()+1)  < 10 ? '0' + (this.getMonth()+1) : this.getMonth()+1,
      (this.getFullYear()) < 10 ? '0' + this.getFullYear()  : this.getFullYear()
    ].join('/');
  }

  $(document).ready(function () {

    $('#tableDoc tbody').on( 'click', 'tr', function () {
      if ( $(this).hasClass('selected') ) {
        $(this).removeClass('selected');
      }
      else {
        $('#tableDoc').DataTable().$('tr.selected').removeClass('selected');
        $(this).addClass('selected');
      }
    });

    $('#tableDoc').DataTable({
      dom: "Trt",
      data: [],
      pageLength : 50,
      scrollY: "20vh",
      scrollX: true,
      scrollCollapse: true,
      columns: [
        {
          data: "name",
          render: function (val, type, row) {
            if (row.isEditing) {
              var ret =
              "<span style='display:none; color:transparent'>"
              + val + "</span>" + "<input class=\"vdInput\" type='text' id='"
              + row.id + "-fileName' value='" + val + "'/>";
              return ret;
            } else {
              return val;
            }
          }
        },
        {
          data: "location",
          visible:false
        },
        {
          data: "date",
          render: function (val, type, row) {
            if (val != null) {
              var re = /-?\d+/;
              var m = re.exec(val);
              var d = new Date(parseInt(m[0]));
              if (type === "display")
                  return val ? d.getStringDate() : '';
              else
                  return (m[0]);
            }
          },
          defaultContent: ""
        },
        {
          data: "name",
          render: function (val, type, row) {
            return val.split('.')[1];
          }, visible: false
        },
        {
         data: "id",
         render: function (val, type, row) {
           if (row.isEditing) {
             var ret = "<button class='mif-undo bg-white buttonTable' data-role='hint' data-hint='Annuler' onclick='cancelRenameDocument(" + val + ")'></button>";
             ret += "&nbsp;" + "<button class='mif-floppy-disk bg-white buttonTable' data-role='hint' data-hint='Enregistrer' onclick='saveRenameDocument(" + val + ")'></button>";
             return ret;
           } else {
             var ret = "<a href='#' hint='Renommer' onclick='renameDocument(" + val + ")'>R</a>";
             return ret;
           }
         },
         orderable: false,
         width: 140
        }
      ],
      language: {
        url: "http://cdn.datatables.net/plug-ins/1.10.9/i18n/French.json"
      }
    });
    loadDocuments();
  });


  function loadDocuments() {
    var params = {
        patientId: $("#patient_id").val()
    };

    var action = $("#tableDoc").attr("data-action-load");
    if (demo) {
      var $tableDocument = $('#tableDoc').DataTable();
      $tableDocument.clear().draw();
      $tableDocument.rows.add(dataset).order([[2, 'desc'], [0, 'asc']]).draw();
    }
    else
    $.ajax(action, {
      type: 'POST',
      data: params,
      success: function (result) {
        if (result.success) {
          var $tableDocument = $('#tableDoc').DataTable();
          $tableDocument.clear().draw();
          $tableDocument.rows.add(result.data)
          .order([[2, 'desc'], [0, 'asc']]).draw();
        } else {
          notifyError(result.msg);
        }
      }
    });
  }

  function renameDocument(id) {
    documentEditing = true;
    var row = $('#tableDoc').DataTable().row('.selected').data();
 
    if (row == undefined || id != row.id) {
        setTimeout(function(){renameDocument(id)}, 100);
        return;
    }

    row.isEditing = true;
    $('#tableDoc').DataTable().rows().invalidate().draw();
  }
  </script>
 

Remarquez la fonction de render pour le champ de type Date. Le type 'display', permet de formater pour l'affichage, l'autre type, c'est le format pour le trie. Ci dessous une fonction javascript qui permet de faire la même chose, de manière plus condensée :


  //formatage de la date pour l'affichage dans un datatable
  function formatDateToDtString(val) {
    eval("var d1 = new " + val.replace(/\//g, ''));
    var d2 = "<span style='display: none;'>"
      + [d1.getFullYear(), (d1.getMonth()+1).pad(2), d1.getDate().pad(2),
      d1.getHours().pad(2), d1.getMinutes().pad(2), d1.getSeconds().pad(2)]
      .join('/') + "</span>";
    d1 = [d1.getFullYear(), (d1.getMonth() + 1).pad(2), d1.getDate().pad(2)]
      .reverse().join('/');
    return d2 + d1;
  }
 

Exemple pratique d'un evennement sur un champ ckeckbox dans un dataTable :


  $('#tableDetails tbody').on('click', 'td', function () {
    var table = $('#tableSchedulePaymentDetails').DataTable();
    var cell = table.cell(this);
    var colIndex = cell.index().column;
    if (colIndex === 6) {
      var isChecked = $("#pascheduleid-" + cell.data()).is(":checked");
      $("#tableDetails input[type='checkbox']:checked").prop("checked", false);
      $("#pascheduleid-" + cell.data()).prop("checked", isChecked);
      var row = table.row($(this).parent());
      if ((isChecked && !row.data().isEditing && row.data().imputedOn !== ""
       && $("#scheduleUsedTo").val() === "invoice")
       || (isChecked && !row.data().isEditing && row.data().imputedOn === ""
       && $("#scheduleUsedTo").val() === "account"))
      {
          $("#btn-UseSchedule").prop('disabled', false);
      }
      else
          $("#btn-UseSchedule").prop('disabled', true);
    }
  });
 

5.6. DataTable : Filtrage et total de colonne

Voici un exemple pratique du filtrage d'une DataTable sur deux colonnes, et avec un calcul du total :


  <head>
  <script language="Javascript"
  src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js"></script>
  <link rel="stylesheet" type="text/css"
  href="https://cdn.datatables.net/1.11.5/css/jquery.dataTables.min.css">
  </head>
  <BODY>
  <table id="tableChequesDiff" class="vdFTable">
    <thead class="vdFTableHeader">
      <tr role="row">
        <th>Date règlement</th>
        <th>Patient</th>
        <th>N° Dossier</th>
        <th>N° Chèque</th>
        <th>Type</th>
        <th>Montant</th>
        <th>Bordereau de remise associé</th>
        <th>Factures associées</th>
      </tr>
    </thead>
    <tbody class="vdFTableBody"></tbody>
  </table>
  <table id="tabletotaux" style="width:30%;margin-left:70%;" class="vdFTable">
    <thead class="vdFTableHeader">
        <tr>
            <th width="40%"></th>
            <th>Montant (€)</th>
            <th>Nombre</th>
        </tr>
    </thead>
    <tbody class="vdFTableBody">
        <tr>
            <td width="40%">Total</td>
            <td class="totalAmount"></td>
            <td class="totalNombre"></td>
        </tr>
    </tbody>
  </table>
  </BODY>
 

javascript :


  <script language="Javascript">
  Date.prototype.yyyymmdd = function() {
    var mm = this.getMonth() + 1; // getMonth() is zero-based
    var dd = this.getDate();
 
    return [this.getFullYear(),
            (mm>9 ? '' : '0') + mm,
            (dd>9 ? '' : '0') + dd
           ].join('');
  };
 

  $(document).ready(function ()
  {
    // Dans le cas ou la datatable est remplie directement en JSON avec Razor
    // @(Html.ToJsonObject<Models.ChequeDiff>(Model.ChequeDiffereList, "list"));
   
    // Test https://jseditor.io/
    var list = [{
        DateReglement: new Date("01/01/2020"),
        NomPrenomPatient: "TOTO",
        NumDossier: 1254,
        NumeroCheque: 2544,
        TypeCheque: "Chèque",
        Montant: 145.25,
        HasBordereauRemise: "Non",
        FacturesAssociees: "1,2"
    }];

    $('#tableChequesDiff').DataTable({
      dom: "tpi",
      data: list,
      scrollY: 500,
      scrollCollapse: true,
      columns: [
        {
            data: "DateReglement",
            render: function (val, type, row) {
                if (val != null) {
                    if (type === "display") {
                        return (val);
                    }
                    else
                        return (val.yyyymmdd());
                }
            },
            type: 'date'
        },
        { data: "NomPrenomPatient"},
        { data: "NumDossier"},
        { data: "NumeroCheque" },
        { data: 'TypeCheque' },
        {
            data: "Montant",
            render: function (val, type, row) {
                return val.toFixed(2);
            },
        },
        { data: "HasBordereauRemise" },
        {
          data: "FacturesAssociees",
          width: '180px',
          render: function (val, type, row) {
            if (val && val.length)
              return val.replace(/(\S*)\s\(([^\)]*)\)/g,
                function (g, invoice, amount) {
                  return '<span title="' + amount + '">' + invoice + '</span>';
              });
            return val;
          },
        }
      ],
 

      /*
      "footerCallback": function ( row, data, start, end, display ) {
        var api = this.api(), data;

        // Remove the formatting to get integer data for summation
        var intVal = function ( i ) {
            return typeof i === 'string' ?
                i.replace(/[\$,]/g, '')*1 :
                typeof i === 'number' ?
                i : 0;
        };

        // Total over all pages
        total = api
            .column( 5 )
            .data()
            .reduce( function (a, b) {
                return intVal(a) + intVal(b);
            }, 0 );

        $("#tabletotaux td.totalAmount").each(function () {
            $(this).html(total.toFixed(2));
        });

      },
      */

 

      // implémentation filtre sur la colonne type de chèque
      initComplete: function () {
        this.api().column(4).every(function () {
          var column = this;
          var select = $('<select id="typeChequeFilter">'
            + '<option value="ALL">Tous</option></select>')
            .appendTo($(column.header()))
            .click(function (e) {
              e.preventDefault();
              e.stopPropagation();
            })
            .on('change', function () {
              var typeChequeFilter = $('#typeChequeFilter').val();
              if (typeChequeFilter === 'ALL')
                  $("#tableChequesDiff").DataTable().column(4).search('')
                  .draw();
              else {
                  $("#tableChequesDiff").DataTable().column(4).search(
                    '^' + typeChequeFilter + '$', true).draw();
              }
              updateTotal();
            });

          $(['Chèque', 'Chèque différé']).each(function () {
            select.append('<option value="' + this + '">' + this + '</option>')
          });
        });

        // implémentation filtre sur la colonne bordereau de remise
        this.api().column(6).every(function () {
          var column = this;
          var select = $('<select id="chequeRemisFilter">'
            + '<option value="ALL">Tous</option></select>')
            .appendTo($(column.header()))
            .click(function (e) {
              e.preventDefault();
              e.stopPropagation();
            })
            .on('change', function () {
              var typeChequeRemisSelect = $('#chequeRemisFilter').val();
              var table = $("#tableChequesDiff").DataTable();
              if (typeChequeRemisSelect === 'ALL')
                table.column(6).search('').draw();
              else if (typeChequeRemisSelect === 'Non')
                table.column(6).search('Non').draw();
              else {
                table.column(6).search('Oui').draw();
              }
              updateTotal();
            });

          $(['Oui','Non']).each(function () {
              select.append('<option value="' + this + '">' +this + '</option>')
          });
        });
        $('#chequeRemisFilter').val('Non');
        $("#tableChequesDiff").DataTable().column(6).search('Non').draw();
      },
    });

    $('.modal-top input[type="search"]').addClass('vdInput vdSearch');
    $('.modal-top label').addClass('float-right');

    //On desactive les filtres des dates
    $("startDate").prop('disabled', true);
    $("endDate").prop('disabled', true);

    updateTotal();
  });
 
  function updateTotal() {
    var amount = 0.00;
    var dtChequesDifferes = $('#tableChequesDiff').DataTable().rows().data();
    var totalNombre = 0;
    for (var i = 0; i < dtChequesDifferes.length; i++) {
      var row = dtChequesDifferes[i];
      var typeChequeRemisSelect = $('#chequeRemisFilter').val();
      var typeChequeFilter = $('#typeChequeFilter').val();
      if (((typeChequeRemisSelect === 'ALL')
             || (row.HasBordereauRemise === typeChequeRemisSelect))
       && ((typeChequeFilter === 'ALL')
             || (row.TypeCheque === typeChequeFilter)))
      {
          totalNombre++;
          amount += parseFloat(row.Montant);
      }
    }
    $("#tabletotaux td.totalAmount").html(amount.toFixed(2));

    //totalNombre = $("#tableChequesDiff").DataTable().data().length;
    $("#tabletotaux td.totalNombre").html(totalNombre);
  }
  </script>
 

CHAPITRE 6 - Les pluggins

Flash

Flash etait un outil de programmation qui vous permet de créer une animation simple ou une application web complexe et interactive, telle qu'une boutique en ligne. Vous pouvez enrichir vos applications Flash en y ajoutant des images, du son et de la vidéo. Il est possible de faire des actions entre l'animation et javascript, tel que lancer une fonction envoyer des données.

La 3D

Le Langage VRML (Virtual Reality Modeling Language) permet de concevoir des simulations interactives en multiutilisateurs et en trois dimensions (cyberespace). Ce langage est né en 1994 et a été pensé par Mark D. Pesce, Peter Kennard et Anthony S.Parisi. Ce langage est devenu un standard incontournable sur le Web.

Il existe deux façons d'insérer un fichier VRML :

  • avec un lien hypertexte : Cliquez ici
  • avec la balise (remplacée par dans HTML 4.0) déjà utilisée pour insérer du son ou de la vidéo. Vous devez ici définir la hauteur (height) et la largeur (width) de la fenêtre qui va accueillir le monde ou l'objet VRML :

    Dans un soucis d'ouverture vers les nouvelles technologies, VRML a tenté d'évoluer vers un formalisme plus orienté « WEB 2.0?, et X3D est né, normalisé en 2005. Ce langage est clairement une reformulation de la syntaxe VRML, permettant de décrire la scène 3D sous forme XML, Binaire, ou encore VRML. Mais voilà, les soucis sont les mêmes, comment visualiser la scène dans son navigateur? Activex, plugins, encore et toujours… Le consortium Web3D finissant par se trouver dans une impasse, des acteurs comme Microsoft finissent par développer leurs propres solutions (typiquement, XAML intègre la description de scènes en 3D). Ainsi au jour d'aujourd'hui, bien trop de standards existent, (Shockwave, Java3D, etc…), et aucun n'a réussi à convaincre.

    … enfin HTML 5 intègre un standard prometteur : WebGL. Pour la première fois, un développeur sera capable d'intégrer de la 3D en se basant sur des spécifications pure HTML, en faisant confiance à l'implémentation des différents navigateurs qui se veut de plus en plus fidèle aux specs, concurrence oblige… Plus de plugin, la seule présence du navigateur implémentant les dernières spécifications HTML5 suffira à faire l'interface entre les pilotes OpenGL, et l'utilisateur, juste à travers des bibliothèques javascript. Pour moi cela ouvre vraiment de nouvelles perspectives sur le Web. Pourquoi pas des jeux en 3D plus aboutis, entièrement en cloud, basés sur le navigateur ? Pourquoi pas des sites internet avec une navigation repensée ? Une vraie 3D dans google map, ou un magasin Amazon dans lequel on pourrait se promener ? Et si le web 3.0 était un web en 3D ?

    A l'heure actuelle, pour pouvoir tester les quelques démonstrations WebGL qui existent, Chrome 9, IE9, ou Firefox 4 sont nécessaires. Si vous avez l'un de ces 3 navigateurs, je vous invite à aller sur ce site (google inside, encore…)

    Adobe Edge est un EDI qui permettra de créer des applications web en HTML5, CSS3 et Javascript

    119 millisecondes