jQuery sans jQuery

Preview:

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.

Citation preview

JQUERY SANSJQUERY

Raphaël Rougeron / @goldoraf

JAVASCRIPT IL Y A 10 ANS

2006

JQUERY AUJOURD'HUI

92,2%

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

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

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

DOCUMENTgetElementByIdgetElementsByTagNamegetElementsByClassNamequerySelectorquerySelectorAll

document.querySelector

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

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

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

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...";

Uncaught TypeError: Cannot set property 'innerHTML' ofnull

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

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

addEventListener

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

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");});

Element.classNamehiddenBox.className += ' hidden';

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

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

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

Element.classList

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

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>');

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);

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

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

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("&"));

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);

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);

FormData

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

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 } ); }); }); });});

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

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

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

then(fulfilledHandler, errorHandler, progressHandler)

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); });}

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

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 });});

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

requestAnimationFrame

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

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/

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;}

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;}

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]; } }}

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

WEB COMPONENTSUN MODÈLE DE COMPOSANT POUR LE

WEB

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));

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);}

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

...

SHADOW DOMHTML IMPORTS

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

WEB COMPONENTSAVEC X-TAG

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

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

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>

...

...

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; } }});

CODEZ POUR LE FUTUR !

Copyright Steve Thomas Art & Illustration, LLC

Recommended