jQuery sans jQuery

62
JQUERY SANS JQUERY Raphaël Rougeron / @goldoraf

description

Une immense majorité de développeurs connaissent jQuery, mais pas vraiment JavaScript. Nous verrons comment faire en pur JS ce que vous avez l’habitude de faire avec jQuery et jQuery UI, en mettant l’accent sur le support par les navigateurs des fonctionnalités JS utilisées, et sur les polyfills disponibles.

Transcript of jQuery sans jQuery

Page 1: jQuery sans jQuery

JQUERY SANSJQUERY

Raphaël Rougeron / @goldoraf

Page 2: jQuery sans jQuery

JAVASCRIPT IL Y A 10 ANS

Page 3: jQuery sans jQuery

2006

Page 4: jQuery sans jQuery

JQUERY AUJOURD'HUI

92,2%

Page 5: jQuery sans jQuery
Page 6: jQuery sans jQuery
Page 7: jQuery sans jQuery
Page 8: jQuery sans jQuery
Page 9: jQuery sans jQuery
Page 10: jQuery sans jQuery

POLYFILLINGif ('querySelector' in document && 'localStorage' in window && 'addEventListener' in window) { // Go!} else { // Polyfill all the things...}

Page 11: jQuery sans jQuery
Page 12: jQuery sans jQuery

MODERNIZRif (Modernizr.localStorage) { // Go!} else { // Polyfill all the things...}

Page 13: jQuery sans jQuery
Page 14: jQuery sans jQuery
Page 15: jQuery sans jQuery

PREMIER EXEMPLE$("button.continue").html("Next Step...")

Page 16: jQuery sans jQuery

DOCUMENTgetElementByIdgetElementsByTagNamegetElementsByClassNamequerySelectorquerySelectorAll

Page 17: jQuery sans jQuery

document.querySelector

>= 8 >= 3.5 >= 1 >= 3.2 >= 10

Page 18: jQuery sans jQuery
Page 19: jQuery sans jQuery
Page 20: jQuery sans jQuery

$("button.continue").html("Next Step...");

document.querySelector("button.continue") .innerHTML = "Next Step...";

Page 21: jQuery sans jQuery

Et que se passe t-il si le sélecteur ne correspond à aucunélément ?

$("button.continue").html("Next Step...");

document.querySelector("button.continue") .innerHTML = "Next Step...";

Page 22: jQuery sans jQuery

Uncaught TypeError: Cannot set property 'innerHTML' ofnull

Page 23: jQuery sans jQuery

DEUXIÈME EXEMPLEvar hiddenBox = $("#banner-message");$("#button-container button").on("click", function(event) { hiddenBox.show();});

Page 24: jQuery sans jQuery

addEventListenervar hiddenBox = document.getElementByID("#banner-message");document.querySelector("#button-container button") .addEventListener("click", function(event) { hiddenBox.setAttribute("style", "display: block"); }, false);

Page 25: jQuery sans jQuery

addEventListener

>= 9 >= 1 >= 1 >= 1 >= 7

Page 26: jQuery sans jQuery
Page 27: jQuery sans jQuery

PLUS VERBEUX ?var $ = document.querySelector.bind(document);Element.prototype.on = Element.prototype.addEventListener;

var hiddenBox = $("#banner-message");$("#button-container button").on("click", function(event) { hiddenBox.setAttribute("style", "display: block");});

Page 28: jQuery sans jQuery

Element.classNamehiddenBox.className += ' hidden';

hiddenBox.className.replace('hidden', '');

Page 29: jQuery sans jQuery

Element.classListhiddenBox.classList.add('hidden');hiddenBox.classList.remove('hidden');

var hiddenBox = $("#banner-message");$("#button-container button").on("click", function(event) { hiddenBox.classList.toggle('hidden');});

Page 30: jQuery sans jQuery

Element.classList

>= 10 >= 3.6 >= 8 >= 5.1 >= 11.5

Page 31: jQuery sans jQuery

insertAdjacentHTML$('#box').before('<p>Test</p>');$('#box').after('<p>Test</p>');$('#box').append('<p>Test</p>');$('#box').prepend('<p>Test</p>');

$('#box').insertAdjacentHTML('beforebegin', '<p>Test</p>');$('#box').insertAdjacentHTML('afterend', '<p>Test</p>');$('#box').insertAdjacentHTML('beforeend', '<p>Test</p>');$('#box').insertAdjacentHTML('afterbegin', '<p>Test</p>');

Page 32: jQuery sans jQuery

DocumentFragmentvar tags = ['foo', 'bar', 'baz'], fragment = document.createDocumentFragment();

tags.forEach(function(tag) { var li = document.createElement('li'); li.textContent = tag; fragment.appendChild(li);});

var ul = document.querySelector('ul');ul.appendChild(fragment);

Page 33: jQuery sans jQuery

TABLE APIinsertRow()deleteRow()insertCell()deleteCell()createCaption()deleteCaption()createTHead()...

Page 34: jQuery sans jQuery

TROISIÈME EXEMPLE$.ajax({ url: "/api/getWeather", data: { zipcode: 97201 }, success: function(data) { $("#weather-temp").html("<strong>" + data + "</strong> degrees"); }});

Page 35: jQuery sans jQuery

XMLHttpRequestvar xhr = new XMLHttpRequest(), data = [], rawData = { zipcode: 97201 };for (var k in rawData) { data.push(encodeURIComponent(k) + "=" + encodeURIComponent(rawData[k]));}xhr.open("GET", "/api/getWeather");xhr.onload = function () { document.querySelector("#weather-temp") .innerHTML = "<strong>" + xhr.response + "</strong> degrees";};xhr.send(data.join("&"));

Page 36: jQuery sans jQuery

XMLHttpRequest etFormData

var xhr = new XMLHttpRequest(), data = new FormData(), rawData = { zipcode: 97201 };for (var k in rawData) { data.append(k, JSON.stringify(rawData[k]));}xhr.open("GET", "/api/getWeather");xhr.onload = function () { document.querySelector("#weather-temp") .innerHTML = "<strong>" + xhr.response + "</strong> degrees";};xhr.send(data);

Page 37: jQuery sans jQuery

XMLHttpRequest etFormData

var xhr = new XMLHttpRequest(), data = new FormData(document.querySelector("#zipcode"));

xhr.open("GET", "/api/getWeather");xhr.onload = function () { document.querySelector("#weather-temp") .innerHTML = "<strong>" + xhr.response + "</strong> degrees";};xhr.send(data);

Page 38: jQuery sans jQuery

FormData

>= 10 >= 4 >= 7 >= 12 >= 5

Page 39: jQuery sans jQuery

CALLBACK HELL$('#demo5').animo("rotate", { degrees:90 }, function(e) { e.element.animo( { animation: "flipOutX", keep: true } ); $('#demo6').animo("rotate", { degrees:90 }, function(e) {

e.element.animo( { animation: "flipOutY", keep: true } ); $('#demo7').animo("rotate", { degrees:90 }, function(e) {

e.element.animo( { animation: "flipOutX", keep: true } ); $('#demo8').animo("rotate", { degrees:90 }, function(e){ e.element.animo( { animation: "flipOutY", keep: true } ); }); }); });});

Page 40: jQuery sans jQuery

JQUERY DEFERREDS$.ajax({ url: "/api/getWeather", data: { zipcode: 97201 }}).done(function(data) { $("#weather-temp").html("<strong>" + data + "</strong> degrees");}).fail(function() { alert("error");});

Page 41: jQuery sans jQuery

PROMISES/A+getTweetsFor("goldoraf", function (err, results) { ...});

var promiseForTweets = getTweetsFor("goldoraf");promiseForTweets.then(function(results) { ...});

then(fulfilledHandler, errorHandler, progressHandler)

Page 42: jQuery sans jQuery

PROMISES & XHRfunction request(type, url, data) { return new Promise(function (resolve, reject) { var xhr = new XMLHttpRequest; xhr.addEventListener("error", reject); xhr.addEventListener("load", resolve); xhr.open("GET", url); xhr.send(null); });}

Page 43: jQuery sans jQuery

RÉSULTAT FINALrequest("GET", "/api/getWeather", data).then(function(result) { document.querySelector("#weather-temp") .innerHTML = "<strong>" + result + "</strong> degrees";});

Page 44: jQuery sans jQuery

CALLBACK HELLPROMISE HEAVEN

$('#demo5').animo("rotate", { degrees:90 }).then(function(e) { e.element.animo({ animation: "flipOutX", keep: true }); return $('#demo6').animo("rotate", { degrees:90 });}).then(function(e) { e.element.animo({ animation: "flipOutY", keep: true }); return $('#demo7').animo("rotate", { degrees:90 });}).then(function(e) { e.element.animo({ animation: "flipOutX", keep: true }); return $('#demo8').animo("rotate", { degrees:90 });}).then(function(e){ e.element.animo({ animation: "flipOutY", keep: true });});

Page 45: jQuery sans jQuery

ANIMATIONS$("#book").animate({ left: "+=50"}, 5000, function() { // Animation complete.});

Page 46: jQuery sans jQuery

requestAnimationFrame

>= 10 >= 4 >= 10 >= 6 >= 15

Page 47: jQuery sans jQuery

requestAnimationFramevar start = null, d = document.getElementById("#book");

function step(timestamp) { var progress; if (start === null) start = timestamp; progress = timestamp - start; d.style.left = Math.min(progress/100, 50) + "px"; if (progress < 5000) { requestAnimationFrame(step); }}

requestAnimationFrame(step);

http://www.html5rocks.com/en/tutorials/speed/rendering/

Page 48: jQuery sans jQuery

TRANSITIONS CSS3

Hello

button.foo { font-size: 40px; background: #C9C9C9; transition-property: background; -moz-transition-property: background; -webkit-transition-property: background; -o-transition-property: background; transition-duration: 500ms; -webkit-transition-duration: 500ms;}button.foo:hover { background: #959595; color: #FFF;}

Page 49: jQuery sans jQuery

ANIMATIONS CSS3

Hello

@keyframes 'my-animation' { 0% { background: #C9C9C9; } 50% { background: #61BE50; } 100% { background: #C9C9C9; }}button.bar:hover { background: #959595; color: #FFF; animation-name: 'my-animation'; animation-duration: 2s; animation-iteration-count: infinite;}

Page 50: jQuery sans jQuery

transitionendfunction whichTransitionEvent(el){ var t, transitions = { 'transition':'transitionend', 'OTransition':'oTransitionEnd', 'MozTransition':'transitionend', 'WebkitTransition':'webkitTransitionEnd' }

for (t in transitions) { if (el.style[t] !== undefined) { return transitions[t]; } }}

Page 51: jQuery sans jQuery

transitionendvar transitionEnd = whichTransitionEvent(element);element.addEventListener(transitionEnd, function(event) { // on déclenche l'animation suivante ! element.classList.add('expand');});

Page 52: jQuery sans jQuery
Page 53: jQuery sans jQuery

WEB COMPONENTSUN MODÈLE DE COMPOSANT POUR LE

WEB

Page 54: jQuery sans jQuery

TEMPLATES<template id="commentTemplate"> <div> <img src=""> <div class="comment-text"></div> </div></template>

var tpl = document.querySelector("#commentTemplate");tpl.content.querySelector(".comment-text").innerHTML = ...;document.body.appendChild(tpl.content.cloneNode(true));

Page 55: jQuery sans jQuery

DECORATORS<decorator id="modal-controls"> <template> <section> <header> <a id="toggle" href="#">Maximize</a> <a id="close" href="#">Close</a> </header> <content></content> </section> </template></decorator>

.my-modal { decorator: url(#modal-controls);}

Page 56: jQuery sans jQuery

CUSTOM ELEMENTS<element extends="button" name="my-button" attributes="foo bar"> <template>...</template> <script> </script></element>

...

Page 57: jQuery sans jQuery

SHADOW DOMHTML IMPORTS

<link rel="import" href="my-component.html">

Page 58: jQuery sans jQuery

WEB COMPONENTSAVEC X-TAG

>= 9 >= 5 >= 4 >= 4 >= 11

Page 59: jQuery sans jQuery

UN EXEMPLE ?<browser-compat ie="9" ff="5" cr="4" sa="4" op="11" />

Page 60: jQuery sans jQuery

UN EXEMPLE ?<polymer-element name="browser-compat" attributes="ie ff cr sa op"> <template> <style> </style> <table class="browser-compat"> <tr> <td><img src="images/ie.png" /></td> ... </tr> <tr> <td class="{{ie_class}}">>= {{ie}}</td> ... </tr> </table> </template> <script> </script></polymer-element>

...

...

Page 61: jQuery sans jQuery

UN EXEMPLE ?Polymer('browser-compat', { created: function() { switch(parseInt(this.ie)) { case 10: this.ie_class = 'red'; break; case 9: this.ie_class = 'yellow'; break; default: this.ie_class = 'green'; break; } }});

Page 62: jQuery sans jQuery

CODEZ POUR LE FUTUR !

Copyright Steve Thomas Art & Illustration, LLC