jquery sans jquery
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
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