Upload
nicholas-zakas
View
25.897
Download
3
Tags:
Embed Size (px)
Citation preview
JavaScript APIs You’ve Never Heard Of
(And some you have)
Nicholas C. Zakas@slicknet
Who’s this guy?
flickr.com/photos/vbillings/172124448/
HTML5, DOM4 &…DOM Level 2!
<ul id=“mylist”> <li>Item 1</li> <li>Item 1</li> <li>Item 1</li></ul>
UL
LI LI LI#text #text#text #text
children
<ul id=“mylist”> <li>Item 1</li> <li>Item 1</li> <li>Item 1</li></ul>
var list = document.getElementById(“mylist”);
console.log(list.childNodes.length); //7console.log(list.children.length); //3
DOM4HTMLCollection of all child nodes that are elements
No
vendo
r
prefix!
children
<ul id=“mylist”> <li>Item 1</li> <li>Item 1</li> <li>Item 1</li></ul>
var list = document.getElementById(“mylist”), node1 = list.childNodes[0], child1 = list.children[0];
console.log(node1.nodeName); //”#text”console.log(child1.nodeName); //”LI”
DOM4HTMLCollection of all child nodes that are elements
No
vendo
r
prefix!
children
<ul id=“mylist”> <!-- comment --> <li>Item 1</li> <li>Item 1</li> <li>Item 1</li></ul>
var list = document.getElementById(“mylist”), node1 = list.childNodes[0], child1 = list.children[0];
console.log(node1.nodeName); //”#text”console.log(child1.nodeName); //”#comment”
DOM4HTMLCollection of all child nodes that are elements
BUG!
IE 6-8 includes comments in the
children collection
Element Traversal APIDefines new properties for accessing element children
UL
LI LI LI#text #text#text #text
lastChildfirstChild
Element Traversal APIDefines new properties for accessing element children
UL
LI LI LI#text #text#text #text
lastElementChildfirstElementChild
9
No
vendo
r
prefix!
firstElementChild
<ul id=“mylist”> <li>Item 1</li> <li>Item 1</li> <li>Item 1</li></ul>
var list = document.getElementById(“mylist”), node1 = list.firstChild, child1 = list.firstElementChild;
console.log(node1.nodeName); //”#text”console.log(child1.nodeName); //”LI”
Element Traversal API & DOM4Point to first child node that is an element
9
No
vendo
r
prefix!
lastElementChild
<ul id=“mylist”> <li>Item 1</li> <li>Item 1</li> <li>Item 1</li></ul>
var list = document.getElementById(“mylist”), node1= list.lastChild, child= list.lastElementChild;
console.log(node1.nodeName); //”#text”console.log(child1.nodeName); //”LI”
Element Traversal API & DOM4Point to last child node that is an element
9
No
vendo
r
prefix!
Element Traversal APIDefines new properties for accessing element children
LI LI#text
nextSibling
9
Element Traversal APIDefines new properties for accessing element children
LI LI#text
nextElementSibling
9
Element Traversal APIDefines new properties for accessing element children
LI LI#text
previousSibling
9
Element Traversal APIDefines new properties for accessing element children
LI LI#text
previousElementSibling
9
// iterate over element childrenvar child = element.firstElementChild;
while(child) { process(child); child = child.nextElementSibling;}
9
Element Traversal APIDefines new properties for accessing element children
No
vendo
r
prefix!
contains()
var element = document.getElementById(“foo”);
if (document.body.contains(element)) { //do something}
function isAncestor(child, maybeAncestor) { return maybeAncestor.contains(child);}
// useful for event delegationif (isAncestor(event.target, list)) { // do something}
DOM4Determines if a given element is an ancestor of another
No
vendo
r
prefix!
insertAdjacentHTML()
element.insertAdjacentHTML(location, html);
HTML5Insert an HTML string into the DOM at a specific place
“beforebegin”“afterbegin”“beforeend”“afterend”
Any valid HTML string
No
vendo
r
prefix!
insertAdjacentHTML()
<nav> <h2>Site Menu</h2> <ul id="menu"> <li><a href="/">Home</a></li> <li><a href="/about">About</a></li> </ul></nav>
var menu = document.getElementById("menu");
HTML5Insert an HTML string into the DOM at a specific place
No
vendo
r
prefix!
insertAdjacentHTML()
<nav> <h2>Site Menu</h2> <p>Hello world!</p> <ul id="menu"> <li><a href="/">Home</a></li> <li><a href="/about">About</a></li> </ul></nav>
var menu = document.getElementById("menu");menu.insertAdjacentHTML("beforebegin", "<p>Hello world!</p>");
HTML5Insert an HTML string into the DOM at a specific place
No
vendo
r
prefix!
insertAdjacentHTML()
<nav> <h2>Site Menu</h2> <ul id="menu"> <li>Hello world!</li> <li><a href="/">Home</a></li> <li><a href="/about">About</a></li> </ul></nav>
var menu = document.getElementById("menu");menu.insertAdjacentHTML(“afterbegin", "<li>Hello world!</li>");
HTML5Insert an HTML string into the DOM at a specific place
No
vendo
r
prefix!
insertAdjacentHTML()
<nav> <h2>Site Menu</h2> <ul id="menu"> <li><a href="/">Home</a></li> <li><a href="/about">About</a></li> <li>Hello world!</li> </ul></nav>
var menu = document.getElementById("menu");menu.insertAdjacentHTML(“beforeend", "<li>Hello world!</li>");
HTML5Insert an HTML string into the DOM at a specific place
No
vendo
r
prefix!
insertAdjacentHTML()
<nav> <h2>Site Menu</h2> <ul id="menu"> <li><a href="/">Home</a></li> <li><a href="/about">About</a></li> </ul> <p>Hello world!</p></nav>
var menu = document.getElementById("menu");menu.insertAdjacentHTML(“afterend", "<p>Hello world!</p>");
HTML5Insert an HTML string into the DOM at a specific place
No
vendo
r
prefix!
insertAdjacentHTML()HTML5Insert an HTML string into the DOM at a specific place
No
vendo
r
prefix!
http://jsperf.com/insertadjacenthtml-perf/4
In many cases, faster than innerHTML!
outerHTML
element.outerHTML = html;
HTML5Get/set HTML for an entire element
Any valid HTML string
No
vendo
r
prefix!
outerHTML
<nav> <h2>Site Menu</h2> <ul id="menu"> <li><a href="/">Home</a></li> <li><a href="/about">About</a></li> </ul></nav>
var menu = document.getElementById("menu");var html = menu.outerHTML;
HTML5Get/set HTML for an entire element
No
vendo
r
prefix!
outerHTML
<nav> <h2>Site Menu</h2> <p>Hello world!</p></nav>
var menu = document.getElementById("menu");menu.outerHTML = "<p>Hello world!</p>";
console.log(menu.tagName); // “UL”console.log(menu.parentNode); // null
HTML5Get/set HTML for an entire element
No
vendo
r
prefix!
Detached reference to
<ul>
createHTMLDocument()
document.implementation.createHTMLDocument(title);
DOM Level 2Create an invisible document
No
vendo
r
prefix!
9
Title of the document
createHTMLDocument()
var doc = document.implementation.createHTMLDocument(“Test”);
console.log(doc.title); // “Test”
doc.body.innerHTML = “<p>Hello world!</p>”;var p = document.querySelector(“p”);
console.log(p.textContent); // “Hello world!”
DOM Level 2Create an invisible document
No
vendo
r
prefix!
9
createHTMLDocument()
function isSafeHTML(html) { var doc = document.implementation.createHTMLDocument(“Test”); doc.body.innerHTML = html;
return !doc.querySelector(“script,style,link,object”);}
DOM Level 2Create an invisible document
No
vendo
r
prefix!
9
createHTMLDocument()
function sanitizeHTML(html) { var doc = document.implementation.createHTMLDocument(“Test”); doc.body.innerHTML = html;
var nodes = doc.querySelectorAll(“script,style,link,object”);
for (var i=0, len=nodes.length; i < len; i++) { nodes[i].parentNode.removeChild(nodes[i]); }
return doc.body.innerHTML;}
DOM Level 2Create an invisible document
No
vendo
r
prefix!
9
setSelectionRange()HTML5Select specific parts of textbox content
No
vendo
r
prefix!
<input value="data" id="data-field">
var textbox = document.getElementById("data-field");textbox.focus();
textbox.select();
textbox.setSelectionRange(1, 3);
9
setSelectionRange()HTML5Select specific parts of textbox content
No
vendo
r
prefix!
// put caret at starttextbox.setSelectionRange(0, 0);
// put caret at endtextbox.setSelectionRange( textbox.value.length, textbox.value.length);
9
selectionStart/selectionEndHTML5Set/get the start and ending range of selection
No
vendo
r
prefix!
<input value="data" id="data-field">
var textbox = document.getElementById("data-field");textbox.focus();textbox.setSelectionRange(1, 3);
console.log(textbox.selectionStart); // 1console.log(textbox.selectionEnd); // 3
9
activeElementHTML5Returns the element that currently has focus
No
vendo
r
prefix!
<input value="data" id="data-field">
var textbox = document.getElementById("data-field");textbox.focus();
var focused = document.activeElement;console.log(focused === textbox); // true
XMLHttpRequest Level 2
FormData
var data = new FormData();
data.append(“name”, “Nicholas”);data.append(“age”, 25);data.append(“note”, “Yeah right!”);
var xhr = new XMLHttpRequest();xhr.open(“post”, “/submit”, true);
//setup event handlers
xhr.send(data);
XMLHttpRequest Level 2Used to submit <form> data via XMLHttpRequest
103
No
vendo
r
prefix!
FormData
var data = new FormData(document.forms[0]);
var xhr = new XMLHttpRequest();xhr.open(“post”, “/submit”, true);
//setup event handlers
xhr.send(data);
XMLHttpRequest Level 2Used to submit <form> data via XMLHttpRequest
103
No
vendo
r
prefix!
FormData
<input type="file" id="photo" name="photo">
var data = new FormData(), fileControl = document.getElementById("photo");
data.append(“name”, “Nicholas”);data.append(“photo”, fileControl.files[0]);
var xhr = new XMLHttpRequest();xhr.open(“post”, “/submit”, true);
//setup event handlers
xhr.send(data);
XMLHttpRequest Level 2Used to submit <form> data via XMLHttpRequest
103
No
vendo
r
prefix!
Upload Progress
var xhr = new XMLHttpRequest();xhr.open(“post”, “/submit”, true);
xhr.upload.onprogress = function(event) { var percentage = event.loaded/event.total * 100; updateProgress(percentage);};
xhr.send(data);
XMLHttpRequest Level 2Monitor the time to upload
103
No
vendo
r
prefix!
XHR Timeouts
var xhr = new XMLHttpRequest();xhr.open(“get”, “/data”, true);
xhr.timeout = 5000;xhr.ontimeout = function() { console.log(“Request timed out.”);};
// other event handlers
xhr.send(data);
XMLHttpRequest Level 2Used to stop a request after a period of time
93
No
vendo
r
prefix!
XHR Response TypesXMLHttpRequest Level 2Retrieve a particular type of object – not just text!
var xhr = new XMLHttpRequest();xhr.open(“get”, “/data”, true);
xhr.onload = function() { var text = xhr.responseText; doSomethingWith(text);};
// other event handlers
xhr.send();
No
vendo
r
prefix!
XHR Response TypesXMLHttpRequest Level 2Retrieve a particular type of object – not just text!
var xhr = new XMLHttpRequest();xhr.open(“get”, “/data”, true);
xhr.onload = function() { var xmldoc = xhr.responseXML; doSomethingWith(xmldoc);};
// other event handlers
xhr.send();
No
vendo
r
prefix!
XHR Response TypesXMLHttpRequest Level 2Retrieve a particular type of object – not just text!
10
var xhr = new XMLHttpRequest();xhr.open(“get”, “/data”, true);
xhr.responseType = "text";
xhr.onload = function() { var text = xhr.response; doSomethingWith(text);};
// other event handlers
xhr.send();
3
No
vendo
r
prefix!
XHR Response TypesXMLHttpRequest Level 2Retrieve a particular type of object – not just text!
10
var xhr = new XMLHttpRequest();xhr.open(“get”, “/data”, true);
xhr.responseType = "document";
xhr.onload = function() { var xmldoc = xhr.response; doSomethingWith(xmldoc);};
// other event handlers
xhr.send();
3
No
vendo
r
prefix!
XHR Response TypesXMLHttpRequest Level 2Retrieve a particular type of object – not just text!
10
var xhr = new XMLHttpRequest();xhr.open(“get”, “/data”, true);
xhr.responseType = "blob";
xhr.onload = function() { var blob = xhr.response; doSomethingWith(blob);};
// other event handlers
xhr.send();
Great for downloading
images!
3
No
vendo
r
prefix!
XHR Response TypesXMLHttpRequest Level 2Retrieve a particular type of object – not just text!
10
var xhr = new XMLHttpRequest();xhr.open(“get”, “/data”, true);
xhr.responseType = "arraybuffer";
xhr.onload = function() { var binData = new Uint16Array(xhr.response); doSomethingWith(binData);};
// other event handlers
xhr.send();
Great for downloading binary data!
3
No
vendo
r
prefix!
XHR Response TypesXMLHttpRequest Level 2Retrieve a particular type of object – not just text!
var xhr = new XMLHttpRequest();xhr.open(“get”, “/data”, true);
xhr.responseType = "json";
xhr.onload = function() { var json = xhr.response; doSomethingWith(json);};
// other event handlers
xhr.send();
Future
CSS in JavaScript
matchesSelector()
var element = document.getElementById(“foo”);
if (element.matchesSelector(“#foo”)) { //do something}
if (element.matchesSelector(“body .bar”)) { //do something}
Selector API Level 2Determines if the element matches a certain CSS selector
93
matchesSelector()
element.mozMatchesSelector()
element.webkitMatchesSelector()
element.msMatchesSelector()
element.oMatchesSelector()
Selector API Level 2Determines if the element matches a certain CSS selector
matches ()
var element = document.getElementById(“foo”);
if (element.matches(“#foo”)) { //do something}
if (element.matches(“.bar”, element.parentNode)) { //do something}
Selector API Level 2Determines if the element matches a certain CSS selector
Future
getBoundingClientRect()CSS Object Model ViewsDetermines size and location of an element in the viewport
Hello!
getBoundingClientRect()CSS Object Model ViewsDetermines size and location of an element in the viewport
var rect = element.getBoundingClientRect();
// all measurements in pixels relative to viewportconsole.log(rect.left);console.log(rect.top);console.log(rect.right); // relative to left console.log(rect.bottom); // relative to top
console.log(rect.width);console.log(rect.height);
No
vendo
r
prefix!
getBoundingClientRect()CSS Object Model ViewsDetermines size and location of an element in the viewport
var rect = element.getBoundingClientRect();
// all measurements in pixels relative to viewportconsole.log(rect.left);console.log(rect.top);console.log(rect.right); // relative to left console.log(rect.bottom); // relative to top
console.log(rect.width);console.log(rect.height);
BUG!
IE < 8 adds 2 to each coordinate – you must
subtract it
elementFromPoint()
var element = document.elementFromPoint(x, y);
CSS Object Model ViewsReturn the element at a position relative to viewport
Think clientX and clientY
No
vendo
r
prefix!
Element at that point with highest
z-index
elementFromPoint()
var element = document.elementFromPoint(x, y);
CSS Object Model ViewsReturn the element at a position relative to viewport
Think clientX and clientY
No
vendo
r
prefix!
Element at that point with highest
z-index
matchMedia()
var mql = window.matchMedia(“(max-width:600px)”);
if (mql.matches) { //do something}
mql.addListener(function(mql) {
console.log(mql.media + “ “ + (mql.matches ? “matches” : “doesn’t match”);
});
CSS Object Model ViewsAllows JavaScript to interact with CSS media queries
10
No
vendo
r
prefix!
Review
What We Talked About
• Element Traversal API• element.children• element.contains()• element.insertAdjacentHTML()• element.outerHTML• document.activeElement• document.implementation.createHTMLDocument()• element.setSelectionRange()• element.selectionStart• element.selectionEnd
What We Talked About
• FormData• Upload Progress• XHR Timeouts• XHR Response Types• element.matchesSelector()• element.getBoundingClientRect()• document.elementFromPoint()• window.matchMedia()
The End
Etcetera
My blog: nczonline.net
Twitter: @slicknet
These Slides: slideshare.net/nzakas