Javascript

Développer une application web en ReactJS

ReactJS à la différence de Angular et de VueJS, est une librairie qui s’occupe uniquement de la vue, très véloce, grâce à l’utilisation d’un virtual DOM. Le principe es de ne mettre à jours que ce qui est nécessaire.

Mise en place du projet

$ npx create-react-app myApp
# npx fourni depuis la version npm@5.2.0 est sensé vous faciliter la vie, si npx <command>, et que la <command> n'est pas dans le PATH, iil est capable d'installer la commande depuis NPM et l'invoquer.
# sortie de la commande npx create-react-app
Initialized a git repository.

Success! Created jeu at /Users/poste5hookipa/sites/reactapplication/jeu
Inside that directory, you can run several commands:

  yarn start
    Starts the development server.

  yarn build
    Bundles the app into static files for production.

  yarn test
    Starts the test runner.

  yarn eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd jeu
  yarn start
react native

Les Hooks en React

Les hook sont apparus avec la version de React 16.8.

Le Hook UseState en ReactJS

Le hook UseState se charge du state dans les composants fonctionnels. Dans le composant de classe on avait :

this.setState(nouveauState)
#avec useState
const [state,setState] = useState(initialState)

Le hook useEffect

Il est l’équivalent de plusieurs fonction de cycle dans les composant de classe. Il remplace ComponentDidMount, ComponentDidUpdate.

#invocation au premier rendu
useEffect( () => {

},[])

#invocation au premier rendu et à chaque update du state
useEffect( () => {

},[variable])


#invocation uniquement à chaque update (et pas au premier chargement)

const isInitialMount = useRef(true);

useEffect(() => {
  if (isInitialMount.current) {
     isInitialMount.current = false; //grâce à cette astuce on bypasse l'exécution du code d'update au premier rendu
  } else {
      // le code pour chaque update
  }
});
javascript

Installer NPM sans avoir les problèmes de droit d’accès à des répertoire

Une des choses qui m’énervent le plus (et les développeur) est que dans certains processus de build avec NodeJs, on est confronté à des erreurs qui résultent de droits d’accès à des répertoires parce qu’on n’est pas utilisateur root. Ce problème se produit surtout en environnement MacOS et Linux. sous Windows vous travaillez en Administrateur en général.

Sur le site de NPM, il vous est expliquée ue procédure d’installation de NodeJS qui vous évite cet écueil. Le principe consiste à changer le répertoire par défaut de NPM.

https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally

Qu’est ce que le temporal dead zone TDZ en ES6?

Cette feature a été introduite depuis ES6 et concerne let et const, deux façons alternatives de déclarer des variables. En bref, si vous vouez accéder à des variables déclarées par let et const avant qu’elle ne soient initialisée va déclencher un ReferenceError là où l’utilisation de var va déclencher un undefined.

#utilisation nominale
var a = "bonjour"
console.log(a)
> "Bonjour"

#utilisation avant initialisation
console.log(b)
var b = "bonsoir" // undefined

#avec const
console.log(c)
const c = "hello" // ReferenceError: can't access lexical declaration `b' before initialization

Le variable hoisting

Pour comprendre le TDZ, il faut d’abord comprendre ce qu’est le hoiosting (hissage en anglais). Dans le langage de programmation JS, les variables sont les premières choses processées lors d’une compilation. déclarer une variable n’importe où équivaut à les déclarer en début de script. (source MDN).

Lorsque vous écrivez var a = « bonjour » en fait il y a deux choses qui se passent (et il faut avoir le réflexe de voir la chose de cette façon)

1/la déclaration de la variable : var a

2/l’initialisation de la variable, on lui donne une valeur : a = "bonjour"

Le hoisting (hissage) ne concerne que la déclaration et pas l’initialisation (important à savoir).

#donc écrire 
a = "bonjour"
var a
#est équivalent à
var a
a = "bonjour"

Pour cette raison, il est conseillé de déclarer les variable au début de leur scope (global ou dans la fonction). Donc ci-dessous un exemple :

function  dire(){
    console.log(a)
    var a = "bonjour"
}
#équivalent à
function dire(){
    var a
    console.log(a)
    a = "bonjour"
}

#autre exemple avec deux variables
var a = "bonjour"
var b = "bonsoir"

#équivalent à 
var a
var b
a = "bonjour"
b = "bonsoir"


#autre exemple
var x = y, y = 'A';
console.log(x + y); // undefinedA

#équivalent à
var x
var y
x = y // y n'est pas initialisé mais il existe et vaut undefined
y = 'A' // y est initialisé, mais x est toujours undefined
console.log(x + y) // undefinedA

La TDZ Temporal Dead Zone

Le petit exemple ci-dessous illustre les effets du TDZ pour let :

console.log(x) //ReferenceError: can't access lexical declaration `x' before initialization
let x = "bonjour" 

# équivalent
let x
console.log(x)
x = "bonjour"

let fait intervenir le hoisting, mais à la différence de var, si on essai d’y accéder, il renvoie ReferenceError. La TDZ est la propriété qui renvoie une ReferenceError lorsqu’on essai d’accéder à une variable non initialisée. La TDZ est cet espace entre la déclaration et l’initialisation d’une variable.

La TDZ a été créé pour avoir plus de feedback lorsque l’on code en Javascript.

Pour aller plus loin : la TDZ concerne aussi les argument d’une fonction. Je ne traiterais pas de ce sujet pour l’instant.

Pour plus d’information : la source d’inspiration

javascript

Améliorer son code par des cas réels

Lorsque l’on code et que l’on est débutant ou intermédiaire, il y a des bonnes chances de faire du code touffu ou en spaghetti, illisible, et souvent buggé. Nous allons voir avec des exemples concrets comment à partir d’un code issu du monde réel, on peut améliorer la lisibilité du code, la concision, et l’efficacité tout en évitant des bugs.

Lecture d’un tableau d’objet en Javascript

L’exemple ci-dessous est tiré d’une application Handlebars, le snippet lit un tableau d’objet en deux dimensions.

if(enfantsObject.EnfantsComm != null || enfantsObject.EnfantsP1 != null || enfantsObject.EnfantsP2 != null){
            if(Object.keys(enfantsObject).length){
                $.each(enfantsObject, function(index,value){
                    if(value != null && value != "{}" && jQuery.isNumeric( value )){
                        $.each(value, function(index2, value2){
                            if(value2.pension !== undefined){
                                montPens += Number(value2.pension);
                            }
                        })
                    }
                })
            }
        }

Le model à lire était un tableau d’objets avec les propriétés suivantes, un seul niveau d’imbriquement. Il y a plusieurs choses qui me surprennent, le fait d’utiliser la fonction de Jquery each, qui sert à itérer dans les éléments du DOM (les tags HTML), elle est ici utilisée alors qu’elle ne devrait pas l’être, inapproprié.

Le problème c’est que les propriétés sont changeante, elles peuvent ne pas être présentessuivant la façon dont l’objet a été initialisé. Voir l’exemple ci-dessous :

Dans l’exemple ci-dessus, les propriétés pension et pensionDate ne sont pas présentes ! Mauvaise pratique qui va nous compliquer le code, soit on retravaille l’initialisation, soit on checke les objets quand ils sont utilisés.

Ensuite il y a le Object.keys, elle est utilisée ici pour détecter que l’objet possède des clés (enfantCommuns, enfantP1, etc). Ceci n’est pas du tout stable, c’est en amont que les choses devraient être faites, notamment en initialisant proprement les différents propriétés de l’objet enfantsObject, y mettre un objet vide nous assure de la présence de la propriété et ne pas à avoir faire ce check inutile.

Première étape on simplifie le code

Si vous voulez améliorer votre code, mais que vous ne savez pas par où commencer, choisissez la lisibilité, qui doit être l’ultime but recherché, pas de code intelligent qui marche mais difficile à lire pour les autres développeur. Quitte à faire une simple boucle for au lieu de faire un map comme en programmation déclarative.

Ci-dessous, j’ai scindé en trois parties (attention il ya duplication de code similaire), ce qui n’est pas bon, mais cette étape intermédiaire nous permettra de refactorer en une fonction réutilisable.

J’ai du faire varier les différents cas sur l’interface pour voir les cas limites, et vous verrez un check pour s’assurer que c’est un tableau, en effet, quand il n’y a pas d’enfant présent, on n’a pas un tableau vide mais un objet ! (pourquoi ne pas revoir l’initialisation vous me direz? pour des impératifs de budget tout simplement)

Preuve que répéter du code n’est pas bon, parfois j’oublie de renommer à certains endroits et le programme plante.

        var pensionEnfantscommun = 0;
        var pensionEnfantPers1 = 0;
        var pensionEnfantPers2 = 0;

        if(enfantsObject.EnfantsComm != null && Array.isArray(enfantsObject.EnfantsComm)){
            for(i=0;i<enfantsObject.EnfantsComm.length;i++){
                if(enfantsObject.EnfantsComm[i].pension != undefined && enfantsObject.EnfantsComm[i].pension != ""){
                    pensionEnfantscommun += parseInt(enfantsObject.EnfantsComm[i].pension);
                }
            }    
        }

        if(enfantsObject.EnfantsP1 != null && Array.isArray(enfantsObject.EnfantsP1)){
            for(i=0;i<enfantsObject.EnfantsP1.length;i++){
                if(enfantsObject.EnfantsP1[i].pension != undefined && enfantsObject.EnfantsP1[i].pension != ""){
                    pensionEnfantPers1 += parseInt(enfantsObject.EnfantsP1[i].pension);
                }
            }    
        }

        if(enfantsObject.EnfantsP2 != null && Array.isArray(enfantsObject.EnfantsP2)){
            for(i=0;i<enfantsObject.EnfantsP2.length;i++){
                if(enfantsObject.EnfantsP2[i].pension != undefined && enfantsObject.EnfantsP2[i].pension != ""){
                    pensionEnfantPers2 += parseInt(enfantsObject.EnfantsP2[i].pension);
                }
            }    
        }

On vérifie que tout fonctionne (en tant que développeur il faut toujours bien tester ce que l’on fait). Maintenant nous pouvons faire une fonction réutilisable.

Seconde étape on refactore avec des fonctions

        // sous fonction 
        const majorationPension = function(enfant){
            if(enfant.pensionDate != undefined && enfant.pensionDate != ""){
                return Math.min(parseInt(enfant.pension) * 1.25,PARAM.SEUIL_JUGEMENT) 
            } else {
                return parseInt(enfant.pension)
            }
        }

        // fonction locale de calcul de fonction
        const sumPension = function(arrayEnfants){
                            const pensionEnfants = 0
                                if(arrayEnfants != null && Array.isArray(arrayEnfants)){
                                            for(i=0;i< arrayEnfants.length;i++){
                                                if(arrayEnfants[i].pension != undefined && arrayEnfants[i].pension != ""){
                                                    pensionEnfants += majorationPension(arrayEnfants[i]);
                                                }
                                            }    
                                        }
                                        return pensionEnfants
                                    }
        var montPens = 0;
        var pensionEnfantscommun = 0;
        var pensionEnfantPers1 = 0;
        var pensionEnfantPers2 = 0;

        pensionEnfantscommun = sumPension(enfantsObject.EnfantsComm)
        pensionEnfantPers1 = sumPension(enfantsObject.EnfantsP1)
        pensionEnfantPers2 = sumPension(enfantsObject.EnfantsP2)

J’ai ajouté une sous fonction majorationPension parce qu’il était nécessaire de faire un filtrage, et on n’oublie pas le parseInt, qui permet de convertir en véritable entier, sinon on aurait des erreurs de type NaN (not a number)

Notez l’utilisation de const pour des variable locales, une bonne pratique à prendre.

Conclusion

Maintenant on a sauvé quelques lignes, et surtout obtenu un code plus lisible pour la maintenance ou les évolutions plus tard.

javascript

Faire des tabulations en Javascript et Jquery

Voici le code minimal pour faire une tabulation (des onglets que l’on peut cliquer pour changer de contenu)

Comment faire des onglets cliquable en javascript?

Le principe :

On a en fait une rangée d’éléments cliquables, que l’on va mettre dans des <li>, mais ce n’est pas obligatoire, et ensuite les différentes <div> que l’on va révéler ou cacher suivant les <lI> cliquer.

<html>
<head>
<title>Tutorial theme</title>
</head>

<body>
    <style>
        .tab-menu {
            padding: 0;
        }
        .tab-menu li {
            display: inline-block;
        }
        .tab-menu .active {
            background: yellow;
        }
    </style>

        <ul class="tab-menu">
            <li><a href="#tab-1">Tab 1</a></li>
            <li><a href="#tab-2">Tab 2</a></li>
            <li><a href="#tab-3">Tab 3</a></li>

        </ul>

<div id="tab-1" class="tab-content" >
Contenu du tab 1
</div>
<div id="tab-2" class="tab-content" >
Contenu du tab 2
</div>
<div id="tab-3" class="tab-content" >
Contenu du tab 3
</div>


</body>
    <script type="text/javascript">
        $(document).ready(function() {
          $('.tab-content').slice(1).hide();
            $('.tab-menu li').eq(0).addClass('active');
            $('.tab-menu li a').click(function(e) {
                e.preventDefault();
                var content = $(this).attr('href');
                $(this).parent().addClass('active');
                $(this).parent().siblings().removeClass('active');
                $(content).show();
                $(content).siblings('.tab-content').hide();
            });
        });
    </script>
</html>

Donc pour résumer en cliquant un lien, ce lien a sa classe css à active, les autres qui sont à côté sont inactifs, content est égal à ce qu’il y a dans l’attribut href, $(content) va en réalité sélectionner l’élément ayant l’id (unique cela va de soi), et le montre, tous ses voisins sont cachés.

 

 

 

Checklist pour développer une PWA (Progressive Web App)

J’essais de créer une PWA depuis quelques temps, et je m’aperçois qu’il y a pas mal de choses à connaitre (vraiment), les connaissances que j’ai acquises en deux ans de JS et d’Angular, ne sont pas suffisantes. Je me fais une liste des pré-requis pour développer une PWA afin d’avoir une feuille de route pour avoir le parcours optimal. Les informations ci-dessous sont tirées du site Google Developer.

Introduction aux Progressives Web App (PWA)

Les PWA sont des pages web dynamiques, offrant des fonctions équivalentes aux applications natives, c’est récent à la date du 2017. Pourquoi a-t-on inventé ça? Pour répondre à plusieurs problématiques inhérentes aux applications natives.

Pourquoi parier sur les PWA?

1/Réduire le travail de développement.

Souvenez vous il n’y a pas si longtemps, on avait Ios, Android et Windows Phone (ce dernier est enterré). Il nous reste donc IOS et Android. Donc si vous voulez développer une application pour ces deux plateformes, vous devez faire deux fois le travail.

2/Les utilisateurs n’installent plus les applications natives

, et seulement une poignée est utilisée régulièrement.

3/Réduire la taille des applications (ou la friction d’installation)

C’est le côté progressif. On ne vous oblige pas à installer une application, mais à tester en douceur le site web, et aller plus loin si vous êtes intéressé.

Ce sont les trois avantages majeurs des PWA. Nous allons voir qu’elles n’ont pratiquement rien à envier aux applications natives. Donc plutôt que d’apprendre à programmer en Java ou Swift, voire en C# si vous voulez utiliser Xamarin (la solution la plus aboutie actuellement), vous allez pouvoir programmer pour toutes les plateformes en Javascript seulement! Donc gros avantage pour les développeurs front-end qui connaissent déjà le Javascript !

Les notions à connaître en PWA

1/Web Push Notification

Les notifications sont les messages que vous voyez apparaitre en haut de l’écran de votre smartphone. Push veut dire qu’il n’est pas besoin (après que vous ayez opté pour les recevoir) pour vous de faire quoique ce soit pour les recevoir. C’est intéressant car pour les marketeurs et pour les développeurs, vous pouvez entrer dans l’intimité d’une personne.

2/Service Worker

C’est l’élément essentiel de la PWA et c’est un gros morceau. Le Service Worker est un thread du processus du navigateur qui tourne en parallèle à côté de la page web proprement dite (le DOM) qui est un autre thread, c’est du code javascript, qui rend les choses hors connexion possibles entre autre (et aussi les Push Notification), le stockage des informations même quand vous êtes hors ligne. Le service worker peut accéder au thread de la page web, donc à l’objet window. Mais il n’y accède pas avec l’objet window qui n’est pas disponible dans le thread, mais via self qui est l’équivalent de window.

Dans le cadre de la programmation d’un service worker, il faut connaitre les Promise, une façon moderne de programmer le JS asynchrone sans faire appel aux callback.

3/Accès aux fonctions natives du smartphone

Ce point est bien sûr très important, à quoi bon si vous ne pouvez pas prendre des photos, enregistrer des vidéos et sons, vous localiser avec le GPS, connaitre l’orientation de l’écran, chatter en vidéoconférence? La réalité virtuelle est aussi disponible quoique encore expérimentale. Donc en résumé voici ce que permet de faire une en 2020 une progressive Web App.

  • géolocalisation GPS
  • Caméra
  • Sensors
  • Payment Request pour les paiements
  • auto update

4/Add to Home screen

C’est pour avoir l’équivalen et de l’installation des application natives depuis le store des applications.

5/ Le fonctionnement hors ligne

C’est une des proposition de valeur majeure des PWA, grâce au Service Worker, votre application web va pouvoir fonctionner hors ligne, et dès que la connexion au web sera restaurée, les données peuvent être synchronisée (moyennant un code bien sûr).

6/Le fichier manifest.json

Un fichier manifest en général décrit le contexte ou le paramétrage de l’application. La première fois que j’ai vu ce concept c’est dans les applications mobiles Android, où il y a un fichier manifest, sur IOS il porte un autre nom info.plist.

Maintenant que vous avez une idée plus claire commençons à développer un PWA ! Le plus didactique est de convertir un site web traditionnel en PWA, plutôt que de faire un PWA de zéro.

node JS

Générer un projet Javascript avec NPM

Imaginez que vous ayez un projet front end, par exemple personnalisation d’un thème d’une boutique Magento, cela ne concerne que le CSS et HTML (voire du javascript), les fichiers sont gros, pouvant faire dix milles lignes en CSS, hors de question de le faire directement en CSS, il y a beaucoup mieux le Sass. Le Sass est un « langage » qui va se compiler en CSS, l’avantage est qu’il est facilement  compréhensible, car sa syntaxe est structurée.

/* Sass */
div > p {
  color:blue;
  a {
    color : red;
  }
}

/* converti en CSS */

div > p {
  color: blue;
}
div > p a {
  color: red;
}

L’exemple ci-dessus illustre la lisibilité de la notation en Sass, hiérachisée mais pas forcément plus concise, en revanche très lisible, la syntaxe Sass est beaucoup plus riche et plus puissante que ne le montre l’exemple ci-dessus. En comparaison, la notation CSS est plus plate et répétitive, et bien sûr moins lisible.

NPM va nous permettre d’installer les dépendances, et dans le cas du Sass, on va installer node-sass pour compiler le Sass en CSS à chaque fois qu’on enregistre le fichier Sass (extension .scss).

Initialisation d’un projet NPM

npm init

Après cette commande vous devez répondre à un tas de questions comme le nom du projet, le propriétaire, la licence, pas mal de champs sont optionnels rassurez-vous etc.

Un fichier package.json est généré.

Ensuite installons le paquet node-sass. Ce dernier permet de surveiller les modifications d’un fichier Sass et de compiler en CSS automatiquement.

$ npm install -D node-sass nodemon
#le D signifie une dev dependency

Dans votre package.json, ajoutez ces lignes

“scripts”: {
  “build-css”: “node-sass --include-path scss scss/main.scss   public/css/main.css”
}

#Pour lancer la compilation
$ npm run build-css

Mieux encore watcher pour automatiquement compiler au moindre changement puis sauvegarde du fichier sass.

“scripts”: {
 “build-css”: “node-sass --include-path scss scss/main.scss public/css/main.css”,
 “watch-css”: “nodemon -e scss -x \”npm run build-css\””
},

lien : https://medium.com/@brianhan/watch-compile-your-sass-with-npm-9ba2b878415b

javascript

Sélectionner des éléments HTML en Javascript pur

Sur ce blog, quand je parle de Javascript, je parle de Javascript pur, et non de JQuery, cette extension étant trop célèbre, sur les forums les gens ont même tendance à proposer une solution en JQuery alors que c’est en Javascript pur (Vanilla Javascript) que la question était posée.

Sélectionner des tags HTML en Vanilla Javascript

Supposons que vous avez une page HTML, vous agrémentez d’un script Javascript en fin de page, on va utiliser la méthode querySelectorAll, qui est une fonction très importante, car elle permet de sélectionner des tags HTML selon divers critères. Par exemple, si on veut les liens hypertextes présents sur la page courante :

var links = querySelectorAll("a")

Pour comprendre comme ça marche, le sélecteur est « a » comme ancre, c’est comme en CSS, si je veux que des div, je mets « div », si je veux les div et ancres :

var elem = document.querySelectorAll("a","div")

Maintenant on va faire un peu plus compliqué :). Supposons que nous voulions seulement les liens nofollow, sur une page HTML un lien nofollow est spécifié avec l’attribut « rel » :

<a href="https://www.google.fr" rel="nofollow" />Lien</a>

Pour sélectionner ce lien, on fera :

var links = document.querySelectorAll("a[rel=nofollow]")

querySelectorAll pour sélectionner dans un sous ensemble de HTML

Parfois on a besoin de faire une sélection sur un ensemble plus petit, parce que la page est complexe, on veut dégrossir le travail. On peut dans ce cas sélectionner un élément HTML d’ordre supérieur, et faire un querySelectorAll sur ce sous ensemble.

var contenu = document.querySelectorAll("div[id=main]")
var links = contenu.querySelectorAll("a")

Ceci est rendu possible par le mécanisme d’héritage de type prototypal (pas un héritage classique au sens classe).

querySelector pour ne sélectionner que le premier

Il peut arrive qu’on n’a besoin que d’un élément (quand on est sûr), et cela pour éviter d’avoir à itérer sur un tableau, on utiliser alors QuerySelector, qui nous retourne alors un seul élément. Dans le jargon, on parle d’un node retourné, là où querySelectorAll retourne un nodeList.

javascript

Comment créer un bookmarklet?

Créer le bookmarklet le plus simple du monde en 10 secondes

<a href="javascript: alert('Un bookmarklet !');">Fav moi</a>

Cela va créer lien Fav moi, que vous allez glisser déposer sur la barre des favoris.

En fait ce n’est rien de plus qu’une ligne de javascript que vous auriez fait de façon classique, sauf que c’est mis dans un lien, et que vous avez mis en favori ce lien, astucieux comme concept non?

Pour c’est super intéressant de savoir faire un bookmarklet? C’est plus simple que de faire faire un addon pour Firefox ou Chrome, par exemple, et c’est presque croos browser de nos jours aux différences d’implémentation de Javascript près.

Parce que ça augmente les fonctionnalité du browser, donc de faire des trucs super intéressant sur les pages web, comme par exemple surligner les liens hypertexte, ou remplacer le logo de Google par celui de Bing ! et vice versa.

Pour les SEO cela peut être intéressant, faites travailler votre imagination.

Les différents degrés de sophistication de conception des bookmarklet

Nous avons vu que la première et plus simple manière de faire un bookmarklet est de mettre directement le Javascript dans un lien hypertexte. Ok c’est cool mais si le code Javascript est plus conséquent?

Un bookmarklet est un code qui va s’exécuter sur la page courante. Vous pouvez définir une fonction anonyme dans la section script et l’appeler dans le lien hypertexte.

  1. Le javascript dans le lien directement (voir ci-dessus)
  2. Le javascript dans une fonction anonyme quand le code est plus conséquent
  3. Le javascript dans un fichier externe (on fait une inclusion avec <link>)
  4. Plus badass, incluez AngularJS ou VueJS ou toute autre librairie
javascript:(function(){// code javascript })();

Voici un exemple de bookmarklet que j’ai fait pour remplir le champ « Legende », »Alt » et « Description » dans l’interface d’ajout d’image.

<a href="javascript:(function(){var t=document.querySelectorAll('div.media-sidebar label input');var a=t[2];var u=document.querySelectorAll('div.media-sidebar textarea');var b=u[0];var v=document.querySelectorAll('div.media-sidebar label input');var c=u[1];b.innerHTML=c.innerHTML=a.value;this.stop;})()">copy</a>

Inclure une feuille de Javascript externe quand vraiment le code est trop volumineux. Dans ce cas il vous placer le script dans une url accessible sur le web.

javascript: (function () { 
   var jsCode = document.createElement('script'); 
   jsCode.setAttribute('src', 'http://domaine.com/file.js');                  
 document.body.appendChild(jsCode); 
}());

Souvenez vous que votre bookmarklet ne doit pas avoir de collission avec le JS de la page sur laquelle elle sera utilisée. Dans l’exemple ci-dessus c’est une fonction à invocation immédiate qui est utilisée, évitant justement la collision de variable.

Si vous chargez un script et que vous voulez être sûr  qu’il soit chargé, voici un tuto sur un site https://idiallo.com/javascript/async-jquery

Element de langage en javascript utile pour les bookmarklets

Les bookmarklets font beaucoup de traversing de DOM ou de sélection de DOM, vous devez en général le faire en Javascript pure voici quelques commandes pour vous simplifier le travail

querySelectorAll

Cette fonction est très utilisée pour matcher des éléments du DOM, elle va vous retourner un objet de type NodeList. NodeList n’est pas un tableau, vous ne pouvez pas le traverser avec une boucle for traditionnelle, ni map(), filter() ou slice(), il faut le convertir en tableau avant.

#sélection des liens 
var a=document.querySelectorAll('a') // NodeList
#sélection des div avec la classe 'primary'
var a = document.querySelectorAll('div.primary')

Convertir un NodeList en tableau

# Array.from()
var array = Array.from(a)

#spread operator
var array = [...a] // rendu possible car a est iterable
javascript

A bookmarklet to let you easily test javascript snippets

A shell for executing javascript in a bookmarklet !

A shell in a bookmarklet

Can you believe that? a bookmarklet is a short javascript code snippet (usually shorter than 1024 characters), that performs various tasks, and you can bookmark them = execute them by clicking on the bookmark, neat huh? For example if you are a member of the social bookmarking site Delicious, there is a bookmarklet that let you bookmark a site without copy pasting a url into the form, all you need to do is click on the bookmarklet, it’s (almost) done !

With the bookmarklet that I am talking, you have a console like a Unix shell, type you javascript command or script, press enter and the code is executed. Go fetch the shell bookmarklet.

Once you are on the webpage, drag the « Shell » bookmarklet in your bookmark area, that’s all. Just clik on the bookmark to open a popup window (the console) and start playing with javascript !

javascript

JSON Javascript Object Notation

A quoi sert la notation JSON

Le JSON ( Javascript Object Notation) est un format d’échange de données très utilisé dans le domaine du web et pas forcément que dans du Javascript. En fait PHP aussi possède des fonction pour encoder un tableau associatif en tableau JSON.

Vous aurez besoin de JSON quand vous allez faire de l’AJAX. Où quand vous allez faire appel à une API chez n’importe quel fournisseur de service Saas possédant une API digne du nom.

Explication de la syntaxe JSON

Un objet JSON est écrit dans des accolades.

{action:edit,id:1956} cette chaîne JSON va inclure comme clé de tableau action et id. Par exemple vous avez une application web en AJAX qui permet d’éditer, d’effacer, un article ou un item identifié par son id. Quand vous cliquez sur le lien « Editer », une action AJAX va envoyer un tableau JSON contenant comme information le type d’action et l’id de l’objet à effacer.

Utiliser en PHP et AJAX

On utilise couramment JQuery pour des traitement AJAX, n’essyez pas de le coder vous même en Javascript pure (compliqué, sujet aux erreus)

Imaginons que vous avez une page html dynamique écrite avec PHP et que vous avez un bouton qui va rafraichir une partie de la page (cours de bourse de Michelin par exemple), en cliquant sur le lien « Rafraichir cours de bourse », un appel AJAX est fait à un script PHP « update_cours_de_bourse.php » (dans la réalité je le nommerais do.php tout simplement).

Ce fichier do.php va calculer le cours de bourse de Michelin et retourner un tableau JSON, on utilisera simplement la commande echo de PHP pour afficher les valeurs JSON :

echo {label:michelin,cours:26.5}

le résultat sera lu par JQuery de la page appelante, grâce à une fonction callback (une fonction qui lit la valeur retournée par la page do.php).

javascript

Les fonctions flèches en Javascript ES6

Découvrez les fonctions fléchées en Javascript

 

Dans javascript on connaissait jusqu’en ES6 deux façon de déclarer des fonctions, les fonctions nommées et les fonctions anonymes.

Déclaration de fonctions nommées :

function saluer(nom){
    console.log('Bonjour ' + nom)
}

Les fonctions anonymes

function (nom){
    console.log('Bonjour ' + nom)
}

Depuis ES6 vous pouvez déclarer les fonction flèches !

Attention les fonctions flèches ne sont pas équivalentes aux fonction nommées. Une fonction flèche n’a pas de this . Les fonctions flèches sont toujours anonymes. Elles ne peuvent être utilisé comme constructeur.

const add = (a) => return a + 5

add(5) //10

Les fonctions flèches ne sont pas à utiliser en tant que méthode

D’abord c’est quoi la différence entre une fonction et une méthode?

une méthode est une fonction définie en tant que propriété d’un objet, sinon pas de différence au niveau de la syntaxe. Dans le cas des fonctions flèches, il y a une différence de comportement vis à vis de this.

L’exemple ci-dessous  :

var obj = {
i: 10,
b: () => console.log(this.i, this),
c: function() {
    console.log(this.i, this)
    }
}

obj.b(); // undefined Window {...}
obj.c(); // 10  Object{i:10}

Alors qu’une fonction anonyme connait son propre this, une fonction flèche n’a pas son propre this, comme l’atteste l’affichage, le this de la fonction se réfère à l’objet Window.

Les fonctions flèches n’ont pas de constructeur

var Foo = function{}()
var f = new Foo()

var Bar = () => {}
var b = new Bar() //Uncaught TypeError : Foo is not a constructor
node JS

Utiliser le Sass et NodeJS pour accélerer son développement CSS

Aujourd’hui en 2017 si vous développez en HTML/CSS directement dans le dur, je vous prédis que vous allez souffrir.

On ne développe plus ne CSS directement, on passe par le LESS ou le SASS.

Personnellement j’utilise le SASS, c’est un lagage qui va être transformé en CSS grâce à un programme qu’on appelle un compilateur.

Mais voyons tout de suite les avantage d’utiliser le SASS:

Supposons que vous ayez une div à l’intérieur d’une autre.

<div class="outer">
    <div class="inner">
        <a href="//google.fr">Google</a>
    </div>
</div>

Pour styler les div, vous faites en CSS:

.outer {font-size:12px}

.inner{font-size:10px}
.inner a {color : blue}

 

javascript

Commencez à programmer en javascript ES6 (ES2015) doucement

Programmer en ECMASCRIPT 6 alias ES2015

Si vous faites du Web, vous avez sans doute entendu abondamment parler de Ecmascript 6. C’est une norme qui décrit la syntaxe du langage Javascript (pour simplifier)

Voyons les innovations syntaxiques que vous devez absolument connaitre car tous les navigateurs les utilisent aujourd’hui.

Déclaration de variable avec var (méthode historique)

Jusqu’à présent vous ne déclariez les variables qu’avec var.

Or il cause beaucoup de poblèmes : son scope est global à l’objet window.

var prenom = "Yvon"

On dit que son scope (sa portée) est globale. Si vous venez du monde du php, vous avez dû voir qu’on peut déclarer une variable comme globale avec le mot clé global.

Pour des raisons de bonne pratique de sécurité, il faut éviter de déclarer des variables globales.

Revenons au Javascript, var déclare une variable de porté globale, c’est à dire qu’elle peut être utilisée partout.

Jusqu’à récemment avant ES6, nous ne pouvions déclarer de variable de porté de type bloc. Un bloc est tout ce qui est compris dans une parie d’accolade.

Une variable de type bloc, de portée bloc, n’existe que dans la paire d’accolade, en dehors on ne la connait pas.

Historiquement var a été introduit pou faciliter la programmation, afin que les programmeurs novices puissent utiliser rapidement Javascript. Mais au fil du temps cela s’est avéré être un mauvais choix. Aujourd’hui (seulement) les concepteur du langage on décidé d’introduire deux nouvelles façons de déclarer une variable. Ces deux nouvelles façons const et let déclarent des variables de porté de bloc.

Déclaration de variable avec const

A la différence de PHP par exemple, const ne déclare pas une constante ! La signification de const est que le binding est constant, invariable, vous ne pouvez pas réassigner la variable à un pointeur différent, mais vous pouvez modifier sa valeur. En Javascript, la notion de constante existe dans le cadre de la programmation fonctionnelle via des librairie comme immutable.js .

cont prenom = "Yvon"

Pour vous montrer que const a sa valeur qui peut changer :

const prenom = 'Yvon' prenom = 'Julien' console.log(prenom) // Erreur Uncaught TypeError: Assignment to constant variable. 

Le code ci-dessus montre que la valeur de la primitive n’est pas modifiable. Par contre, si on déclare un objet litéral :

const eleve = { prenom :'Yvon', nom : 'Huynh'} eleve.prenom = 'Julien' console.log(eleve.prenom) // Julien

 

On peut modifier une propriété d’un objet litéral. eleve est bindée par référence à cet objet. Mais si on essai de réaffecter par référence :

const eleve = { prenom : 'yvon', nom : 'huynh' } eleve = { prenom : 'toto' } console.log(eleve.prenom) // Uncaught TypeError: Assignment to constant variable.

Une autre particularité de const est que vous devez initialiser dè sla déclaration de la variable, sinon vous avez une erreur.

const pays; //Uncaught SyntaxError: Missing initializer in const declaration

Block scope avec const

Enfin regardons l’aspect le plus important concernant const, il est block scoped, c’est à dire qu’en dehors (à l’extérieur) des accolades où la variable a été définie, elle n’existe pas.

function saluer(ami){ const pays = 'France' if(pays === 'France'){ const greet = ' Monsieur' console.log('Bienvenue en ' + pays + greet) } console.log('A une autre fois en ' + pays) console.log('Au revoir ' + greet) } saluer('Yvon') // imprime Bienvenue en France Monsieur,A une autre fois en France, mais affiche Uncaught ReferenceError: greet is not defined

Alors que pays reste en valable, greet n’est plus connue en dehors des accolades où greet a été définie.

Un exemple encore plus flagrant on va créer deux variables portant le même nom,mais avec des valeurs différentes :

const ville = 'Paris' function saluer(nom){ const ville = 'Nantes' console.log('bienvenue à ' + ville) } saluer('Yvon') //bienvenue à Nantes console.log('Euh non on est à ' + ville) //Euh non on est à Paris

Nantes ne peut exister en dehors des accolades de la fonction.

 

Peut on rendre une variable const vraiment immuable?

Même si dans votre vie vous aurez probablement peu l’opportunitéde rendre un objet immuable, il existe une façon de rendre immuable une variable déclarée avec const.

const eleve = Object.freeze( {prenom : 'yvon', adresse : { rue : ' De gaulle', ville : 'Nantes', codepostal : 44000} }) eleve.prenom ='Julien' console.log(eleve.prenom) // yvon

Vous remarquez que la propriété prenom est inchangée. Si vous utilisez « use strict »; vous aurez une erreur Uncaught TypeError: Cannot assign to read only property ‘prenom’ of object ‘#‘.

Object.freeze est ‘shallow’ comme on dit en anglais, cela veut dire que vous pouvez quand même altérer les propriétés des objets imbriquée.

"use strict"; const eleve = Object.freeze( {prenom : 'yvon', adresse : { rue : ' De gaulle', ville : 'Nantes', codepostal : 44000} }) eleve.adresse.codepostal = 44100 console.log(eleve.adresse.codepostal) // 44100

Le code ci-dessus est tout à fait valide.

A quoi ça sert const en Javascript?

On dit que les variables déclarées avec const sont « block scoped ». Un bloc c’est ce qui est entre accolade dans la définition d’une fonction. C’est pour pallier au défaut de var (qui est défini dans les accolades d’une fonction, on dit que var est function scoped), qu’on a introduit const afin de mieux structurer son code et d’éviter des collisions.

 

Qu’est ce que la Temporal Dead Zone?

Lorsqu’un code javascrip est exécuté, une variable ne peut être settée ou gettée tant que l’exécution n’a pas atteint la ligne de code où la variable a été définie.

function saluer(name){ // début de la fonction if(name === 'yvon'){ //début du block var ville = 'Paris' console.log('Pays = ' + pays + ' Ville destination = ' + ville) var pays = 'France' } } saluer('yvon') // Pays = undefined Ville destination = Paris

On voit que la variable pays étant définie après le console.log, il est à undefined. Par contre que se passe-t-il si on a const à la place de var ?

function saluer(name){ // début de la fonction if(name === 'yvon'){ //début du block var ville = 'Paris' console.log('Pays = ' + pays + ' Ville destination = ' + ville) const pays = 'France' } } saluer('yvon') //Uncaught ReferenceError: pays is not defined

Vous avez une erreur (un avertissement) comme quoi votre variable n’est pas définie. Au moment ou le console.log s’exécute, pays n’est pas encore définie, elle n’a pas de valeur attribuée. L’utilité de la Temporal Dead Zone (TDZ) est de vous permettre de coder plus proprement, en lançant des avertissements.

javascript

Comprendre l’objet Window dans javascript

Quelle est la différence entre Window, Document, Screen?

Window est l’objet principal du DOM, le document object model, qui est la base de la page web et quand je dis la base ça comprend vraiment tout, les images, les scripts javascript, et autres objets, bref ce que vous voyez dans la fenêtre de votre navigateur.

Quand vous faite un script javascript, vous ne le savez peut être pas, mais vous utiliser une méthode ou un objet de l’objet Window, qui est le parent de tous les objets javascripts.

 

Document est un sous objet de Window. Document est en fait la vraie partie visible de la page qui est dans votre navigateur.

Pour savoir ce que l’objet Window contient, je vous invite à faire tourner le script suivant dans la console javascript (pour Chrome, faire F12,cliquer sur console) :

console.log(window);

 

cette ligne de javascript va afficher l’objet Widow dans la console de debug. Déplier le et vous allez être submergé, car il contient beaucoup d’objet, et vous allez vous rendre compte qu’il est facile de faire une radiographie de la page web et très facilement.

Ne sous estimez pas la puissance d’un simple console.log, il vous permet d’afficher n’importe quel objet, même les lus obscure. Par exemple, quend vous chargez un script Jquery, il est rattaché au DOM donc à window. Vous pourrez afficher tout l’objet Jquery et regarder ce qu’il contient ! De même si vous ne savez pas ce qu’il y a dans l’objet Angular, vous pouvez l’afficher de cette façon. Attention, c’est gros et vous allez peut etre vous y perdre.

 

Cas des iframes

Lorsqu’il y a des iframes dans votre page html, le code JS qu’il y a dans le ifrmae ne peut pas accéder directement à la fenêtre qui le contient. Si vous êtes dans l’iframe, pour accéder à un élément du DOM de la fenêtre parente, vous devez faire :

var topWindow = window.top

votre variable topWindow contiendra une référence vers l’objet window le pus haut dans la hiérachie des windows, oui il peut avoir plusieurs windows dans une page web.

Le parent immédiat :

Si vous êtes dans une iframe et que vous voulez le parent immédiat :

var parentWindow = window.parent

 

 

 

 

javascript

les bases de La bibliothèque moment.js

Pour manipuler les dates en Javascript, ce n’est pas forcément simple, en outre nativement Javascript possède peu de fonction de manipulation de date, d’ou l’intérêt de Moment.js.

Le problème c’est que moment.js sait faire tellement de chose et que la documentation est tellement touffue (voire pas bien foutue) que l’on peine même pour faire les opérations les plus élémentaires.

Ce post se veut comme un aide mémoire pour faire les opérations les plus simples avec les dates.

 

Instanciation d’une date

const t = moment()

génère un objet correspondant à la date et heure actuelle

const t = moment("12-05-1996","MM-DD-YYYY")

 

génère une date mais avec un format passé en second argument, pour être sûr de bien comprendre la date passée en premier argument.

calculer la différence entre deux dates

Pour calculer la différence entre deux objets moment, il faut utiliser la méthode diff (moment.diff() )

const start = moment('2016-11-13','YYYY-MM-DD')

const end = moment('2016-11-11','YYYY-MM-DD')

 

 

 

Calculer la différence en heures

const c = start.diff(end,’hours’)

 

Calculer la durée dans moment

 

MomentJS est plus dédié à la notation de temps à un point donné, mais il est possible de

duration = moment.duration(start.diff(end),’milliseconds’)

javascript

Utiliser NPM Script au lieu de Gulp pour builder

On entends sur le net beaucoup à propos de Grunt ou de Gulp, ces outils vous permettent de compiler du sass en css, de minifier les script css et javascript, de rassembler en un seul fichier etc.

Cependant, il vous est tout à fait possible de faire ce que fait Gulp par exemple rien qu’en utilisant ce qui est disponible avec NPM script.

NPM est le gestionnaire de package sous nodeJS. Il vous permet de télécharger les dépendances nécessaire au fonctionnement de votre application web et du développement de ce dernier.

Voyons voir comment on peut compiler du Sass en CSS en utilisant NPM script.

les scripts NPM sont logés dans le fichier package.json, dans la propriété scripts.

C’est un objet json qui contient des paire clé-valeurs. La clé étant le nom d’un script, et la valeur est la commande NPM que vous auriez tapé en ligne de commande.

Bon assez parlé on y va !

Compiler du Sass en css

c’est la tâche que l’on aura le plus souvent à faire.

Donc je suppose que vous avez déjà installé nodeJS, donc que vous pouvez utiliser NPM.

> npm install node-sass

Ensuite dans l’objet scripts qu’il y a dans le fichier package.json, créez une entrée comme ceici:

"scripts": {
"scss-build": "node-sass --include-path src/scss src/scss/style.scss public/css/style.css",
"watch-scss": "node-sass -w src/scss/ -o public/css/"
},

 

les chemins sont relatifs à l’emplacement du fichier package.json

le premier script « scss-build » va dire à node de compiler le fichier style.scss en style.scss

  1. src/scss est le répertoire source
  2. src/scss/style.scss est le fichier sass à compiler
  3. public/css/style.css est le fhicer cible

Rien qu’avec ce premier script (n’ajoutez pas le second script watch-scss pour l’instant), faite ceci:

> npm run scss-build

 

et voilà !

Passons au second script, comme avez à modifier un grand nombre de fois le fichier sass, vous aurez envie que la compilation se fasse à chaque fois que vous sauvez le fichier sass,

le « watch-scss » va surveiller toute modification du ficheir et va le compiler.

Il suffit donc de lancer non pas le premier script, mais le second script seul.

> npm run watch-scss

 

 

et voilà !

Il y a plus dans les npm scripts que la compilation. On aura envie de minifier le css,minifier le javascript, linter le javascript (linter veut dire vérifier que le code soit aux normes),autopréfixer les propriétés css, et même compresser les images (ce qui est très intéressant !). Le top du top est de pouvoir travailler avec Browsersync quand vous développez en cross browser.

 

 

javascript

Creer un projet avec NPM proprement

Pour un projet web en php pour le backend, et javascript pour le front(en fait vous n’avez pas d’autres choix que le javascript pour le front car c’est le seul langage côté navigateur à l’heure actuelle),

je vais vous montrer comment initier un projet avec NPM.

 

Créez votre répertoire web, entrez-y, et commencez par:

>npm init

Vous aurez une suite de question pour configurer votre application, les paramètres globaux de la solution sera sauvée dans un fichier package.json.

A ce niveau votre fichier json ne contient pas de dépendance vers une quelconque bibliothèque javascript.

On va installer Angular (la dernière version):

> npm install --save angular

 

L’argument save a pour but de sauver la ligne d’installation du module Angular dans el fichier package.json.

Vous faites de même avec les autres librairie (sass, gulp etc), pour savoir ce qu’il faut taper exactement, allez sur le site officiel de NPM, maintenant on va faire une installation d’une autre catégorie de librairies, les dev dependencies. Ce sont les librairies qui sont utilisée seulement en développement mais ne figureront pas dans la version production.

Par exemple je vais installer la librairie de test unitaire Karma, qui est un orchestrateur de tests, et Jasmine qui est la librairie de test unitaire proprement dite.

>npm install --save-dev karma

 

 

Voilà ce que vous aurez comme fichier package.json

{

"name": "monprojet",
"version": "1.0.0",
"description": "monprojet",
"main": "index.php",
"dependencies": {
"angular": "^1.5.8"
},
"devDependencies": {
"karma": "^1.1.2"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Yvon Huynh",
"license": "ISC"

}

Si vous versionnez avec GIT par exemple, vous n’allez pas versionner le répertoire node_modules (le répertoire dans lequel sont entreposés les dépendances). Mais vous allez par contre versionner le fichier package.json. C’est lui qui contient toutes les informations sur les dépendances, si un collègue ou un contributeur désire cloner le projet chez lui, il fera un :

> npm update

pour lancer le processus de chargement des modules npm. Npm va lire le package.json et réinstaller les modules. Comme ça pas de repository Github surchargé par du code non en liaison directement avec votre application.

Retour en haut