JQUERY SANS JQUERY
Transcription
JQUERY SANS JQUERY
JQUERY SANS JQUERY Raphaël Rougeron / @goldoraf JAVASCRIPT IL Y A 10 ANS 2006 JQUERY AUJOURD'HUI 92,2% POLYFILLING if ('querySelector' in document && 'localStorage' in window && 'addEventListener' in window) { // Go! } else { // Polyfill all the things... } MODERNIZR if (Modernizr.localStorage) { // Go! } else { // Polyfill all the things... } PREMIER EXEMPLE $("button.continue").html("Next Step...") DOCUMENT getElementById getElementsByTagName getElementsByClassName querySelector querySelectorAll document.querySelector >= 8 >= 3.5 >= 1 >= 3.2 >= 10 $("button.continue").html("Next Step..."); document.querySelector("button.continue") .innerHTML = "Next Step..."; $("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 ? Uncaught TypeError: Cannot set property 'innerHTML' of null DEUXIÈME EXEMPLE var hiddenBox = $("#banner-message"); $("#button-container button").on("click", function(event) { hiddenBox.show(); }); addEventListener var 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.className hiddenBox.className += ' hidden'; hiddenBox.className.replace('hidden', ''); Element.classList hiddenBox.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>'); DocumentFragment var 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 API insertRow() 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"); } }); XMLHttpRequest var 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 et FormData 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 et FormData 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 & XHR function 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 FINAL request("GET", "/api/getWeather", data) .then(function(result) { document.querySelector("#weather-temp") .innerHTML = "<strong>" + result + "</strong> degrees"; }); CALLBACK HELL PROMISE 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 requestAnimationFrame var 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 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; } Hello ANIMATIONS CSS3 @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; Hello transitionend function 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]; } } transitionend var transitionEnd = whichTransitionEvent(element); element.addEventListener(transitionEnd, function(event) { // on déclenche l'animation suivante ! element.classList.add('expand'); }); WEB COMPONENTS UN 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 DOM HTML IMPORTS <link rel="import" href="my-component.html"> WEB COMPONENTS AVEC 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