Vincent Garreau
Co-Founder & Front-end developer livestorm.co
Initiation au JavaScript : outils et astuces pour un développement front-end moderne
Lundi 13/11 | Workflow CSS + Les bases du JavaScript |
Mardi 14/11 | Workflow JavaScript / Modules et composants web |
Mercredi 15/11 (1) | Frameworks JavaScript / Initiation à Vue.js |
Mercredi 15/11 (2) | Frameworks JavaScript / Initiation à Vue.js + Consignes TP1 |
Jeudi 16/11 | Correction TP1 + Suite initiation à Vue.js + Consignes TP2 |
Jeudi 7/12 | Correction TP2 + Récapitulatif global du cours |
Les bases du CSS
Préprocesseurs CSS
Postprocesseurs CSS
Méthodologies CSS
Variables
Opérations
Conditions
Boucles
Fonctions
Interaction avec le DOM
Événements
L'objet window
Package managers
Linters JavaScript
Modules et composants web
Systèmes de modules
Module bundlers
Présentation rapide des frameworks JavaScript actuels
Introduction à Vue.js
<style>.element { width: 200px; }</style>
<span style="width:200px"></span>
<link rel="stylesheet" href="style.css">
Terme en anglais : CSS specificity
Terme en français : Poids des sélecteurs
<span style="color: red"> // 1000
#element // 100
.element // 10
span // 1
#element > div > li:hover // 100 + 1 + 1 + 10
.element !important // S'applique en priorité
Style inline
(HTML) |
IDs |
Classes, attributs,
pseudo classes (:) |
Elements,
pseudo elements (::) |
---|---|---|---|
1000 | 100 | 10 | 1 |
.button-push { padding: 10px; }
<button class="button-push">Push 1</button>
<button class="button-push">Push 2</button>
D'après les standards W3C
Un préprocesseur CSS contient une palette d'outils qui permet d'écrire un CSS plus maintenable
// CSS
.element {
width: 200px;
height: 80px;
font-size: 1.2em;
}
// Stylus ({}, : et ; sont chacun optionnel)
.element
width 200px
height 80px
font-size 1.2em
Léger et rapide à écrire
// CSS
.element > li { padding:10px; }
.element > li:hover { padding:20px; }
// Stylus
.element
> li
padding 10px
&:hover
padding 20px
Principe d'indentation (évitez plus de 3 niveaux)
// Sans préprocesseur
.element
width 20px
height 20px
margin-right 10px
// Avec préprocesseur
$element-size = 20px
.element
width $element-size
height $element-size
margin-right $element-size / 2 // Opération
Mixins
Fonctions
Opérateurs
Conditions
Itérations
@extend
@block
....
Un postprocesseur CSS est un outil qui permet d'effectuer
des tâches spécifiques sur un fichier CSS
PostCSS est un outil JavaScript qui permet d'effectuer des transformations d'un fichier CSS grâce à des plugins
Plugins PostCSS populaires :
autoprefixer : préfixe les propriétés
cssnext : permet d'écrire dès aujourd'hui du CSS4
Ensemble de conseils et de lignes de conduite
pour un CSS organisé et maintenable
Avantage d'un préprocesseur CSS :
Pouvoir générer un fichier CSS
à partir de plusieurs fichiers
Remarque
Sans préprocesseur, il est possible d'importer plusieurs fichiers CSS avec la méthode @import, mais cela est lourd car sans préprocesseur aucun fichier n'est généré.
Sans préprocesseur, 1 import = 1 requête HTTP en plus.
7-1 Pattern
7 dossiers, 1 fichier
Détails sur sass-guidelin.es/#the-7-1-pattern
📁 base
📁 components
📁 layout
📁 pages
📁 themes
📁 abstracts
📁 vendors
main.scss
Permet d' éviter des cas problématiques comme écraser du style précédemment appliqué / mélanger des styles
Si plusieurs développeurs travaillent sur un même projet, appliquer une règle de nommage commune est plus facile à comprendre / lire et à maintenir
OOCSS
Object-Oriented CSS
SMACSS
Scalable and Modular Approach for CSS
BEM
Block Element Modifier
// block-name__element-name--modifier-name
<header class="app-header">
<nav class="app-header-nav">
<ul>
<li class="app-header-nav__item"></li>
<li class="app-header-nav__item app-header-nav__item--on"></li>
</ul>
</nav>
</header>
<script>
console.log('Hello World')
</script>
<script src="app.js"></script>
// ES5 : var
var foo = 'bar'
// ES6 : let ou const
let foo = 'bar'
const foo = 'bar'
// Global (à éviter)
foo = 'bar'
window.foo = 'bar'
let age = 21
const firstname = 'Marie'
const identity = {}
age = 22 // let donc OK
firstname = 'Elodie' // const donc ERREUR
identity = { firstname: 'Marie' } // ERREUR
identity.firstname = 'Marie' // OK
const company = 'Apple'
// Anciennement var (ES5)
if (company === 'Apple') {
var founder = 'Steve Jobs'
}
console.log(founder) // Steve Jobs
// Avec let (ES6)
if (company === 'Apple') {
let founder = 'Steve Jobs'
console.log(founder) // 'Steve Jobs'
}
console.log(founder) // Error not defined
// Anciennement var (ES5)
for (var i = 0; i <= 10; i++) {
console.log(i) // 0 à 10
}
console.log(i) // 11
// Avec let (ES6)
for (let i = 0; i <= 10; i++) {
console.log(i) // 0 à 10
}
console.log(i) // Error not defined
// Camel case
const myAwesomeFoo = 'bar'
// Snake case
const my_awesome_foo = 'bar'
// Pascal case
const MyAwesomeFoo = 'bar'
// Kebab case
const my-awesome-foo = 'bar' // ⚠️ ERREUR
// D'autres conventions existent...
String | "Hello World" |
---|---|
Number | 4 4.847 |
Boolean | true false |
Array | ["Hello", "World"] |
Object | { id: "Hello World" } |
Function | () => { return 'Hello World' } |
const foo = 'Hello'
const bar = ['Hello']
console.log(typeof(foo))
// Output: "string"
console.log(typeof(bar))
// Output: "object"
console.log(Array.isArray(bar))
// Output: true
D'autres types existent ; ceux présentés ci-dessus sont les plus courants
typeof n'est pas un outil fiable
const foo = ['Hello']
foo.push('World')
// Create - ['Hello', 'World']
foo[1] = 'Man'
// Update - ['Hello', 'Man']
foo.splice(0, 1)
// Delete - ['Man']
const foo = {
title: 'Hello World',
tagline: 'Awesome tagline'
}
// Create
foo.image = 'hello-world.jpg'
// Update
foo.title = 'Hello Man'
Type | Exemple |
---|---|
Opérateurs arithmétiques | x + y, x / y |
Opérateurs d'affectation | x = y, x += y |
Opérateurs de comparaison | x === y, x >= y |
Opérateurs logiques | x && y, x || y |
Opérateurs de chaînes de caractères | 'Hello' + 'World' |
Opérateur conditionnel ternaire | x === y ? 'yes' : 'no' |
Opérateurs unaires | typeof(x) |
D'autres types d'opérateurs existent, ceux présentés ci-dessus sont les plus courants
Math.abs(-4.8)
// 4.8
Math.floor(4.8)
// 4
Math.ceil (4.8)
// 5
Math.round(4.8)
// 5
Math.random()
// 0.7628140805056463
// Entre 0 et 1
const year = '2021'
// ES5
const bar = 'La P' + year + 'est au top'
// ES6
const foo = `La P${year} est au top`
const foo = `La P${2000 + 21} est au top`
// La P2021 est au top
const foo = 2017
let output
if (foo < 2021) {
output = 'if'
} else if (foo === 2017) {
output = 'else if'
} else {
output ='else'
}
console.log(output) // 'if'
const foo = 2015
let output
switch (foo) {
case 2017:
output = 'Hello 2017'
break
case 2016:
case 2015:
output = 'Hello 2015 / 2016'
break
default:
output ='default'
}
console.log(output) // 'Hello 2015 / 2016'
const foo = '2017'
let output
if (foo == 2017) {
output = 'if'
} else {
output = 'else'
}
console.log(output) // 'if'
let output
if (foo === 2017) {
output = 'if'
} else {
output = 'else'
}
console.log(output) // 'else'
== | valeur |
=== | valeur + type |
const foo = true
const bar = false
// Au lieu de :
if (foo === true) { ... }
// On peut faire :
if (foo) { ... }
// Au lieu de :
if (bar === false) { ... }
// On peut faire :
if (!bar) { ... }
const foo = 'Hello'
const bar = 2017
if (foo === 'Hello' && (bar <= 2000 || bar === 2017)) {
console.log('ok')
} else {
console.log('fail')
}
// 'ok'
&& | et |
|| | ou |
for (let i = 0; i <= 10; i++) {
console.log(i) // 0 à 10
}
for (let i = 10; i >= 0; i--) {
console.log(i) // 10 à 0
}
for (let i = 0; i <= 10; i += 5) {
console.log(i) // 0, 5, 10
}
let i = 0 | Initialisation |
i <= 10 | Condition |
i++ | Incrémentation |
i-- | Décrémentation |
console.log(i) | Instruction |
const foo = [
{ title: 'Hello' },
{ title: 'World' }
]
for (let i = 0; i < foo.length; i++) {
console.log(foo[i].title) // 'Hello', 'World'
}
let year = 2000
while (year <= 2017) {
console.log(year)
year++
}
// Function declaration
function myFunction (x, y) {
return x + y
}
// Function expression
const myFunction = function (x, y) {
return x + y
}
// Function expression - Arrow function (Fonctions fléchées, ES6)
const myFunction = (x, y) => {
return x + y
}
x, y | Paramètres |
const addition = function (x, y) {
return x + y
console.log('Not display')
}
const sum = addition(10, 5)
console.log(sum) // 15
Tout ce qui se trouve après return est ignoré
let obj = {
bar: () => {
return this
}
}
console.log(obj.bar()) // window
let obj = {
bar: function () {
return this
}
}
console.log(obj.bar()) // obj
document.getElementById('foo')
document.getElementsByClassName('foo')
document.getElementsByTagName('header')
document.querySelector('#foo')
document.querySelectorAll('.foo')
document.querySelectorAll('header')
const foo = document.querySelector('#foo')
foo.setAttribute('data-value', 'bar')
foo.getAttribute('data-value')
foo.removeAttribute('data-value')
const foo = document.querySelector('#foo')
foo.style.color('#FF0000')
foo.style.backgroundColor('#000')
foo.style.width = '100px'
const foo = document.querySelector('#foo')
foo.classList.add('foo')
foo.classList.add('foo', 'bar')
foo.classList.remove('foo')
foo.classList.contains('foo')
const foo = document.querySelector('#foo')
foo.innerText = 'bar'
foo.inneHTML = '<span>bar</span>'
// Créer un élément span et lui appliquer un id
const foo = document.createElement('span')
foo.id = 'bar'
// Ajouter cet element dans le DOM, au sein et à la fin de #main-header
document.querySelector('#main-header').appendChild(foo)
// Supprimer cet élément
document.querySelector('#bar').remove()
// Récupérer un élément du DOM
const foo = document.querySelector('#foo')
// Écouter l'événement "click"
foo.onclick = (event) => {
// Callback
console.log('click', event)
}
// Écouter l'événement "onmouseenter"
foo.onmouseenter = (event) => {
console.log('mouse enter', event)
}
// Récupérer un élément du DOM
const foo = document.querySelector('input[type="checkbox"]')
// Écouter l'événement "click"
foo.onclick = (event) => {
console.log('click', event)
event.preventDefault()
}
const foo = document.querySelector('#foo')
const bar = document.querySelector('#bar')
// click : on peut écouter un seul événement click
foo.onclick = (event) => {
console.log('click', event)
}
// addEventListener : on peut écouter 2 événements click
bar.addEventListener('click', (event) => {
console.log('click 2', event)
})
bar.addEventListener('click', (event) => {
console.log('click 1', event)
})
const foo = document.querySelector('#foo')
// Callback function
const callbackClick = () => {
console.log('click')
}
// addEventListener
foo.addEventListener('click', callbackClick)
// removeEventListener
foo.removeEventListener('click', callbackClick)
history | Historique de navigation |
localStorage | Stockage de données |
location | Données sur l'url d'une page |
navigator | Données sur le navigateur |
screen | Données sur l'écran |
scrollX, scrollY | Valeurs du scroll horizontal / vertical |
innerWidth, innerHeight | Taille de la fenêtre |
alert / prompt | Afficher une modal |
focus / blur | Focus / blur sur un input / un select |
setTimeout / setInterval | Exécuter des instructions après un certain délai |
scrollTo | Scroller à une certaine valeur |
open | Ouvrir une nouvelle fenêtre / tab du navigateur |
// Afficher une modal après 3 sec.
setTimeout(() => {
alert('Hello Modal')
}, 3000)
Gestion des librairies / plugins via un
gestionnaire de paquets
// package.json
{
"name": "my-portfolio-package",
"version": "1.0.0",
"dependencies": {
"jquery": "^2.2.3"
}
}
// Commande pour installer le package jquery par exemple :
yarn add jquery
Outil pour garder un code JS lisible, cohérent et harmonieux
Plugins
C'est quoi ? Pourquoi ?
Consiste à utiliser une
approche modulaire de l'architecture d'un projet informatique
Concept appliqué au
Javascript
Plus large qu'un module :
Template HTML + Javascript + Style CSS
Différents systèmes pour créer des modules Javascript
AMD
CommonJS
ES2015 Modules
// operators.js
define([], function () {
return {
sum: function (a, b) {
return a + b
},
divide: function (a, b) {
return a / b
}
}
})
// app.js
define(["./operators.js"], function (operators) {
var test = operators.sum(10, 5) // 15
})
Asynchronous Module Definition
// operators.js
exports.sum = function (a, b) {
return a + b
}
exports.divide = function (a, b) {
return a / b
}
// app.js
var operators = require('./operators.js')
var test = operators.sum(10, 5) // 15
// operators.js
const myObject = {}
myObject.sum = (a, b) => {
return a + b
}
myObject.divide = (a, b) => {
return a / b
}
export default myObject
// app.js
import operators from './operators.js'
const test = operators.sum(10, 5) // 15
Un outil qui analyse les modules pour générer des assets
Grafikart - Lien du tutoriel
module.exports = {
// Points d'entrée
entry: './assets/js/main.js',
// Configuration de l'export
output: {
path: './build/js',
filename: "main.js"
},
// Configuration des loaders
module: {
rules: [
{ test: /\.css$/, loader: "style-loader!css-loader" },
]
},
// Configuration des plugins
plugins: []
}
Un outil tout en un pour créer une application maintenable
2010
2011
2011
2013
2009
2013
2014
Jeremy Ashkenas
Yehuda Katz
Meteor
Evan You
Facile à prendre en main
Développement rapide
Un écosystème flexible grâce aux différents plugins Vue
Mises à jour régulières
Communauté active
By Vincent Garreau
Initiation au JavaScript