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... }
if (Modernizr.localStorage) { // Go! } else { // Polyfill all the things... } MODERNIZR
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 }); });
$("#book").animate({ left: "+=50" }, 5000, function() { // Animation complete. }); ANIMATIONS
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; Hello } animation-name: 'my-animation'; animation-duration: 2s; animation-iteration-count: infinite;
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
<browser-compat ie="9" ff="5" cr="4" sa="4" op="11" /> UN EXEMPLE?
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