single web page • Fluid UX, like desktop app • Examples like Gmail, Google maps • Html page contains mini-views (HTML Fragments) that can be loaded in the background • No reloading of the page, better UX • Requires handling of browser history, navigation and bookmarks
Usually we use some framework for this • ECMAScript is a scripting language, standardized by Ecma International • In Browsers, ECMAScript is commonly called JavaScript • JavaScript = Native (EcmaScript) + Host objects (browser)
the Web • Hypertext Transfer Protocol • Delivers resources on the WWW • Usually delivered by TCP/IP • HTTP client sends a request to HTTP server • Default port is 80 • Resource can be a file or dynamically generated query result
Format • an initial line, • zero or more header lines, • a blank line, • optional message body (this is the resource) • Example <initial line, different for request and response> Header1: value1 Header2: value2 <optional message body>
the request than response. • Request line has three parts • method name, local path to resource, version of http • Example • GET /path/to/file/index.html HTTP/1.0 • Method name can be GET, POST, PUT, DELETE...
the status line • Typical status lines • HTTP/1.0 200 OK • HTTP/1.0 404 Not Found • Status code (200, 404) is computer-readable, reason phrase is human-readable • Status codes • 1xx, information message • 2xx, success • 3xx, redirect • 4xx, client error • 5xx, server error • See all status codes • http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
and response • Header-name: value • HTTP 1.0 provides 16 headers, HTTP 1.1 provides 46 headers • For example client should tell who is making the request • User-Agent: ... • Server should identify • Server: ...
localhost:8080 User-Agent: curl/7.49.1 Accept: */* Content-type: text/plain Content-Length: 9 Some data HTTP/1.1 200 OK Server: GlassFish Server Open Source Edition 4.1.1 X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 4.1.1 Java/Oracle Corporation/1.8) Content-Type: text/plain;charset=ISO-8859-1 Date: Tue, 10 Jan 2017 10:39:58 GMT Content-Length: 9 Some data
objects exposed by web browser • There is no standard implementation and no strict definition • Browser vendors are free to implement BOM • In Browsers, you use EcmaScript + Host Objects • Host Objects are • BOM (Browser object model) • DOM (Document object model) • DOM has strict definition from W3C / WHATWG
• Mouse click (onclick) • Web page loading (onload) • Mousing over and out (onmouseover, onmouseout) • Submitting HTML form (onsubmit) • Key handling, web page completing, user scrolling or resizing …
• <a href="http://www.opera.com/" onclick="alert('Hello')">Say hello</a> • DOM Level 2 (W3C) • document.getElementById("my-link").addEventListener("click", myFunction, false); • Microsoft (IE) did not follow the W3C model until IE8. IE11 deletes its support for MS model
and language- independent convention for interacting with objects in HTML and in XML. • With DOM you can manipulate html/xml document! Dynamic html! • Public interface available: http://www.w3.org/DOM/DOMTR
Intermediate DOM ) • Not W3C Standards, used in Netscape 2 (Level 0) and Netscape 4 (Intermediate DOM) • DOM Level 1 • 1998: Ability to change entire HTML or XML document • Core and HTML specifications • Level of support: excellent • DOM Level 2 • 2001: Introduces “getElementById” function, event model and support for XML namespaces • Core, Views, Events, Style, Traversal and Range, HTML • Level of Support: good • DOM Level 3 • 2004: XPath, focus on keyboard event handling • Core, Load, Save, Validation, Events, XPath
You can change dynamically the document using DOM • The document is presented in nodes • Most browsers support both • W3C DOM • WHATWG DOM • And in addition have extensions to these • DOM is not a programming language, it's an specification
• WHATWG DOM "standardizes" DOM • DOM LEVEL 3 core and DOM LEVEL 3 Events • Selectors API Level 2 • And others • https://dom.spec.whatwg.org/ • For HTML also additions • https://html.spec.whatwg.org/multipage/dom.html • Other languages support also DOM, not just JavaScript
Is the entry point into web page's content (DOM Tree) • Some methods for getting elements • getElementsById(id) • getElementsByTagName(name) • querySelector(cssselector) • The DOM tree can be traversed in a lot of different ways • DOM Tree consists of nodes. Node can be for example • element, attribute, text ...
this • <p>Hello</p> • You have two nodes 1) element node p 2) text node Hello • Text node is child node of p element. P element is parent node of the text node
var headElementNode = htmlElementNode.firstChild; var titleElementNode = headElementNode.firstChild; var titleTextNode = titleElementNode.firstChild; var titleString = titleTextNode.nodeValue; console.log(titleString); </script> </body> </html>
<h1>Title 2</h1> <script> var allH1Elements = document.getElementsByTagName("h1"); var firstH1 = allH1Elements[0]; firstH1.firstChild.nodeValue = "Hello!"; </script> </body> </html> Getting all elements with tag H1
1</h1> <h1>Title 2</h1> <script> var firstH1 = document.getElementById("mytitle"); firstH1.firstChild.nodeValue = "Hello!"; </script> </body> </html> Getting H1 with the id of mytitle
Title</title> </head> <body> <div id="myDiv"> <h1>Title</h1> </div> <script> var div = document.querySelector("#myDiv"); var h1 = div.firstChild; var text = h1.firstChild; text.nodeValue = "Hello"; </script> </body> </html> We are NOT getting the H1 Here!
= document.querySelector("#myDiv"); var h1 = div.firstElementChild; var text = h1.firstChild; text.nodeValue = "Hello"; </script> Bypassing the text node..
document.createElement("h1") let text = document.createTextNode("Hello World") h1.appendChild(text) document.getElementsByTagName("body")[0].appendChild(h1) } window.addEventListener('load', main) </script> Creating new elements and text nodes!
"http://www.tamk.fi") let text = document.createTextNode("tamk") a.appendChild(text) document.getElementsByTagName("body")[0].appendChild(a) } window.addEventListener('load', main)
{ let a = document.createElement("a") a.setAttribute("href", "http://www.tamk.fi") let text = document.createTextNode("tamk") a.appendChild(text) let p = document.getElementById("someid") let parent = p.parentElement parent.insertBefore(a, p) } window.addEventListener('load', main) </script> </head> <body> <p id="someid">Hello</p> </body> </html> Insert the link (a) before the p under body
{ let body = document.getElementsByTagName('body')[0] let p = document.getElementById('someid') body.removeChild(p) } window.addEventListener('load', main) </script> </head> <body> <p id="someid">Hello</p> </body> </html>
unresponsive) until request is done • Asynchronous requests does not block the client -> User can interact with the web page while at the same time the request is being fulfilled • Asynchronous requests usually work with callbacks or Promises • AJAX requests are asynchronous, also web workers and setTimeout
Install http-server module globally: • npm install http-server –g • Then start the http-server in your project folder: • http-server • Open browser • http://127.0.0.1:8080
server side script is run in background. • Javascript does not have to wait for the server response.. You can • Execute other scripts while waiting server response • Deal with the response when ready • Specify a function that is called when response is ready!
same- origin policy • Only http requests to its own domain! • So access from 127.0.0.1/index.html -> 127.0.0.1/students.xml is allowed • From 127.0.01/index.html -> someothersite.com/students.xml is NOT allowed!
or GET? "somescript.php", // URL true); // async or not? // Specify the data you want to send via POST xmlobj.setRequestHeader("Content-type","application/x-www-form-urlencoded"); // Send data xmlobj.send("name=Kalle");
doing AJAX • Fetch API uses Promises • Promises an alternative to callbacks delivering result of an async computation • Promises are part of EcmaScript 2015 • Previously you could use them as additional library • https://promisesaplus.com/ 122
method (chaining) -> using callbacks can be messy • What is async fails? If you have chained async methods and one of them fails? • It is not standard, everyone can have they own version of doing callbacks 124
stuff if(true) { resolve("OK!"); } else { reject("Failed!"); } } function onSuccess(msg) { console.log(msg); } function onError(msg) { console.log(msg); } let promise = new Promise(promiseFunction); promise.then(onSuccess, onError); promise.then(onSuccess).catch(onError); You can do both here 125
200 - 299 if(!response.ok) { throw new Error('Network response was not ok!'); } if(!contentType.includes('application/json')) { throw new Error('It was not json') } return response.json(); }).then(function(jsonObject) { // do something with the jsonObject }).catch(function(error) { console.log('There has been a problem with your fetch operation: ' + error.message); });
pairs from a form • When having a form in HTML page you can just create the FormData by • let formData = new FormData(someFormDomElement) • Then by using Fetch API or XmlHttpRequest, it's really easy to send user given values to backend
to draw graphics via scripting in JavaScript • Draw graphics, bitmaps, create animations... • Really easy • <canvas></canvas> • And then in JS start to draw to the element
let text = e.target.result console.log(text) } function readFile(file) { var reader = new FileReader(); reader.onload = read reader.readAsText(file) } function handleFileSelect(evt) { let f = evt.target.files[0] readFile(f) } document.getElementById('files').addEventListener('change', handleFileSelect); </script>