Premiers pas en JavaScript
39.1 Graphisme
cuy copyleft
  See You Why?  

 


Test relatif à la validation de formulaire (38.9) | | Librairies et autres ressources pour le graphisme (39.2)

Contenu

 

 

I. Graphisme et JavaScript

Les pages traitant du graphisme sont nombreuses sur le Web : malheureusement, elles n'ont souvent d'intérêt que si elles s'accompagnent de routines déjà écrites et souvent payantes. Nous essaierons ici de trouver les principales fonctions qui permettent les animations graphiques essentiellement sans l'aide de ces bibliothèques de fonctions, puis en en faisant usage.

Une des premières difficultés est que Internet Explorer joue toujours à part (il refuse d'adopter JavaScript et travaille avec son JScript) et que sans cesse, les instructions à donner dépendront du navigateur auquel ces instructions s'adressent. Nous n'irons peut-être pas jusqu'à rebaptiser IE de BB ou badbrowser comme le font certains, mais nous pensons que ces derniers n'ont pas fait un mauvais choix. Nous développerons les aspects suivants du graphisme :

  1. reconnaitre le browser (navigateur, babillard, etc.) utilisé par le visiteur de nos pages ;
  2. reconnaitre la position de la souris sur l'écran ;
  3. déplacer un dessin sur l'écran ;
  4. v ;

Avant de poursuivre, vérifions rapidement ce que nous répond l'appel des propriétés de l'objet navigator appelé sur votre ordinateur :


navigator.vendorSub =
navigator.productSub = 20030107
navigator.vendor = Google Inc.
navigator.maxTouchPoints = 0
navigator.scheduling = [object Scheduling]
navigator.userActivation = [object UserActivation]
navigator.doNotTrack = null
navigator.geolocation = [object Geolocation]
navigator.connection = [object NetworkInformation]
navigator.plugins = [object PluginArray]
navigator.mimeTypes = [object MimeTypeArray]
navigator.pdfViewerEnabled = false
navigator.webkitTemporaryStorage = [object DeprecatedStorageQuota]
navigator.webkitPersistentStorage = [object DeprecatedStorageQuota]
navigator.windowControlsOverlay = [object WindowControlsOverlay]
navigator.hardwareConcurrency = 64
navigator.cookieEnabled = true
navigator.appCodeName = Mozilla
navigator.appName = Netscape
navigator.appVersion = 5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)
navigator.platform = Linux x86_64
navigator.product = Gecko
navigator.userAgent = Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)
navigator.language = en-US
navigator.languages = en-US
navigator.onLine = true
navigator.webdriver = true
navigator.getGamepads = function getGamepads() { [native code] }
navigator.javaEnabled = function javaEnabled() { [native code] }
navigator.sendBeacon = function sendBeacon() { [native code] }
navigator.vibrate = function vibrate() { [native code] }
navigator.deprecatedRunAdAuctionEnforcesKAnonymity = false
navigator.protectedAudience = [object ProtectedAudience]
navigator.storageBuckets = [object StorageBucketManager]
navigator.clipboard = [object Clipboard]
navigator.credentials = [object CredentialsContainer]
navigator.keyboard = [object Keyboard]
navigator.managed = [object NavigatorManagedData]
navigator.mediaDevices = [object MediaDevices]
navigator.storage = [object StorageManager]
navigator.serviceWorker = [object ServiceWorkerContainer]
navigator.virtualKeyboard = [object VirtualKeyboard]
navigator.wakeLock = [object WakeLock]
navigator.deviceMemory = 8
navigator.userAgentData = [object NavigatorUAData]
navigator.login = [object NavigatorLogin]
navigator.ink = [object Ink]
navigator.mediaCapabilities = [object MediaCapabilities]
navigator.hid = [object HID]
navigator.locks = [object LockManager]
navigator.gpu = [object GPU]
navigator.mediaSession = [object MediaSession]
navigator.permissions = [object Permissions]
navigator.presentation = [object Presentation]
navigator.usb = [object USB]
navigator.xr = [object XRSystem]
navigator.serial = [object Serial]
navigator.adAuctionComponents = function adAuctionComponents() { [native code] }
navigator.runAdAuction = function runAdAuction() { [native code] }
navigator.canLoadAdAuctionFencedFrame = function canLoadAdAuctionFencedFrame() { [native code] }
navigator.clearAppBadge = function clearAppBadge() { [native code] }
navigator.getBattery = function getBattery() { [native code] }
navigator.getUserMedia = function getUserMedia() { [native code] }
navigator.requestMIDIAccess = function requestMIDIAccess() { [native code] }
navigator.requestMediaKeySystemAccess = function requestMediaKeySystemAccess() { [native code] }
navigator.setAppBadge = function setAppBadge() { [native code] }
navigator.webkitGetUserMedia = function webkitGetUserMedia() { [native code] }
navigator.clearOriginJoinedAdInterestGroups = function clearOriginJoinedAdInterestGroups() { [native code] }
navigator.createAuctionNonce = function createAuctionNonce() { [native code] }
navigator.joinAdInterestGroup = function joinAdInterestGroup() { [native code] }
navigator.leaveAdInterestGroup = function leaveAdInterestGroup() { [native code] }
navigator.updateAdInterestGroups = function updateAdInterestGroups() { [native code] }
navigator.deprecatedReplaceInURN = function deprecatedReplaceInURN() { [native code] }
navigator.deprecatedURNToURL = function deprecatedURNToURL() { [native code] }
navigator.getInstalledRelatedApps = function getInstalledRelatedApps() { [native code] }
navigator.registerProtocolHandler = function registerProtocolHandler() { [native code] }
navigator.unregisterProtocolHandler = function unregisterProtocolHandler() { [native code] }

Ce qui a été affiché par la source suivante, une simple boucle du type 'for... in...' :

<script type="text/javascript">
for (propr in navigator) {
    document.write('<br /><b>navigator.' + propr + '</b> = ' + navigator[propr]);
}
</script>

Le lecteur attentif aura remarqué que la meilleure façon de tester l'OS et le navigateur n'est pas de faire appel aux propriétés de l'objet navigator. Il n'est en effet pas rare qu'un navigateur se cache derrière d'autres noms pour pouvoir exécuter des scripts qui n'ont pas été écrits pour eux. Chez moi, alors que j'utilise essentiellement Google Chrome, je vois aussi apparaitre des mots tels que Gecko, Mozilla, Safari, Netscape dans le descriptif des propriétés de mon navigator affiché ci-dessus... de quoi dérouter la recherche de mon navigateur réel.

La traditionnelle lecture de la propriété userAgent ne convient plus pour détecter quel navigateur ou browser le visiteur de votre page utilise.

 

A. quel navigateur ?

Il existe différents moyens de reconnaitre le navigateur (Internet Explorer, Google Chrome, Mozilla Firefox, Netscape, Opera, Safari ou autre) qu'utilise le visiteur de votre page.

Quel Micro§oft Internet Explorer ?

Nous vous proposons en premier lieu un procédé qui ne permet que de détecter IE et sa version,
d'après http://msdn.microsoft.com/en-us/library/cc817582.aspx.

function getInternetExplorerVersion() {
// Renvoie la version de Windows Internet Explorer ou la valeur -1
// (qui signifie que vous utilisez un autre navigateur).
   var rv = -1;                    // Renvoie la valeur si rien d'autre n'est valable
   if (navigator.appName == 'Microsoft Internet Explorer') {
      var ua = navigator.userAgent;
      var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
      if (re.exec(ua) != null) {
         rv = parseFloat( RegExp.$1 );
      }
   }
   return rv;
}

function checkIEVersion() {
   var msg = "Vous n'employez pas Windows Internet Explorer. Bravo !";
   var ver = getInternetExplorerVersion();
   if ( ver> -1 ) {
      if ( ver>= 8.0 ) {
         msg = "Vous utilisez une version récente 8.0 ou mieux d'Internet Explorer.";
      } else if ( ver == 7.0 ) {
         msg = "Vous utilisez Windows Internet Explorer 7.";
      } else if ( ver == 6.0 ) {
         msg = "Vous employez encore Windows Internet Explorer 6. Songez à mettre à jour";
      } else {
         msg = "Il faut mettre à jour votre vieille version d'Internet Explorer";
      }
   }
   alert( msg );
}

C'est la fonction checkIEVersion() qu'il faut appeler, cette dernière appelle getInternetExplorerVersion() pour retrouver la valeur de la variable ver. Chez vous, l'appel de cette méthode affichera :

 

Quel navigateur ? méthode longue

On pourrait aussi utiliser une fonction, parfois appelée classe, mais plus correctement 'objet' de type 'prototype' en JS, qui extrairait de toutes les propriétés du navigator, celles qui selon les cas seraient utiles. Cette fonction que nous avons appelée DetecteLeNavigateur est bien basée sur la construction des prototypes en JS: nous en donnerons plus de détails sous peu.
Pour ceux qui veulent comprendre avant notre explication, nous nous sommes inspirés de la lecture de https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Details_of_the_Object_Model, qui distingue la construction de type 'classe' en Java de celle de type 'prototype' en JavaScript.

Quant à l'utilisation de cet objet 'prototype' de JS, il faut :

      1. appeler la page d'extension .js qui contient la construction de cette classe ;
        <script type="text/javascript" src="scripts/detectenavigateur.js"></script>
      2. initialiser cette classe ;
        DetecteLeNavigateur.init();
      3. relever les informations utiles et les stocker dans des variables ;
        var nv_navig = DetecteLeNavigateur.browser;
        var nv_vers = DetecteLeNavigateur.version;
        var nv_os = DetecteLeNavigateur.OS;
      4. afficher ou utiliser les éléments relevés.
        Chez vous, on a écrit :
        <button onclick="alert(nv_navig+' * '+nv_vers+' * '+nv_os)">Lancer l'affichage</button>

Ce qui, sur l'ordi du visiteur de votre page donnera :

Quelle fonction marche sur cet ordi ?

Cependant, compte tenu que les navigateurs évoluent, adoptent parfois ce qu'ils refusaient dans une version précédente et vice-versa, c'est une des bonnes pratiques que de ne pas tester le navigateur, mais de préférer tester l'existence de la méthode... si la méthode n'offre pas assez de sécurité quant à son existence.

Ainsi, en écrivant  :
if (history.pushState) {
   // faire ce que l'on veut avec history.pushState
} else {
   // soit le dire autrement,
   // soit envoyer un petit message pour dire qu'on est désolé
}

on ne teste pas si on travaille avec certaines versions d'IE, certaines de FF ou sous Opera... on teste si le navigateur connait l'objet history et sa méthode pushState. Les programmeurs en JS n'emploient pas assez souvent cette option.

Quel navigateur par le test d'une fonction ? méthode courte

Nous l'avons déjà signalé, IE a des fonctions qui lui sont propres et que les autres navigateurs emploient via des autres fonctions quasi équivalents. document.all est une de ces fonctions de IE qui permettent de distinguer IE des autres qui généralement utilisent la fonction document.getElementById('un_id') et, comme d'une part, il n'est pas indispensable de donner un argument pour voir si une méthode fonctionne et que d'autre part IE a finalement, dans ses dernières versions, adopter le DOM (Document Object Model), on devra vérifier que les autres répondent au critère document.getElementById sans accepter le document.all. C'est pourquoi nous emploierons généralement le test suivant pour détecter si nous sommes face au navigateur de Micro§oft ou un autre :

var ie = document.all;
var gb = document.getElementById && !document.all;

Dans la suite de la programmation, si chaque navigateur a besoin de ses propres fonctions ou instructions, on utilisera le test :
if (gb) {
    var fobj= e.target;
} else {
    var fobj= event.srcElement;
}

ou, plus court encore, la condition ternaire :
var fobj = gb ? e.target : event.srcElement;

Quel est l'objet ou élément HTML a été ciblé par un évènement ? IE fait appel à sa propriété srcElement de l'objet event, alors que le DOM recommande la propriété target de l'objet passé en paramètre (e) à la fonction en cours... ce qui explique cette ou ces lignes de code...

De même, on lira :
var topelement = gb ? "HTML" : "BODY";
while (fobj.tagName != topelement && fobj.className != "glissemoi") {
    fobj = gb ? fobj.parentNode : fobj.parentElement;
}

car, en DOM, la propriété tagName renvoie le nom de l'élément courant, souvent spécifié par un id="monNom" dans une balise <span>, <form> ou autre ;
comme JS a une organisation hiérarchique des objets, la propriété parentNode renvoie en DOM et en JS l'objet parent, mais était inconnue de IE6, la propriété parentElement renvoie en JScript l'objet parent; ceci aurait pu être corrigé facilement par un nouveau prototype :
Element.prototype.parentElement = Element.prototype.parentNode;

HTML
HEAD
TITLE LINK SCRIPT
BODY id ="mon_body"
H1
id ="mon_h1"
UL id ="mon_ul"
LI id ="mon_li"
UL
LI LI
LI
DIV
id ="mon_div"
P id ="mon_p"
EM
INPUT
id ="mon_input"

La collection document.mon_body.children ne contient que 4 éléments :

Elle ne contient pas "mon_li".
Par contre document.mon_ul.parentNode désigne document.mon_body, son parent.
Dans IE le simple fait d'avoir un tag (ou balise) avec un id l'utilisation du nom de l'id comme variable référence implicitement le tag portant l'id ;

Pendant de nombreuses versions, la surface totale accessible et visible sur l'écran (donc l'objet le plus haut dans la hiérarchie) était l'objet body pour IE mais html pour les autres ;

 

B. reconnaitre la position de la souris sur l'écran

On ne fait pas de graphisme sans au moins pouvoir détecter la position du curseur (de la souris). JS a prévu plusieurs moyens pour repérer la position de la souris sur l'écran. Les deux propriétés que nous utiliserons sont clientX qui renvoie l'abscisse (distance du bord gauche) et clientY qui renvoie l'ordonnée (distance du bord supérieure) de la pointe de la souris. Rappelons d'abord qu'en HTML et en JS, l'origine des axes se trouve dans le coin supérieur gauche, ce point a comme abscisse 0 et comme ordonnée 0, ce qui se note (0,0).

Si vous longez le bord supérieur en allant vers la droite,
l'ordonnée de votre souris (sa distance p/r au bord supérieur) reste quasi nulle,
mais son abscisse (sa distance p/r au bord gauche) va en augmentant.
Horizontalement, l'abscisse maximale (bord droit) dépendra de la définition de votre écran (de 640 ou 800 sur des écrans avec une faible définition à près de 2000 sur des écrans plus précis).
Par contre,
si vous partez du coin supérieur gauche et longez le bord gauche en descendant,
l'abscisse (distance du bord gauche) reste quasi nulle,
mais son ordonnée (distance p/r au bord supérieur) augmente jusqu'à 480 ou 600 sur des écrans avec une faible définition à près de 1200 sur des écrans plus précis.
Et oui, on augmente en descendant alors que les matheux s'enfoncent dans les valeurs négatives en descendant.

Javascript est un langage événementiel. Les évènements relatifs à la souris seront détectés par :
- onMouseMove :
     lorsque l'utilisateur bouge la souris
     indépendamment du fait que la touche en soit appuyée ou non ;
- onMouseClick :
     lorsque l'utilisateur clique ;

Et, lorsqu'on se risquera à faire glisser un objet, il faudra aussi distinguer :
- onMouseDown :
     lorsque l'utilisateur maintient la touche de souris appuyée ;
- onMouseUp :
     lorsque l'utilisateur, après avoir appuyé la touche de souris, la relâche.

Ces évènements peuvent n'être détectés que sur certains objets. Ainsi, dans l'exemple ci-dessous, le onclick n'est applicable que si le curseur de la souris est sur la zone rouge, alors que le mouvement de la souris onMouseMove est détectable sur toute la page.

Exemple

<html>
<head>
   <title>Evenement position souris</title>
   <script type="text/javascript">
      function handleEvent(oEvt) {
         var oTextbox = document.getElementById("txta");
         oTextbox.value += "\n sur (" + oEvt.clientX + "," + oEvt.clientY + "), OK pour la cible";
      }
   </script>
</head>
<body>
   <h2>CUY position souris</h2>
   <script type="text/javascript">
      document.body.onmousemove = function (e) {
         souris = document.getElementById("souris");
         souris.innerHTML= "Coordonnées souris : <br>X= "+e.clientX+" ; Y= "+e.clientY+" .";
      }
   </script>
   <table align="center"><tr align="center">
      <td>
         <textarea id="txta" rows="23" cols="35"></textarea>
      </td>
      <td>
         Déplacez votre souris <br>
         et lisez la ligne surlignée en jaune.<br>
         Avec votre souris, <br>
         cliquez et double-cliquez<br>
         sur le carré rouge de 200px x 200px,<br>
         particulièrement les coins.<br>
         Essayez aussi en dehors du carré.
         <div style="width: 200px; height: 200px; background-color: red"
            onclick="handleEvent(event)" id="zone_rouge"></div>
         <div id="souris" style="background-color: yellow">Coordonnées souris :<br>&nbsp; </div>
      </td>
   </tr></table>
</body>
</html>

 

 

C. déplacer un dessin sur l'écran (drag and drop)

Si vous avez compris toutes les nuances des deux scripts qui relèvent la position de pointeur de la souris, nous n'avons plus grand chose à vous expliquer pour que vous puissiez déplacer un dessin ou une image, voire même un objet sur votre écran. Quelles sont les informations qui vous manquent ? Commençons par observer la source :

Exemple

<html>
<head>
   <title>
      CUY Javascript (Glisse et laisse tomber image)
   </title>
<style type="text/css">
   .glissemoi{position:relative;}
</style>

<script type="text/javascript">
   <!-- d'après http://www.lecodejava.com/javaadraganddrop.html -->

   var ie=document.all;
   var nn6=document.getElementById&&!document.all;
   var estenglisse=false;
   var x,y;
   var dobj;

   function bougesouris(e) {
      if (estenglisse) {
         dobj.style.left = nn6 ? tx + e.clientX - x : tx + event.clientX - x;
         dobj.style.top = nn6 ? ty + e.clientY - y : ty + event.clientY - y;
         return false;
      }
   }

   function choixsouris(e) {
      var fobj = nn6 ? e.target : event.srcElement;
      var topelement = nn6 ? "HTML" : "BODY";
      while (fobj.tagName != topelement && fobj.className != "glissemoi") {
         fobj = nn6 ? fobj.parentNode : fobj.parentElement;
      }
      if (fobj.className=="glissemoi") {
         estenglisse = true;
         dobj = fobj;
         tx = parseInt(dobj.style.left+0);
         ty = parseInt(dobj.style.top+0);
         x = nn6 ? e.clientX : event.clientX;
         y = nn6 ? e.clientY : event.clientY;
         document.onmousemove=bougesouris;
         return false;
      }
   }

   document.onmousedown=choixsouris;
   document.onmouseup=new Function("estenglisse=false");

</script>
</head>
<body>
   <p>Faire un drag-and-drop (glisser-déposer) de l'image</p>
   <div align="center">
      <img src="../images/logocuy1mini4.gif" width="60" height="40" class="glissemoi">
   </div>
</body>
</html>

      1. Que contient le <body> ?

        Uniquement l'image choisie que l'on voudra déplacer... et à déclarer dans un style "glissemoi" qui permettra de faire partie des objets "glissables" ;
        mais à placer dans une balise <div> sans devoir l'identifier.
         
      2. Que fait la propriété style.left (et style.top) appliquée à un objet ?
         
        La propriété style.left (en mode lecture) relève l'abscisse (distance p/r au bord gauche) de l'objet auquel elle s'applique ; cette méthode peut être utilisée en mode écriture et dans ce cas déplace l'objet jusqu'à ce qu'il ait l'abscisse souhaitée ;
        idem pour style.top qui relève ou impose l'ordonnée de cet objet.
         
        Malheureusement, ces propriétés renvoient une valeur suivie de son unité en pixels, comme, par exemple '60px'. Puisqu'il s'agit d'une chaine de caractères, rien n'empêche de remplacer 'px' par '' et le tour est joué... malheureusement, le '60' qui resterait serait toujours une chaine. Dans notre page jvs_504_emprunt_bancaire_4.html nous comparons 4 fonctions qui peuvent s'appliquer à une chaine pour en extraire une valeur numérique entière. La fonction parseInt(chaine) semble donner le résultat convoité.
         
      3. Pourquoi trouve-t-on les 3 détecteurs relatifs aux évènements de la souris ?

        Un 'glisser-jeter', en anglais 'drag-and-drop' se fait en 3 temps :
        - enfoncer le bouton de souris sur l'objet choisi : onMouseDown,
        - glisser sans relâcher le bouton de la souris : onMouseMove,
        - relâcher le bouton de souris quand l'objet est arrivé à destination : onMouseMove.
         
      4. À quoi sert cette variable "estenglisse" ?
         
        Il s'agit d'une variable logique. Elle détecte si l'objet choisi est en cours de glissage ou pas. En d'autres mots, elle est 'fausse' par défaut, devient 'vraie' dès que l'on enfonce le bouton de la souris et redevient fausse dès que l'on relève le bouton de souris.
         
      5. P

       

       

       

      D. Le "drag and drop" en HTML5

      Le HTML5 nous apporte bien des avantages par rapport à sa version précédente. C'est bien la procédure suivie lorsque vous «attrapez» un objet et le faites glisser vers un autre emplacement.

      Étape 1 : rendre l'objet déplaçable

      HTML5 permet de rendre tout objet 'glissable' ou 'draggable'. Il suffit pour cela de lui attribuer l'attribut "draggable="true". Le lecteur excusera mon vocabulaire concernant la dragabilité de mes expressions.

      Étape 2 : préciser dans 'ondragstart' quelle fonction sera appelée

      Ensuite, on précisera ce qui devrait se passer si l'élément est glissé. Ici, dans notre exemple, on précise dans notre argument ondragstart, à quelle fonction on fera appel, ici glisse avec comme attribut evenement que nous définirons plus loin en spécifiant quelle donnée doit être transportée.

       

      Il existe de nombreuses librairies extérieures qui peuvent vous aider au niveau du graphisme. Vous trouverez par exemple un autre "drag and drop", réalisé avec l'aide de la librairie RGraph ici. La séquence suivante vous renseignera sur quelques librairies utiles pour le graphisme ; les exemples sont donnés à titre informatif et n'ont pas la prétention d'être une liste exhaustive.

 

II. Librairies extérieures pour le graphisme JS

voir suite >>>

 

III. HTML5 et <canvas> pour le graphisme JS

voir suite >>>

 

IV. Propriétés et méthodes pour <canvas> et le graphisme JS

voir suite >>>

 

 

VIII. Exercices relatifs au graphisme

voir suite >>>

 

 

IX. Test relatif au graphisme

voir suite >>>

 

 


Test relatif à la validation de formulaire (38.9) | | Librairies et autres ressources pour le graphisme (39.2)

 

 

Merci de votre visite à partir de :

Vous êtes sur :
https://cuy.be/cours/jvs/jvs_390_graphisme_objet.html

partager sur FaceBook...           consulter sur FaceBook...

 

copyleft
Des liens ne fonctionnent plus ?
Avez-vous des suggestions ?
des commentaires, des corrections, un encouragement... ?
Pour info : Non, il n'y a pas de version papier ou DOC, PDF, etc. de ces notes.


Envoyez-moi un E-Mail (cuy(point)w(at)skynet(point)be)

Attention (at) signifie @ et (point) signifie .

Accueil CUY = See you why?

Compteur gratuitEasyCounter     BelStat Monitored by BelStat - Your Site Counts
La 1 000 000e page a été visitée le 21 mai 2010.
La 2 000 000e page a été visitée ce 18 mars 2012, vers midi.
La 3 000 000e page a été visitée ce 7 janvier 2014 entre 18 h et 18 h 45,
La 4 000 000e page a été visitée ce 5 juin 2015 entre 15 h 49 et 15 h 52,
La 5 000 000e page a été visitée ce 29 aout 2017 après 23 h 30,
Et la 6 000 000e page visitée, trop tôt pour y penser ?
 
et, d'après BelStat, CUY est visité surtout en semaine, peu le weekend...
moins et irrégulièrement pendant les vacances :

visites sur 3 mois, de la mi octobre 2013 à la mi janvier 2014.
 
La 3 333 333e page visitée a eu lieu ce mardi 10 juin 2014, en début d'après midi...
La 3 666 666e page visitée a eu lieu ce dimanche 28 decembre 2014, vers 16 h...
Un tiers de million de pages visitées en 154 jours cela fait une moyenne de 2165 pages visitées par jour...
Deux tiers de million de pages visitées en 355 jours soit une moyenne de 1878 pages visitées par jour...
et seulement 1195 pages visitées quotidiennement pendant les vacances estivales
de la mi juin à la mi septembre 2014

Vous voulez lire quelques messages reçus ?
quelques encouragements ?
Cliquez ici


Fin septembre 2009, installation de ce compteur
qui ne compte chaque nouvel ordinateur visiteur qu'une seule fois
free counter
 
m-à-j du 22/11/2021 :

Depuis cette fin septembre 2009, parmi les 210 pays (sur 274 drapeaux connus) qui nous ont visité,
voici les 100 pays qui nous visitent le plus, 
Nos petits visiteurs, classés par date de visite, où un seul ordi nous a visité, sont :
199. Turkmenistan (TM May 10, 2017) ; 200. Lesotho (LS March 1, 2017) ;
201. Turks and Caicos Island (TC January 18, 2016
202. Cook Islands (CK September 19, 2015)  203. Faroe Islands (FO January 27, 2015
204. Virgin Islands American (VI November 12, 2014) ;
205. Belize (BZ September 29, 2014) ;206. Eswatini - Swaziland (SZ July 21, 2014) ;
207. Grenada (GD April 3, 2014) ; 208. Timor-Leste (TI March 29, 2014) ;
209. American Samoa (AS December 26, 2012) ; 210. Guyana (GY November 5, 2010).