Pages

Les fonctions de base

JS Bin

les fonctions de base

'#'+'0123456789abcdef'.split('').map(function(v,i,a){ return i>5 ? null : a[Math.floor(Math.random()*16)] }).join('');

Est ce un code secret ?

Pour le comprendre : Décomposons le code en étape

  1. const values = '0123456789abcdef';
  2. const tab = values.split('');
  3. let random = tab.map((v,i,a) => i>5 ? null : a[Math.floor(Math.random()*16)]);
  4. let colorRandom = '#'+random.join("");
Lig. 3 transforme les 6 premiers éléments du tableaux en des nombres <16.

En action

Il vous suffit ensuite de copiez la valeur de colorRandom et de tapez dans votre console
  1. document.body.style.background = "#848250"


Start game !

JS Bin

https://github.com/dupontdenis/Game-useGlobal.git

Flex : A la loupe

Cas d'augmentation-

p:nth-of-type(2n+1) {//bleu
  flex : 1 1 25%; 
}

p:nth-of-type(2n) {//rouge
  flex : 1 1 50%; 
}

voir -> fichier test

Dans ce cas, la somme des pourcentage est inférieur à 100% (la taille du conteneur), il y a augmentation ; les chiffres rouges sont pris en compte.

Chaque bloc va augmenter proportionnellement de la même valeur.

Ainsi, si le body fait 1000 px, nous aurions eu le bloc bleu (25%) à 250 px et le bloc rouge (50%) à 500 px. Il y a une augmentation de 1000 - ( 250 + 500) = 250 px à répartir.

Cette augmentation de 250 px va se répartir sur 1/1+1 pour le bloc bleu et 1/1+1 pour le bloc rouge.

Nous pouvons appliquer la formule :

nouvelle taille = taille + ( augmentation * proportion)

Ainsi, pour le bloc bleu

nouvelle taille = 250 + ( 250  *1/2 ) = 375

Et, pour le bloc rouge

nouvelle taille = 500 + ( 250  *1/2 ) = 625




Autre cas 


p:nth-of-type(2n+1) {//bleu
  flex : 4 1 25%; 
}

p:nth-of-type(2n) {//rouge
  flex : 1 1 50%; 
}

Dans ce cas encore, la somme des pourcentages est inférieur à 100% (la taille du conteneur), il y a un étirement ; les chiffres rouges sont pris en compte.

Chaque bloc va augmenter proportionnellement de la même valeur.

Ainsi, si le body fait 1000 px, nous aurions eu le bloc bleu (25%) à 250 px et le bloc rouge (50%) à 500 px. Il y a une augmentation de 1000 - ( 250 + 500) = 250 px à répartir.

Cette augmentation de 250 px va se répartir sur 4/1+4 pour le bloc bleu et 1/1+4  pour le bloc rouge.

Nous pouvons appliquer la formule :

nouvelle taille = taille + ( augmentation * proportion)

Ainsi, pour le bloc bleu

nouvelle taille = 250 + ( 250  *4/5 ) = 450

Et, pour le bloc rouge

nouvelle taille = 500 + ( 250  *1/5) = 550



Fichier de test

Flex : A la loupe

Reprenons l'écriture avec des pourcentages

body {
  display : flex;
  flex-flow: row nowrap;
}

p:nth-of-type(2n+1) {//blue
  flex : 1 4 100%; 
}

p:nth-of-type(2n) {//red
  flex : 1 1 50%; 
}

Nous allons tenter de comprendre la situation.

fichier

Notons tout d'abord que la propriété nowrap impose que les blocs soient sur une ligne.

body {
  ...
  flex-flow: row nowrap;
}

Notons ensuite que le bloc blue fait 100% et que le bloc Rouge 50%, nous allons donc devoir les réduire.

Réécrivons notre code pour avoir un cas plus simple.

p:nth-of-type(2n+1) {//blue
  flex : 1 1 100%; 
}

p:nth-of-type(2n) {//red
  flex : 1 1 50%; 
}

Comme il y a réduction, nous nous intéressons aux valeurs rouge, Chaque bloc va se réduire proportionnellement de la même valeur.

Ramenons les pourcentages à des proportions :

100% -> 2
50%   -> 1

Le bloc bleu va donc compter pour 2 sur un total de 3
Le bloc rouge va compter pour 1 sur un total de 3

Ainsi, si le body fait 1000px, nous aurions eu le bloc bleu (100%) à 1000px et le bloc rouge (50%) à 500px. Il y a une réduction de 1000-(1000+500) = 500px.

Cette réduction de 500px va se répartir sur 2/3 pour le bloc bleu et 1/3 pour le bloc rouge.

Nous pouvons appliquer la formule :

nouvelle taille = taille - ( réduction * proportion)

Ainsi, pour le bloc bleu

nouvelle taille = 1000 - ( 500  *2/3 ) = 666

Et, pour le bloc rouge

nouvelle taille = 500 - ( 500  *1/3 ) = 333

Donner une taille au body de 1000px et vérifié le résultat.

←Fichier→



Cas suivant

Modifions le cas précédent en changeant la valeur de réduction du bloc bleu.

p:nth-of-type(2n+1) {//blue
  flex : 1 2 100%; 
}

p:nth-of-type(2n) {//red
  flex : 1 1 50%; 
}

Comme il y a réduction, nous nous intéressons aux valeurs rouge, Chaque bloc va se réduire non plus proportionnellement mais le bloc bleue va se réduire de fois plus de la même valeur.

Ramenons les pourcentages à des proportions :

100% -> 2
50%   -> 1

En prenant en compte le facteur de réduction.

Le bloc bleu va donc compter pour 2*2 sur un total de (2*2+1)
Le bloc rouge va compter pour 1 sur un total de (2*2+1)

Ainsi, si le body fait 1000px, nous aurions eu le bloc bleu (100%) à 1000px et le bloc rouge (50%) à 500px. Il y a une réduction de 1000-(1000+500) = 500px.

Cette réduction de 500px va se répartir sur 4/5 pour le bloc bleu et 1/5 pour le bloc rouge.

Nous pouvons appliquer la formule :

nouvelle taille = taille - ( réduction * proportion)

Ainsi, pour le bloc bleu :

nouvelle taille = 1000 - ( 500  * 4/5 ) = 600

Et, pour le bloc rouge :

nouvelle taille = 500 - ( 500  * 1/5 ) = 400


→fichier←

Finalement pour les valeurs
p:nth-of-type(2n+1) {
  flex : 1 4 100%;
}

p:nth-of-type(2n) {
  flex : 1 1 50%;
}

Les proportions seraient de 4*2/4*2+1 et de 1/9. Vérifiez avec le premier fichier test.

Flex : à la loupe

Nous allons étudier en détail le comportement FLEXIBLE des blocs en fonction de la taille de leur conteneur.

Prenons le cas de deux paragraphes contenus dans un bloc (le body).

Et donnons à chaque paragraphe les valeurs de flexibilité suivantes :

body {
  display : flex;
  flex-flow: row nowrap; //nowrap = une ligne !
}
p:nth-of-type(2n+1) { //bleu
  flex : 5 5 400px;
}

p:nth-of-type(2n) { //rouge
  flex : 1 1 400px;
}

Le fichier de test ( lien sur le fichier ) permet de faire varier la taille du conteneur pour observer la flexibilité des blocs.


Nous allons examiner trois cas :
  1. La place totale du conteneur est  <  à la somme de la taille de chaque bloc.
  2. La place totale du conteneur est  >  à la somme de la taille de chaque bloc.
  3. Egalité entre le contenu et le contenant

Cas 1 : Conteneur plus petit que le contenu !

Prenons par exemple un conteneur (body) de taille 400px.

Nous sommes dans le cas 1, où la taille du body ne permet pas de placer les deux blocs avec leur taille initiale de 400px.

Il faut donc réduire  la taille de chaque bloc.

Valeur de réduction : -400px(taille P1)-400px(taille P2)+400px(taille body) =  -400px.

Nous devons réduire les blocs(Pi) de 400px au total.

Les 400px(de chaque bloc) doivent être réduits mais proportionnellement.

Nous prenons le second coefficient de la propriété flex qui indique la valeur de réduction.

p:nth-of-type(2n+1) { //bleu
  flex : 5 5 400px;
}

p:nth-of-type(2n) { //rouge
  flex : 1 1 400px;
}

Le bloc bleu va se réduire de 5/(5+1) * réduction = 5/6 * 400 = 333.
Sa taille sera donc de 400-333 = 66.

Le bloc rouge va se réduire de 1/(1+5) * réduction = 1/6 * 400 = 66.
Sa taille sera de 400-66=334.

En action : 
a l'aide du fichier test, modifier la taille du body à 400px, et vérifier que les valeurs calculées correspondent à la simulation.

Cas 2 : Conteneur plus grand que le contenu !

Prenons par exemple un body de taille 1000px.

Nous sommes dans le cas 2, où la taille du body permet de placer les deux blocs avec leur taille initiale de 400px et de les agrandir.

Valeur de l'augmentation : -400px(taille B1)-400px(taille B2)+1000px(taille body) =  +200px.

Il faut donc les augmenter de 200px, mais proportionnellement aux valeurs indiquées par la première valeur de la propriété de flex.

p:nth-of-type(2n+1) { //bleu
  flex : 5 5 400px;
}
p:nth-of-type(2n) { //rouge
  flex : 1 1 400px;
}

Le bloc bleu va augmenter de 5/(1+5) * augmentation = 5/6*200 = 166
Sa taille sera donc de 400 + 166 = 566.

Le bloc rouge va augmenter de 1/(1+5) * augmentation = 1/6*200 = 33
Sa taille sera donc de 400 + 33 = 433.





Cas 3 : body = 800px


Remarque

si les valeurs de flex sont :

p:nth-of-type(2n+1) { //bleu
  flex : 5 5;
}
p:nth-of-type(2n) { //rouge
  flex : 1 1;
}

Nous aurons simplement à répartir 800px (la taille du body) en 5/5+1 *800px pour le bloc1 et 1/5+1 *800px pour le bloc 2.





Flex : en action

JS Bin

Sublime Text (suite)

           Sublime Text est un éditeur de texte générique (et non un IDE) développé par Jon Skinner, en C++ et Python. Il est aujourd'hui un des éditeurs les plus utilisés avec notamment Notepad++.

Le logiciel est payant (mais utilisable en version "Unregistered"), il prend en charge 44 langages de programmation majeurs (ex: html/css/javascript/php/...).


Sublime Text est très personnalisable, il vous est par exemple possible d'adapter l'interface de votre programme jusqu'à changer la couleur de la balise de votre code. 

Afin de rendre votre programmation la plus ergonomique possible, vous pouvez utiliser des raccourcis très pratiques !

Voici quelques exemples :



  • Aller directement à un symbole (ex:#) : Windows : Control + R  |  Mac : ⌘ + R
    • Splitter l'éditeur en deux parties : Windows : Alt + Maj + 2  |  Mac : ⌘ + ⌥ + 2
          


    Sublime Text possède un package manager (comprendre un gestionnaire d'extensions pour le programme) qui est téléchargeable librement à l'adresse suivante :

    https://sublime.wbond.net/installation


    Il vous faudra par la suite copier (Ctrl+C) l'instruction fournie en prenant soin de choisir la version que vous possédez (Sublime Text 2 ou 3) 




    Puis la collez dans Sublime Text comme ceci :
    1. Cliquez sur "View" dans la barre de menu
    2. Cliquez sur "Show Console"
    Vous verrez alors apparaître une fenêtre en bas du programme.


    Collez y votre instruction précédemment copiée. Appuyez sur Entrée et relancez votre programme.

    Voilà, vous avez réussi à installer le Package Control !


    Le + de l'article !


    Après avoir installé le Package Control, il vous est possible d'installer l'un des plugins les plus populaires : Live Reload

    Live Reload vous permet de pouvoir rafraîchir par exemple une page HTML que vous codez sur Sublime Text. Nul besoin d'aller tapoter votre touche F5 pour mettre à jour l'affichage de votre page modifiée. Il vous suffit juste de sauvegarder votre code HTML, Live Reload s'occupe du rafraichissement automatique de votre navigateur.

    Pour installer Live Reload, procédez comme ceci :
    1. Ouvrez Sublime Text
    2. Cliquez sur "Tools" puis sur "Commande Palette"
    3. Saisissez dans la recherche qui s'affiche : "pci"
    4. Appuyez sur Entrée
    5. Saisissez "Live Reload" et appuyez sur Entrée




    6. Redémarrez votre Sublime Text
    7. Tapez dans Google : "Live Reload" et choisissez :

    8. Ajoutez l'extension en cliquant sur "Gratuit"
    9. Retournez dans Google Chrome, accédez à : Menu (3 barres) > Plus d'outils > Extensions
    10. Cherchez l'extension LiveReload
    11. Cochez : "Autoriser l'accès aux URL de fichiers"
    Voilà, à vous de jouer !










    Flex : en action menu

    Partons de la situation suivante →voir fichier, puis ajoutons

    nav {
     ...
       justify-content: space-between;
    }

    fichier

    Améliorons la situation en ajoutant du style (de haut vol)

     nav > a {
     ...
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
     }

    fichier

    Ajoutons le comportement flex

    nav > a {
     ...
      text-align: center;
      flex : 1
    }

    Pensez à redimensionner votre page :
    fichier

    Flex : en action

    Notez la différence de comportement de ces deux exemples :

    -> fichier -> fichier
    Notez aussi cette astuce !
    footer {
        margin-top : auto;
    }
    -> fichier

    Voir exemple complet : où l'on remarque que l'input "print" est toujours en bas du conteneur grace à la propriété margin-top !

    -> fichier

    Speudoclassical subclass

    voici comment créer des sous classes en JavaScript.


    Nous allons tenter de comprendre ce code.

    Recopie

    L'idée est simple, nous voulons écrire qu'un taxi "ressemble" à une voiture.

    Pourquoi ne pas écrire le code suivant.


    L'idée est simple, un taxi a les mêmes propriétés qu'une voiture donc recopions simplement ces propriétés dans le constructeur.

    Si l'idée semble ici séduisante, il faut penser que le nombre de propriétés à recopier ainsi peut être important et qu'un cas de modification d'une propriété, nous aurons à répéter cette modification en deux endroits. C'est bien pour cette raison que nous voulons éviter la recopie.

    instancier Car

    Pourquoi ne pas créer une instance de Car dans le constructeur.


    Cette solution pose un certains nombre de problèmes. 
    Coté mémoire, nous créons une instance de Car à chaque fois que nous appellerons la fonction Taxi. Mais, en appelant new Car() dans le constructeur de cette façon, this dans le constructeur Car sera une nouvelle instance de Car et non de Taxi. 

    Rappelons nous que le langage en interne crée à chaque appel de new un objet this.


    Mais, il n'y a pas de lien (mis à part le nom) entre ces deux objets this. Il y a bien deux objets distincts.

    Il serait tentant d'écrire le code suivant. Mais, l’interpréteur du langage ne le permet pas et de toute façon il y aurait encore deux objets this.


    Appel de la fonction

    Pourquoi ne pas appeler simplement la fonction Car dans le constructeur. Encore une fois, la réponse est simple, l'objet this dans car ne représente pas une instance de Taxi mais l'objet global. Puisque la fonction est simplement invoquée dans le contexte global.


    Finalement, il suffirait de passer à cette fonction Car le this instance de taxi.
    La solution utilise donc l'appel à la fonction call.

    Il est parfois difficile d'appréhender son utilisation mais c'est en fait assez simple. Elle a pour rôle de faire correspondre les deux this qui au départ représente deux objets différents ! 

    Une bonne explication est donnée sur la vidéo 11'30





    Ainsi c'est le this de Taxi auquel on ajoutera une propriété pos. Il n'y aura donc aucun objet supplémentaire crée ni de recopie de propriétés.

    Superclass et Subclass

    Reprenons l'exemple de la functional Class.


    Un problème classique est de définir des catégories de Voiture ayant des spécificités bien particulières.

    Il faut a tout pris éviter de recopier le code comme le montre la figure suivante.


    Il est clair que nous devons limiter la recopie de code commun. Par exemple la fonction move est dupliquée.

    Nous allons définir une fonction (la super Fonction) qui regroupe le code commun. Nous créons ensuite d'autres fonction (les sous Fonction) qui décorent la super fonction. Mais, nous pouvons utiliser le mot classe à la place de fonction. Puisque la super classe a pour rôle de générer un grand nombre d'objets.





    3 closures

    setTimeout :


    Array


    return function


    Speudoclassical pattern

    Revenons un instant sur le code de prototype class.


    Nous voyons que chaque fois que nous voulons définir une fonction class, il faut créer un objet avec Object.create et le retourner.

    Modifions le code précédant en introduisant this à la place de obj.


    Et finalement puisque nous devons pour chaque class créer et retourner cette objet pourquoi ne pas l'intégrer directement dans le Langage et ainsi ne plus l'écrire dans le code. Pour valider ce type d'écriture (pour ne pas le confondre avec un autre type d'objet à modifier) il suffira d'appeler la fonction avec l'opérateur new.

    Finalement, nous écrirons


    Examinons une dernière fois ce code


    En Partie 1, nous spécifions les parties spécifiques de chaque objet. Ces différences seront écrire à l'intérieur du constructeur.

    En partie 2, nous aurons le code commun à partager entre tous les objets instanciés de la classe. Ces similarités seront stockées dans l'objet prototype de la classe.

    Prototype Class


    Reprenons l'exemple de functional-classes



    La fonction Car, crée un objet copie les propriétés et retourne un objet.

    Nous avons vue la différences entre la fonction extend et l'utilisation de object.create.

    Nous allons utiliser cette délégation pour transformer notre code. Il suffit de remplacer avantageusement  extend par Objet.create.


    Régles d'ecriture pour JS

    Voici un **guide** donnant les règles à suivre pour l'écriture de code en Javascript édité par Google.

    Functional Classes

    Nous allons voir encore une fois, l'importance des fonctions dans le langage JavaScript et comment elle peuvent créer la base des classes.

    Dans l'article du pattern décoration, nous avons vu comment une fonction peut augmenter (décorer) un objet existant.

    Reprenons cet exemple :

    A noter l'erreur de code loc = pos car la fonction carlike.



    La fonction carlike décore l'objet obj qui lui est passé en paramètre.

    Nous allons renommer et modifier la fonction pour qu'elle génère les objets.


    Le paramètre obj est remplacé par une déclaration de variable locale var obj = {...}.
    A l'inverse de la fonction de décoration qui modifie un objet existant, la fonction Car crée ici l'objet obj et le retournera.

    Notez la convention d'écriture de cette fonction : Le nom commence par une Majuscule.

    Nous venons de définir ce que l'on appelle un constructeur. L'appel de cette fonction, une instanciation, retourne un objet de type Car. L'objet aCar est une instance. Les objets générés possèdent une propriété pos et une fonction move.

    Nous avons déjà vu dans l'article pattern décoration que chaque objet possède sa propre fonction move. En sortant la fonction du constructeur, chaque objet va pointer sur la fonction move ce qui évite la duplication coûteuse en mémoire.


    En sortant la fonction move du constructeur, nous n'avons pas conservé la closure et nous remplaçons obj par this. This sera l'objet placé à gauche de l'appel de la fonction. lorsque nous écrirons bcar.move() this sera lié à bcar.

    Amélirations

    Nous devons améliorer notre écriture, en effet, considérons que nous avons une vingtaine de fonctions identiques à move à écrire, ces fonctions apparaîtrons à deux endroits. 

    Nous regroupons les fonctions dans un objet methods. L'ajout d'une nouvelle fonction en ligne 12 ne modifie en rien (ligne 4) le constructeur Car.


    Mais, en lisant le code, nous remarquons que l'objet methods n'est en rien lié à Car. Ainsi, pour améliorer la lisibilité, nous ajoutons methods comme propriété de la fonction Car. Ce qui évite en plus la création d'une variable globale methods.

    Rappel : une fonction est un objet, un objet peut avoir des propriétés et méthodes. Il en est de même pour les fonction ! Une différence est que les fonctions peuvent être appelées. 


    Dans cette article, nous avons vue comment une fonction peut être considérée comme une classe. Dans d'autres articles, nous introduirons des amélioration de performance avec la chaîne de prototype : un des fondement de JS.

    Annexe : 

    Pour la fonction extend(obj1,obj2), on pourra trouver des exemples de code sur le web.

    Dans la bibliothèque jquery

    L'idée générale est recopier chaque propriété de l'objet2 dans  l'objet1.
    var __slice = [].slice;
    
    function extend () {
      var consumer = arguments[0],
          providers = __slice.call(arguments, 1),
          key,
          i,
          provider;
    
      for (i = 0; i < providers.length; ++i) { 
        provider = providers[i];
        for (key in provider) { // pour toutes les methodes et propriétés
          if (provider.hasOwnProperty(key)) { //oublions la chaîne de prototype 
            consumer[key] = provider[key]; // création d'une prop key et recopie
          };
        };
      };
      return consumer;
    };
    
    extend(sam, person);
    
    sam.rename