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