full-stack web developmentbusaco/teach/courses/staw/presentations/... · jerryscript (destinat iot...
TRANSCRIPT
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Full-Stack Web Development
JavaScript în cadrul navigatorului Web
javascript.info
Dr. Sabin Corneliu Buraga – profs.info.uaic.ro/~busaco/
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
“Solving the problem is more importantthan being right.”
Milton Glaser
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Cum rulează programele JavaScriptîn navigatorul Web?
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Majoritatea programelor JavaScript
rulează – sunt interpretate –
în navigatorul Web via un script engine
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Majoritatea programelor JavaScript
rulează – sunt interpretate –
în navigatorul Web via un script engine
Chakra (Edge, Node-ChakraCore – Microsoft)
JavaScriptCore (Safari, React Native – Apple)
JerryScript (destinat IoT – JS Foundation)
SpiderMonkey (Firefox, SpiderNode – Mozilla)
Rhino (implementare Java – Mozilla)
Nashorn (OpenJDK – Oracle)
V8 (Chrome, Opera, Edge, Node.js – Google)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
fazele principale ale procesării și rulării codului JavaScript(Hyungwook Lee, 2014)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Analiza lexicală și sintactică precedă faza de compilare
procesarea (parsing) codului-sursă JS
arbore sintactic abstract (AST – Abstract Syntax Tree) conținând obiecte ce reprezintă structura programului
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Analiza lexicală și sintactică precedă faza de compilare
procesarea (parsing) codului-sursă JS
arbore sintactic abstract (AST – Abstract Syntax Tree) conținând obiecte ce reprezintă structura programului
AST este apoi transformat în cod binar (bytecode)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
etape principale ale procesării codului JS la V8(T. Verwaest, 2019) – v8.dev/blog/scanner
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
intern, procesorul JavaScript interpretează codul-sursă care apoi este optimizat de un compilator
(M. Bynens & B. Meurer, 2018) – mathiasbynens.be/notes/shapes-ics
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
cod JScod intermediar (bytecode)cod mașinăM. Bynens & B. Meurer, 2018mathiasbynens.be/notes/prototypes
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
cod JScod intermediar (bytecode)cod mașinăM. Bynens & B. Meurer, 2018mathiasbynens.be/notes/prototypes
function add(x, y) {
return x + y;
}
add(1, 2);
StackCheck
Ldar a1
Add a0, [0]
Return
leaq rcx,[rip+0x0]
movq rcx,[rcx-0x37]
testb [rcx+0xf],0x1
jnz CompileLazyDeoptimizedCode
push rbp
movq rbp,rsp
push rsi
push rdi
cmpq rsp,[r13+0xe88]
jna StackOverflow
…
jo Deoptimize
shlq rdx, 32
movq rax,rdx
movq rsp,rbp
pop rbp
ret 0x18
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
V8 – v8.dev
interpretorul Ignition + compilatorul TurboFan
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Optimizările sunt realizate pe baza unor euristici(speculative optimizations)
interpretorul colectează informații (profiling data) despre datele de intrare (input) ale unor operații
aceste informații vor fi utilizate apoi de compilator pentru a face diverse presupuneri vizând input-urile posibile
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
etapele principale realizate de procesorul V8a se studia articolul lui B. Meurer (2017)
benediktmeurer.de/2017/12/13/an-introduction-to-speculative-optimization-in-v8/
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
SpiderMonkey – developer.mozilla.org/docs/Mozilla/Projects/SpiderMonkey
recurge la 2 compilatoare pentru optimizarea codului
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
când procesorul JS determină – în funcție de datele colectate (profiling data) – că o parte de cod e utilizat (hot),
decide să-l optimizeze mathiasbynens.be/notes/prototypes
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Chakra – github.com/Microsoft/ChakraCore
recurge la 2 compilatoare pentru optimizarea codului
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
JavaScriptCore – developer.apple.com/documentation/javascriptcore
recurge la 3 compilatoare pentru optimizarea codului
Data Flow Graphcompiler
Faster Than Lightcompiler
Low-Levelinterpreter
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
în cazul JavaScriptCore, optimizările au loc complet concurent (all optimizing compilers run fully concurrent
with the main JavaScript execution)mathiasbynens.be/notes/prototypes
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
codul mașină optimizat necesită memorie suplimentarăprocesorul JS nu poate optimiza „orice”
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Cod JavaScript intern vs.preluat dintr-un fișier extern
<body>
…
<script type="text/javascript">
alert ("Salut, lume!");
</script>
</body>
<script type="text/javascript" src="http://salutari.info/salut.js">
</script>
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Cod JavaScript intern vs.preluat dintr-un fișier extern
<body>
…
<script type="text/javascript">
alert ("Salut, lume!");
</script>
</body>
<script type="text/javascript" src="http://salutari.info/salut.js">
</script>
remarcă: pentru browser-ele moderne se va specificaapplication/javascript în loc de text/javascript
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
arhitectura de bază a interpretorului (script engine) JS inclus într-un navigator Web (A. Zlatkov, 2017)
blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cfblog.sessionstack.com/how-javascript-works-inside-the-v8-engine-5-tips-on-how-to-write-optimized-code-ac089e62b12e
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
execuția codului JavaScript se realizează într-un singur fir de execuție (proces), dar alte acțiuni efectuate de browser-ul Web nu
developers.google.com/web/updates/2018/09/inside-browser-part1
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Procesorul JavaScript e responsabil și cu eliminarea memoriei neutilizate (junk) via operația garbage collection
algoritmul de bază: mark-and-sweeprulat periodic
javascript.info/garbage-collection
developer.mozilla.org/Web/JavaScript/Memory_Management
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
garbage collection
tradițional, are loc în firul de execuție principal eventual, aplicându-se optimizări (euristici):
generational / incremental / idle-time collection
v8.dev/blog/jank-busters
jayconrod.com/posts/55/a-tour-of-v8-garbage-collection
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
garbage collection
actualmente, se poate realiza concurent sau în paralel
exemplu: Orinoco inclus în V8v8.dev/blog/orinoco-parallel-scavenger
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Un program JavaScript are acces la arborele DOM (Document Object Model)
corespunzător documentului HTML
specificații ale Consorțiului Webvarianta în vigoare: DOM 4 (2015)
www.w3.org/TR/dom/
de revăzut materia „Tehnologii Web”profs.info.uaic.ro/~busaco/teach/courses/web/
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Un program JavaScript are acces la arborele DOM (Document Object Model)
corespunzător documentului HTML
DOM Living Standard – dom.spec.whatwg.org
specific HTML5, în continuă dezvoltare(cea mai recentă actualizare: 4 noiembrie 2019)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Programul JS recurge la obiecte implementând interfețele DOM pentru accesarea și modificarea
reprezentării interne a unui document HTML (i.e. arborele DOM)
devdocs.io/dom
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
<!DOCTYPE html>
<html>
<body>
<p>Tehnologii Web</p>
<div>
<img src="web.png"/>
</div>
</body>
</html>
HTMLHtmlElement
HTMLBodyElement
HTMLParagraphElement
Text
HTMLDivElement
HTMLImageElement
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
dom: browser
inspectarea arborelui DOM asociat unui document HTML via instrumentele oferite de navigatorul Web
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Minimal, navigatorul Web implementează
recomandarea DOM Level 2 HTML (2003)
www.w3.org/TR/DOM-Level-2-HTML
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
dom: core
un document HTML și arborele DOM corespunzătorreprezentat via Live DOM Viewer
software.hixie.ch/utilities/js/live-dom-viewer/
în cazul HTML, numele elementelor sunt disponibile cu litere mari (capitals)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
dom: core
un document HTML și arborele DOM corespunzătorreprezentat via Live DOM Viewer
software.hixie.ch/utilities/js/live-dom-viewer/
De ce apare și acest nod?
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
De asemenea, programele JavaScript au accesla diverse obiecte oferite de mediul de execuție
pus la dispoziție de browser
e.g., informații privind contextul rulării(caracteristici ale navigatorului, latența rețelei),
istoricul navigării, fereastra de redare a conținutului, transfer (a)sincron de date,…
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Arborele DOM asociat documentului HTMLpoate fi accesat/alterat via obiectul document
instanță a clasei implementând interfața HTMLDocument
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
interface HTMLDocument : Document { attribute DOMString title; // titlul documentuluireadonly attribute DOMString referrer; // adresa resursei ce referă paginareadonly attribute DOMString domain; // domeniul de care aparținereadonly attribute DOMString URL; // URL-ul absolut al documentuluiattribute HTMLElement body; // acces la elementul <body>readonly attribute HTMLCollection images; // lista tuturor imaginilorreadonly attribute HTMLCollection links; // lista tuturor legăturilorreadonly attribute HTMLCollection forms; // lista tuturor formularelor
attribute DOMString cookie; // acces la cookie-uri// emite o excepție dacă e asignată o valoare
void open (); // deschide un flux de scriere (alterează DOM-ul curent)void close (); // închide fluxul de scriere și forțează redarea conținutuluivoid write (in DOMString text); // scrie un șir de caract. (e.g., cod HTML)void writeln (in DOMString text); // idem, dar inserează și new lineNodeList getElementsByName (in DOMString numeElement);
// furnizează o listă de elemente conform unui nume de tag}; interfață specificată în limbajul declarativ WebIDL
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Deoarece interfața HTMLDocument
extinde Document, putem recurge la funcționalitățile
stipulate de specificația DOM generală
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Proprietatea documentElement
desemnează nodul-rădăcină
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
getElementById (identificator)
furnizează un element – nod de tip Element –conform identificatorului său unic, desemnat de valoarea
atributului id specificat în cadrul documentului
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
parentNode
oferă acces la numele nodului-părinte al nodului curent
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
previousSibling
nextSibling
acces la nodul precedent/următorde pe același nivel al arborelui
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Pentru noduri de tip Element
se pot folosi și proprietățile
previousElementSibling
nextElementSibling
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
childNodes
proprietate furnizând într-un tablounumele nodurilor-copil ale nodului curent
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
firstChild
desemnează primul nod-copil al nodului curent
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
lastChild
specifică ultimul nod-copil al nodului curent
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
attributes
reprezintă tabloul asociativconținând atributele asociate unui nod de tip Element
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
cofunction topLevelNodeAt (nod, top) {
while (nod && nod.parentNode != top)
nod = nod.parentNode;
return nod;
}
function topLevelNodeBefore (nod, top) {
while (!nod.previousSibling && nod.parentNode != top)
nod = nod.parentNode;
return topLevelNodeAt (nod.previousSibling, top);
}
discuție
Ce rol au cele două funcții?
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Interfața HTMLElement o extindepe cea generală oferită de DOM Level 2
fiecare element HTML specific derivă din ea
Node ElementHTML
ElementHTML
DivElement
o interfață specifică fiecărui element HTML
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
// un element HTML generic
interface HTMLElement : Element {
attribute DOMString id; // identificator asociat elementului
attribute DOMString title; // titlu explicativ
attribute DOMString lang; // limba în care e redactat conținutul
attribute DOMString className; // numele clasei CSS folosite pentru redare
};
// specifică un formular Web
interface HTMLFormElement : HTMLElement {
readonly attribute HTMLCollection elements; // elementele HTML incluse în formular
readonly attribute long length; // numărul câmpurilor formularului
attribute DOMString action; // URI-ul resursei ce procesează datele
attribute DOMString enctype; // tipul MIME de codificare a datelor
// (e.g., application/x-www-form-urlencoded)
attribute DOMString method; // metoda HTTP folosită: GET, POST
void submit(); // trimite date URI-ului definit de ‘action’
};
// o imagine (conținut grafic raster)
interface HTMLImageElement : HTMLElement {
attribute DOMString alt; // text alternativ descriind conținutul grafic
attribute DOMString src; // URI-ul resursei grafice
};
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Interfața HTMLCollection modelează o listă de noduri
un nod poate fi accesat folosind un index numeric sau pe baza unui identificator (e.g., stabilit via atributul id)
interface HTMLCollection {
readonly attribute unsigned long length; // reprezintă lungimea listei
Node item (in unsigned long index); // oferă un nod via un index numeric
Node namedItem (in DOMString name); // furnizează un nod pe baza numelui
};
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Cum putem afla/modifica diverse informațiiprivind nodurile arborelui DOM?
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Informații referitoare la nodurile arborelui DOM
nodeType
proprietate care furnizează tipul unui nod
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
dom: coreTipuri de noduri (valori pentru nodeType) Valoare
ELEMENT_NODE 1
ATTRIBUTE_NODE 2
TEXT_NODE 3
CDATA_SECTION_NODE 4
ENTITY_REFERENCE_NODE 5
ENTITY_NODE 6
PROCESSING_INSTRUCTION_NODE 7
COMMENT_NODE 8
DOCUMENT_NODE 9
DOCUMENT_TYPE_NODE 10
DOCUMENT_FRAGMENT_NODE 11
NOTATION_NODE 12
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Informații referitoare la nodurile arborelui DOM
nodeValue
proprietate oferind valoarea unui nod
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Informații referitoare la nodurile arborelui DOM
innerHTML
proprietate – mutabilă – ce furnizează codul HTMLdin cadrul unui nod de tip Element
utilizarenerecomandabilă
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Informații referitoare la nodurile arborelui DOM
textContent
proprietate ce furnizează/stabilește conținutul textual al nodului și posibililor descendenți
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Informații referitoare la nodurile arborelui DOM
getAttribute (numeAtribut)
metodă care oferă acces la valoarea unui atribut
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Modificarea structurii arborelui DOM
createElement (element)
creează un nod de tip Element
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Modificarea structurii arborelui DOM
createTextNode (nod)
creează un nod cu conținut textual
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Modificarea structurii arborelui DOM
appendChild (nod)
adaugă un nod-copil nodului curent
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Modificarea structurii arborelui DOM
removeChild (nod)
elimină un nod-copil
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Modificarea structurii arborelui DOM
cloneChild ()
„clonează” un nod al arborelui
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Modificarea structurii arborelui DOM
setAttribute (atribut, valoare)
stabilește valoarea unui atribut asociat unui element
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Modificarea structurii arborelui DOM
removeAttribute (atribut)
elimină un atribut
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
JS Fiddle
generare dinamică via JavaScripta unui formular Web
jsfiddle.net/busaco/0wvn3fha/
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
function adaugaControl (element, tip, nume, explicatie) {// vom crea un element <input> atașându-i atributele esențialelet control = document.createElement ('input');control.type = tip;control.id = nume;control.name = nume;
let eticheta = document.createElement ('label'); // o etichetă explicativă…eticheta.htmlFor = nume;eticheta.innerHTML = explicatie;eticheta.style.background = 'lightgray’; // …plus diverse stiluri CSSeticheta.style.color = '#333';eticheta.style.padding = '0.2em';
// vom plasa elementele <label> și <input> într-un container let container = document.createElement ('div');container.className = "interactiv";container.appendChild (eticheta);container.appendChild (control);
// vom adăuga nodul container la elementul dat ca parametruelement.appendChild (container);
}
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
// preluăm elementul de tip formularlet formular = document.getElementById ('unFormular’);
// adăugăm controalele de interacțiune doriteadaugaControl (formular, 'text', 'nume', 'Numele meu: ');adaugaControl (formular, 'password', 'parola', '<em>Codul secret</em>: ');adaugaControl (formular, 'checkbox', 'particip', 'Particip? ');for (let an = 2018; an <= 2020; an++) {
adaugaControl (formular, 'radio', 'an', 'Web Hackathon ' + an);}
arborele DOM corespunzător codului HTML
generat prin program
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Suport pentru procesarea proprietăților CSS
pe baza unui model obiectual specificCSSOM (CSS Object Model)
specificație în lucru (draft) – 16 octombrie 2019
drafts.csswg.org/cssom/
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Suport pentru procesarea proprietăților CSS
actualmente, modificarea proprietăților de stil se poate realiza via proprietatea HTMLElement.style
// asocierea mai multor stiluri CSS
elem.style.cssText = "color: blue; border: 1px solid #000";
// similar cu linia – are drept efect alterarea arborelui DOM:
elem.setAttribute ("style", "color: blue; border: 1px solid #000;");
developer.mozilla.org/Web/API/CSSStyleDeclaration
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Găsirea de noduri via selectori CSS
Selectors API – Level 1recomandare W3C (2013)
acces la diverse date via selectorii CSS cu metodelequery() queryAll() querySelector() querySelectorAll()
www.w3.org/TR/selectors-api/
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Găsirea de noduri via selectori CSS
querySelector (selectori)
furnizează primul element – folosind traversarea în adâncime în preordine – care se potrivește grupului
de selectori (delimitați de virgulă)
querySelectorAll (selectori)
oferă lista de tip NodeList a tuturor elementelor găsite
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Găsirea de noduri via selectori CSS
// toate elementele <li> selectate via CSS (date de tip NodeList)var elemente = document.querySelectorAll ("ul.menu > li");for (var i = 0; i < elemente.length; i++) {prelucrează (elemente.item (i)); // procesăm fiecare nod
}
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
exemplificare – folosim consola browser-ului Web: document.querySelectorAll ("section[id^=\"week\"]:nth-child(odd) > h2");
selectori CSS3
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Traversarea arborilor DOM
se utilizeazăTreeWalker
NodeIteratorFilter
developer.mozilla.org/docs/Web/API/TreeWalker
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
// instanțiem un obiect TreeWalker pentru a parcurge arborele DOMlet calator = document.createTreeWalker(document.body,
NodeFilter.SHOW_ELEMENT, // selectăm doar nodurile de tip element{ acceptNode: nod => { // ...și le filtrăm (doar <p>, <div> și <strong>)
if (nod.nodeName === 'P' || nod.nodeName === 'DIV' || nod.nodeName === 'STRONG') return NodeFilter.FILTER_ACCEPT;
}});
let noduri = [ ];
// baleiem toate nodurile găsite și le plasăm în tabloul 'noduri'while(calator.nextNode()) noduri.push(calator.currentNode);// listăm nodurile găsitelet elem = document.getElementById('info');noduri.forEach(nod => {
// plasăm informațiile în DOM, în <div> înainte de ultimul nod copilelem.insertAdjacentText('beforeend', nod.outerHTML + "\u25CF");// și la consola browser-ului Webconsole.log (`Element ${nod.nodeName}: ${nod.textContent}`);
});
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
program disponibil la JSFiddle: jsfiddle.net/busaco/ofm958vr/
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
definirea de activități (callback-uri) executatela apariția unui eveniment
eveniment = acțiune produsă în cadrul mediului deexecuție în urma căreia programul va putea reacționa
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
codul JavaScript invocat la apariția unui evenimentva putea fi încapsulat într-o funcție de tratare a acestuia
(event handler)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
tradițional, se atașează cod JavaScript ce va fi executatla apariția unui eveniment de bază
(e.g., onclick, onmouseover, onchange, onload, onkeypress,…)asupra unui element
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
<button onclick="alert ('Au!');">Apasă-mă!</button>
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
<button onclick="alert ('Au!');">Apasă-mă!</button>
pentru a inhiba execuția acțiunii implicite, codul JavaScript va trebui să întoarcă false
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
<button onclick="alert ('Au!');">Apasă-mă!</button>
document.getElementById ("identificator").onclick
= trateazaClick; // mai „evoluat” via DOM 1
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
tratarea standardizată a evenimentelor:specificația DOM Level 2 Events
www.w3.org/TR/DOM-Level-2-Events/
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
specificarea de activități executatela apariția unui eveniment
obiect.addEventListener ("eveniment", funcție, mod);
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
descrierea arborescentă a fluxului de evenimente
capture versus bubble
de parcurs javascript.info/bubbling-and-capturing
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
fluxul de evenimente (T. Leithead et al., 2012)
a se studia și W. Page, An Introduction to DOM Events (2013)www.smashingmagazine.com/2013/11/an-introduction-to-dom-events/
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
descrierea arborescentă a fluxului de evenimente
mod = true
se încearcă tratarea evenimentului pornindde la rădăcină până la obiectul-țintă – capture phase
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
descrierea arborescentă a fluxului de evenimente
mod = false
se încearcă tratarea evenimentului atunci cândevenimentul e propagat de la obiectul unde a survenit
până la entitățile superioare lui – bubbling phase
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
se va utiliza un set standard de evenimente
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tipuri de evenimente – interacțiune cu utilizatorul
mouse: click dblclick mouseenter mousedown mouseup
mouseover mousemove contextmenu select wheel
keyboard: keypress keydown keyup
clipboard: copy cut paste
view: resize scroll fullscreenchange fullscreenerror
drag & drop: dragstart drag dragenter dragover
dragleave dragend drop
form: focus blur select submit reset
document (page lifecycle): load DOMContentLoaded
beforeunload unload abort cancel
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tipuri de evenimente – vizând resursele
network: online offline
session history: pagehide pageshow popstate
printing: beforeprint afterprint
media: canplay play playing pause suspend waiting seeking
seeked stalled complete ended emptied durationchange
ratechange volumechange timeupdate …
progress: loadstart progress error timeout abort load loaded
storage: change storage
Web socket: open message error close
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tipuri de evenimente – altele
CSS transitions: transitionstart transitionrun
transitionend transitioncancel
CSS animations: animationstart animationend
animationiteration
value change: broadcast hashchange input readystatechange…
pentru amănunte, a se explora șideveloper.mozilla.org/Web/Events
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
coTipuri de evenimente – specifice HTML5
asociate API-urilor disponibile:
Ambient Light, App Cache, Battery, Contacts, Device Orientation, Device Storage, Download, File,
IndexedDB, Media Capture & Streams, Payment, Pointer, Proximity, Push, SVG, Touch, Time & Clock, TV, Web Audio, WebGL, WebRTC, Web Notifications, Web Speech, WebVR,
Wifi Information, Wifi P2P etc.
vezi cursurile viitoare
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
interface Touch { // specifică zona tactilă readonly attribute long identifier;readonly attribute EventTarget target;readonly attribute long screenX;readonly attribute long screenY;readonly attribute long clientX;readonly attribute long clientY;readonly attribute long pageX;readonly attribute long pageY;
};interface TouchList { // definește lista punctelor de contact pentru un eveniment tactil
readonly attribute unsigned long length;getter Touch? item (unsigned long index);
};interface TouchEvent : UIEvent {
readonly attribute TouchList touches;readonly attribute TouchList targetTouches;readonly attribute TouchList changedTouches;readonly attribute boolean altKey;readonly attribute boolean metaKey;readonly attribute boolean ctrlKey;readonly attribute boolean shiftKey;
};
pot fi tratate evenimentele
touchstart
touchend
touchmove
touchcancel
exemplificare:specificarea
evenimentelor tactile
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
(în loc de) pauză
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
proprietăți utile ale obiectului Event
type
specifică tipul evenimentului ca șir de caracteree.g., "click", "load", "scroll", "submit"
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
proprietăți utile ale obiectului Event
target
desemnează nodulasupra căruia evenimentul a fost declanșat inițial
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
proprietăți utile ale obiectului Event
currentTarget
indică nodul care tratează evenimentul
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
proprietăți utile ale obiectului Event
bubbles
indică dacă evenimentul se propagăspre elemente ascendente (valoarea true)
ori către descendenți (valoarea false)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
proprietăți utile ale obiectului Event
bubbles
e.g., evenimentele abort, error, select, submit, resize, scroll,click, mousedown, mouseover, mousemove, mouseout,
touchstart, touchend pot avea bubbles = true
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
proprietăți utile ale obiectului Event
bubbles
în cazul evenimentelor focus, blur, load, unload, proprietatea bubbles are valoarea false
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
proprietăți utile ale obiectului Event
cancelable
precizează dacă evenimentul poate fi întrerupt
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
proprietăți utile ale obiectului Event
cancelable
de exemplu, pentru evenimentele load, unload, abort, error, select, focus, blur, resize, scroll, touchcancel
proprietatea cancelable este setată ca fiind false
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
proprietăți utile ale obiectului Event
cancelable
pentru evenimente precum click, mousedown, mouseup,mouseover, mousemove, mouseout, touchstart, touchend,
touchmove proprietatea cancelable poate fi true
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
eliminarea tratării unui eveniment
removeEventListener ()
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
ignorarea comportamentului implicit
preventDefault ()
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
comportamentul implicit pentru evenimentul tactiltouchend poate varia în funcție de context/platformă:
mousemove, mousedown, mouseup, click
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
trimiterea evenimentului să poată fi procesatconform modelului oferit de implementare
dispatchEvent ()
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Tratarea evenimentelor
oprirea propagării unui eveniment în cadrul arborelui DOM
stopPropagation ()
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
<!DOCTYPE html><html><head><meta charset="utf-8" /><title>Evenimente JS</title></head><body>
<form><textarea id="editor"></textarea>
</form></body><script type="application/javascript">const infoEv = e => { console.log (
`Eveniment: ${e.type}\nCaracter: ${String.fromCharCode (e.charCode)}\nElement țintă al evenim.: ${e.target}\nȚinta curentă: ${e.currentTarget}`);
}; document.addEventListener ("keypress", infoEv);</script></html>
exemplificare: afișarea datelor vizând un eveniment
adap
tare
du
pă
Bap
tist
e P
esq
uet
(20
17
)g
ith
ub
.co
m/b
pes
qu
et/t
hej
sway
/blo
b/m
aste
r/m
anu
scri
pt/
chap
ter1
6.m
d
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
inspecție de evenimente apărute în pagina Web(tratate de un program JS
sau de o extensie instalată)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
// Adaptare după https://eloquentjavascript.net/14_event.htmlconst trateazaEveniment = ev => {
// plasăm un 'punct' la coordonatele cursorului mouse-uluilet pct = document.createElement ('div');pct.className = (ev.type === 'dblclick') ? 'punct roz' : 'punct';pct.style.left = (ev.pageX - 5) + 'px';pct.style.top = (ev.pageY - 5) + 'px';document.body.appendChild (pct);console.log (`${ev.type}: Am plasat un punct
la coord. (${ev.pageX}, ${ev.pageY}).`);};// "ascultăm" evenimentele click și dblclickdocument.addEventListener ('click', trateazaEveniment);document.addEventListener ('dblclick', trateazaEveniment);
exemplu: tratarea evenimentelor click și dblclick
vezi exemplul complet în arhivă
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
studiu de caz (Ondřej Žára, 2013)
calcul tabelar în 30 de linii JavaScript
jsfiddle.net/ondras/hYfN3/
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
// crearea interfeței Web via DOM
// construim tabelul cu câmpuri de intrare
for (var i = 0; i < 6; i++) {
// adăugăm un rând la tabel
var row = document.querySelector ("table").insertRow (-1);
for (var j = 0; j < 6; j++) {
var letter = String.fromCharCode ("A".charCodeAt (0) + j - 1);
row.insertCell (-1).innerHTML =
i && j ? "<input id='" + letter + i + "'/>" : i || letter;
}
}
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
var DATA={}, INPUTS=[].slice.call (document.querySelectorAll ("input"));INPUTS.forEach ( function(elm) { // pentru orice <input>, preluăm valoarea
elm.onfocus = function (e) {e.target.value = localStorage[e.target.id] || ""; };
elm.onblur = function (e) {localStorage[e.target.id] = e.target.value; computeAll(); };
var getter = function () {// furnizează valoarea (deja stocată în localStorage)var value = localStorage[elm.id] || "";if (value.charAt(0) == "=") { // începe cu =, deci e o formulă de evaluat
with (DATA) return eval (value.substring(1));} else { return isNaN (parseFloat (value)) ? value : parseFloat (value); }
};Object.defineProperty (DATA, elm.id, { get: getter });Object.defineProperty (DATA, elm.id.toLowerCase(), { get: getter });
} );( window.computeAll = function () { // funcție ce evaluează toate celulele
INPUTS.forEach (function (elm) { try { elm.value = DATA[elm.id]; } catch(e) {} });
} )();
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Remarcă:
unele navigatoare acceptă tratarea unor evenimentenestandardizate (încă) de Consorțiul Web
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Remarcă:
pot fi specificate și evenimente definite de programator
CustomEvent
dom.spec.whatwg.org/#interface-customevent
developer.mozilla.org/Web/API/CustomEvent
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Browser-ul Web oferă obiectul Window
reprezintă o zonă de redare a conținutului pe baza reprezentării interne (arborele DOM)
a unui document HTML
developer.mozilla.org/Web/API/Window
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Browser-ul Web oferă obiectul Window
fiecare tab al interfeței navigatorului conține propriul obiect Window
acest obiect nu este partajat de tab-uri multiple
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Browser-ul Web oferă obiectul Window
proprietăți importante:
document – referință la documentul (arborele DOM) pe care obiectul Window îl include
history – acces la istoricul navigării (via obiectul History)html.spec.whatwg.org/multipage/history.html
location – adresa Web (URL) curentă
navigator – oferă date despre browser (un obiect Navigator)developer.mozilla.org/Web/API/Navigator
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Browser-ul Web oferă obiectul Window
proprietăți importante – continuare:
screen – oferă detalii despre ecran (obiectul Screen)developer.mozilla.org/Web/API/Screen
localStorage – date persistente stocate local (obiectul LocalStorage specificat de HTML5)
developer.mozilla.org/Web/API/Window/localStorage
sessionStorage – referință la date vizând sesiunea curentă (stocate într-un obiect SessionStorage oferit de HTML5)
html.spec.whatwg.org/multipage/webstorage.html
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Browser-ul Web oferă obiectul Window
metode utile:
alert() confirm() prompt() postMessage()
focus() blur() find() print()
open() close() stop()
moveBy() moveTo() resizeBy() resizeTo()
scrool() scrollBy() scrollTo()
amănunte: drafts.csswg.org/cssom-view/
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
coBrowser-ul Web oferă obiectul Window
evenimente – specificate prin nume prefixat de on
și clasificate ca fiind WindowEventHandlers(reuniunea evenimentelor definite de interfețele Window, HTMLBodyElement și HTMLFrameSetElement)
developer.mozilla.org/Web/API/WindowEventHandlers
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
suportul cumulat vizând evenimentele oferit de navigatoarele Web actuale
caniuse.com/#search=event
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
În ce manieră are loc transferul asincronîntre aplicațiile de pe server
și documentul Web?
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
AJAX – Asynchronous JavaScript And XML
permite transfer asincron de date între client (browser) și serverul Web
a se revizita cursul„Tehnologii Web”
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
AJAX – Asynchronous JavaScript And XML
suită de tehnologii deschise
limbaje standardizate de structurare – uzual, HTML –și de prezentare a datelor: CSS
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
AJAX – Asynchronous JavaScript And XML
suită de tehnologii deschise
redare + interacțiune la nivel de client Webvia standardul DOM
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
AJAX – Asynchronous JavaScript And XML
suită de tehnologii deschise
interschimb și manipulare de date reprezentate prin: diverse dialecte XML
JSON (JavaScript Object Notation) HTML
alte formate
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
AJAX – Asynchronous JavaScript And XML
suită de tehnologii deschise
transfer (a)sincron de datefacilitat de obiectul XMLHttpRequest
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
AJAX – Asynchronous JavaScript And XML
suită de tehnologii deschise
procesare folosind limbajul ECMAScript (JavaScript)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Obiectul XMLHttpRequest
disponibil la nivel de navigator Web via JavaScript
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Obiectul XMLHttpRequest
specificația actuală oferită de navigatoarele curente(Living Standard, 24 septembrie 2019)
xhr.spec.whatwg.org
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Obiectul XMLHttpRequest
permite realizarea de cereri HTTP – e.g., GET, POST,… –dintr-un program rulând la nivel de client (browser)
spre o aplicație / un serviciu Web existent(ă) pe server,în mod asincron ori sincron
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Obiectul XMLHttpRequest
open ( )
inițiază – deschide – o conexiune HTTP cu serverul,emițând o cerere: GET, POST,…
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Obiectul XMLHttpRequest
send ( )
transmite (asincron) date – e.g., JSON, XML etc. –,spre aplicația/serviciul ce rulează pe server
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Obiectul XMLHttpRequest
send ( )
transmite (asincron) date – e.g., JSON, XML etc. –,spre aplicația/serviciul ce rulează pe server
orice listener (asociat evenimentelor onloadstart, onprogress, onload, onloadend, ontimeout, onabort, onerror)
trebuie stabilit înainte de a trimite date
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Obiectul XMLHttpRequest
abort ( )
abandonează transferul de date curent
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Obiectul XMLHttpRequest
setRequestHeader ( )
specifică anumite câmpuri de antet HTTP
exemple: Cookie, Keep-Alive, User-Agent,…
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Obiectul XMLHttpRequest
getResponseHeader ( )
furnizează un anumit câmp prezentîn antetul mesajului de răspuns HTTP trimis de server
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Obiectul XMLHttpRequest
getAllResponseHeaders ( )
oferă toate câmpurile HTTP trimise de server,exceptând Set-Cookie
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Obiectul XMLHttpRequest
readyState
furnizează codul de stare a transferului:0 – UNSENT
1 – OPENED
2 – HEADERS_RECEIVED
3 – LOADING
4 – DONE
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Obiectul XMLHttpRequest
status
oferă codul de stare HTTP întors de serverul Web:200 (Ok)
404 (Not Found)500 (Internal Server Error)
…
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Obiectul XMLHttpRequest
statusText
conține mesajul corespunzător codului de stare HTTP
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Obiectul XMLHttpRequest
responseText
responseXML
conțin răspunsul (datele) obținut(e) de la server
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Obiectul XMLHttpRequest
onreadystatechange
specifică funcția ce va fi invocată la modificările de stareale transferului de date dintre server și client
handler de tratare a evenimentelor de transfer
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Obiectul XMLHttpRequest
excepții care pot fi emise:AbortError
InvalidAccessError
InvalidStateError
NetworkError
SecurityError
TimeoutError
…
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Noutăți:stabilirea unui timeout privind realizarea unei cereri
(la nivel de milisecunde)
o valoare nenulă cauzează realizarea unei preîncărcări (fetching) a resursei
de studiat Fetch
(HTML5 Living Standard, 4 noiembrie 2019)fetch.spec.whatwg.org
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Noutăți:datele vehiculate pot fi de mai multe tipuri
(ArrayBuffer, Blob, Document, DOMString, FormData)
detalii la xhr.spec.whatwg.org/#interface-formdata
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Noutăți:procesul de transmitere a datelor spre server (upload)
poate avea asociat un handler specific via proprietatea upload
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Noutăți:progresul încărcării poate fi urmărit pe baza
funcționalităților specificate de interfața ProgressEvent
xhr.spec.whatwg.org/#interface-progressevent
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
studiu de caz: RandomAjax
preia asincrono secvență de numere aleatoare generate de random.org – trimisă ca
text obișnuitjsfiddle.net/busaco/2254kdqn/
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
var xhr = new XMLHttpRequest ();
var numbers = document.getElementById ('numbers’);
// tratarea evenimentului de expirare a timpului de așteptare
xhr.ontimeout = function () { numbers.textContent = 'Time-out... :('; };
// tratarea evenimentului de preluare a datelor solicitate unui serviciu
xhr.onload = function () {
if (xhr.readyState === 4) { // am primit datele
if (xhr.status === 200) { // răspuns Ok din partea serverului
// înlocuim spațiile albe cu virgulă și plasăm conținutul
// în cadrul elementului HTML identificat prin 'numbers'
numbers.textContent = xhr.responseText.trim ().replace (/\W+/g, ', ');
} else {
numbers.textContent = 'An error occurred: ' + xhr.statusText;
}
}
};
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co// adresa Web a sursei de date
const URL = 'https://www.random.org/sequences/
?min=1&max=33&col=1&format=plain';
// timpul maxim de așteptare a răspunsului trimis de server
const TIME = 2000;
// deschidem conexiunea
xhr.open ("GET", URL, true);
// stabilim timpul maxim de așteptare a răspunsului
xhr.timeout = TIME;
// nu expediem date
xhr.send (null);
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
studiu de caz: RandomAjax (Fetch)
soluție folosind Fetch APIpentru aceeași problemă
jsfiddle.net/busaco/a2q9regd/
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
API-ul Fetch se bazează pe conceptul promise
rezultat ce ar putea fi oferit în urma execuției unei operații asincrone
revezi unul dintre cursurile anterioare
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
coRecurgem la promises pentru a realiza procesăriîn funcție de codul de stare HTTP primit
function status(response) { if (response.status >= 200 && response.status < 300) {// cererea poate fi rezolvatăreturn Promise.resolve (response)
} else {// cererea a fost rejectatăreturn Promise.reject (new Error (response.statusText))
}}
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
let numbers = document.getElementById ('numbers’);
fetch (URL)
.then (status) // verificăm dacă datele au fost recepționate cu succes
// transformăm obiectul răspunsului în șir de caractere
.then ((response) => response.text ())
// procesăm secvența de numere
.then ((response) => {
// înlocuim spațiile albe cu virgulă și plasăm conținutul
// în cadrul elementului HTML identificat prin 'numbers'
numbers.textContent = response.trim ().replace (/\W+/g, ', ');
})
.catch ((error) => { // a survenit o eroare :(
numbers.textContent = 'An error occurred: ' + error;
});
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Scenariu:preluăm caractere de la client – introduse în <textarea> –
și le trimitem asincron prin POST unei aplicații Webrulând pe server care le expediază înapoi
mesaje vehiculate în format JSON{ "tasta": "caracter", "data": "secunde" }
tratăm evenimentul keypress pentru a capta tastele acționate de utilizator
studiu de caz: PostJSON
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
// codul programului ES6 interpretat de navigatorul Web// tratăm evenimentul de apăsare a unei tasteconst trateazaEveniment = ev => {
// mesajul propriu-zis trimis serverului prin POST // atunci când survine evenimentullet msg = `{ "tasta": "${String.fromCharCode (ev.charCode)}",
"data": "${Date.now()}" }`; // încapsulăm o cerere POSTlet request = new Request ('/ajax/post.php', {method: 'POST',body: JSON.stringify (msg), // convertim datele JSON în șir de caractereheaders: {} // n-avem câmpuri-antet
});
de consultat arhiva cu exemple
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
fetch (request) // promitem să executăm codul, transmițând cererea....then (response => { // verificăm dacă am primit date JSON de la server
let contentType = response.headers.get ('Content-Type');if (contentType && contentType.includes ('application/json')) {
return response.json (); };throw new TypeError ('Datele primite nu-s JSON :(');
}).then (json => { // procesăm efectiv datele
// creăm un nod text care indică tasta apăsatălet elem = document.createTextNode (json.tasta);document.getElementById ('tasteApasate').appendChild (elem);// raportăm datele primite și la consola browser-uluiconsole.log
(`Date JSON primite: tasta=${json.tasta}, data=${Date(json.data)}`); })
};// via DOM, tratăm evenimentul keypressdocument.addEventListener ('keypress', trateazaEveniment);
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
// post.php -- program PHP care preia date JSON // transmise via POST de client și le trimite înapoi (echo)
function eJSONValid ($sir) { // verifică dacă datele JSON sunt corectejson_decode ($sir); return json_last_error () == JSON_ERROR_NONE;
}
// preluăm de la intrarea standard datele transmise de client (raw data)// (aici, cele dintr-o cerere POST)$date = trim (file_get_contents ("php://input"));
if (eJSONValid ($date)) { // trimitem datele JSON înapoi dacă sunt în regulăheader ("Content-type: application/json");echo json_decode ($date);
} else {die ('Date incorecte’);
}
aplicația (serviciul) Web invocat(ă) pe servertemă: portarea programului pentru Node.js
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
suportul pentru Fetch API în browser-ele Web curente
caniuse.com/#search=fetch
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Ce alte aspecte trebuie considerate
atunci când se recurge la Ajax?
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Oferirea de alternative la Ajax, atunci când suportulpentru acesta nu este implementat/activat
graceful degradation
progressive enhancement
www.w3.org/wiki/Graceful_degradation_versus_progressive_enhancement
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Aspect dezirabil:minimizarea traficului dintre browser și server
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Transferul de date poate fi monitorizat(+interceptat) via instrumente dedicate
la nivel de desktop: instrumentul WireShark
www.wireshark.org/docs/wsug_html_chunked/
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
inspecție a datelor vehiculate cu instrumentele pentru dezvoltatorii Web oferite de browser
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Stabilirea unui mod de interacțiune clar
interacțiune HTML clasică versus
interacțiune „bogată” cu Ajaxversus
interacțiune la nivelul unei aplicații convenționale
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Adoptarea Ajax pentru creșterea utilizabilității,nu doar de dragul tehnologiei
exemple negative:distragerea utilizatorului
abuz de resurse (e.g., supradimensionarea arborelui DOM)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Oferă premisele invocării asincrone de servicii Webîn stilul REST
transferul de date se realizeaza via POX (Plain Old XML),JSON (JavaScript Object Notation),
AHAH (Asynchronous HTML and HTTP)sau text neformatat
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Șabloane de proiectare AJAX
amănunte în cartea Michael Mahemoff, Ajax Design Patterns, O’Reilly, 2006
www.oreilly.com/library/view/ajax-design-patterns/0596101805/
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Șabloane de proiectare AJAX
privind programarea:
invocare de servicii Web(RESTful Service, JSON Message)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Șabloane de proiectare AJAX
privind programarea:
dialog între navigatorul Web și server(Periodic Refresh, Submission Throttling, Cross-Domain Proxy)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Șabloane de proiectare AJAX
privind programarea:
asigurarea performanței(Fat Client, Browser-Side Cache, Guesstimate,
Predictive Fetch, Code Compression, On-Demand JS)
detalii într-un curs viitor
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Șabloane de proiectare AJAX
privind programarea:
popularea arborelui DOM(e.g., Browser-Side Templating)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Șabloane de proiectare AJAX
referitoare la interacțiunea cu utilizatorul:
formulare Web(Edit-in-place, Rich Text Editor, Live Search)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Șabloane de proiectare AJAX
referitoare la interacțiunea cu utilizatorul:
widget-uri de afișare a conținutului(Data Grid, Progress Indicator, Suggestion, Slider, Status Area)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Șabloane de proiectare AJAX
referitoare la interacțiunea cu utilizatorul:
acțiuni oferite(Drag-and-Drop, Popup, Upload/Download Files)
detalii la master, în cadrul materiei Human-Computer Interaction
profs.info.uaic.ro/~busaco/teach/courses/hci/hci-film.html
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Șabloane de proiectare AJAX
referitoare la interacțiunea cu utilizatorul:
efecte vizuale(One-Second Spotlight, One-Second Motion, Highlight)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Șabloane de proiectare AJAX
referitoare la interacțiunea cu utilizatorul:
funcționalitate (Lazy Registration, Direct Login, Timeout,
Heartbeat, Autosave, Unique URLs)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Șabloane de proiectare AJAX
inginerie Web:
monitorizare & diagnoză(Logging, Debugging)
vezi cursul următor
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Șabloane de proiectare AJAX
inginerie Web:
inspecție de cod/date (DOM Inspection, Traffic Sniffing)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Șabloane de proiectare AJAX
inginerie Web:
testare(Simulation Service, Browser-Side Test,
Service Test, System Test)
vezi cursul următor
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Comet
permite ca datele să fie „împinse” (push) de către server spre aplicația client, utilizând conexiuni HTTP
persistente (long-lived) în vederea reducerii latenței
complementar Ajax: long polling, HTTP server push, Reverse Ajax
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Comet
șablon de proiectare a aplicațiilor Webcare necesită realizarea de conexiuni persistente,
în stilul peer-to-peer
utilizat de aplicațiile Web intensiv interactive,eventual colaborative – e.g., Mibbit
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Comet
instrumente software – exemplificări:
Atmosphere – github.com/Atmosphere/atmosphere-javascript
APE (Ajax Push Engine) – www.ape-project.org
Axios – github.com/axios/axios
Fermata – github.com/natevw/fermata
Push – pushjs.org
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Comet
soluții alternative, moderne: adoptarea diverselor tehnologii HTML5
server-sent eventsWebSocket
detalii într-un curs viitor
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Ajax/Comet oferă suport pentru dezvoltarea de aplicații Web hibride – mash-ups
combinarea – în contextul nostru, la nivel de client –a conținutului ce provine din surse (situri)
multiple, oferind o funcționalitate/experiență nouă
„curentul” SaaS (Software As A Service)
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
mash-ups
Surse de date(data feeds)
Atom, RSS, geoRSS, microdate HTML5, RDFa,…
Interfețe de programare(API-uri)
specifice serviciilor publiceși de procesare JSON, XML etc.
Biblioteci/framework-uripentru dezvoltare
framework-uri Web genericesau oferite de organizații
Instrumente interactive(Web tools)
eventual, disponibile în „nori”
Platforme(Platform As A Service)
Digital Ocean, Heroku, Google Cloud Platform, MS Azure,…
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Crearea unui mash-up Web la nivel de clientDoCa (Dogs ‘n’ Cats)
imagini cu câini dog.ceo/dog-api/ – răspuns JSON:{ "status": "success", "message": "URL_imagine" }
+fotografii cu pisici aws.random.cat/meow – răspuns JSON:
{ "file": "URL_imagine" }
studiu de caz: DoCa
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
codul-sursă complet la jsfiddle.net/busaco/z2f3vp4m/
utilizăm două apeluri fetch()
pentru a prelua date JSON de la cele două servicii Web
(API-uri publice)
URL-urile obținute sunt folosite pentru a genera
cu DOM elementele <img />
corespunzătoare
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
inspectarea cererilor HTTP inițiate de program
dog.ceo folosește HTTP/2aws.random.cat recurge la HTTP/1.1
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
// verificăm dacă avem succes (codul de stare e 2XX)function status(response) {
if (response.status >= 200 && response.status < 300) {// cererea poate fi rezolvatăreturn Promise.resolve (response)
} else {// cererea a fost rejectatăreturn Promise.reject (new Error (response.statusText))
}}
// generăm în cadrul unui element identificat prin 'id'// elementul <img /> pentru a include URL-ul fotografiei // (parametrul 'url' dat funcției) ce reprezintă un animalfunction genImg (url, id) {
const elem = document.createElement ('img');elem.setAttribute ('src', url);document.getElementById (id).appendChild (elem);
}
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
const URLDOGS = 'https://dog.ceo/api/breed/dalmatian/images/random';
// folosim Dog API pentru a obține o imagine aleatorie// a unui câine dalmațian fetch (URLDOGS)
.then (status) // datele au fost recepționate cu succes?
.then (response => response.json ())
.then (json => {// procesăm datele JSON primite...// proprietatea 'message' stochează URL-ul imaginii câineluigenImg (json.message, 'dog');
}).catch (error => { // redăm eroarea survenitădocument.getElementById ('dog').textContent = error;
});
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
// similar pentru pisici…const URLCATS = 'https://aws.random.cat/meow';
// invocăm random.cat API pentru a obține fotografia unei/unor pisici fetch (URLCATS)
.then (status) // datele au fost recepționate cu succes?
.then (response => response.json ())
.then (json => {// procesăm datele JSON primite...// proprietatea 'file' stochează URL-ul fotografiei cu pisicigenImg (json.file, 'cat');
}).catch (error => { // redăm eroarea survenitădocument.getElementById ('cat').textContent = error;
});
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
inspectarea datelor obținute prin transfer asincron cu instrumentele pentru dezvoltatori ale browser-ului Web
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
performanță: scalabilitatea și latența
limite ale API-urilor + existența versiunilor multiple
drepturi de autor asupra datelor și licențiere
securitate: abuz, confidențialitate, încredere etc.
monetizare
lipsa unei interoperabilități reale între platforme
mash-ups
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
mash-ups
lista mash-up-urilor: www.programmableweb.com/mashups/directory
multe alte API-uri publice la github.com/toddmotto/public-apis
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Nu există o problemă de securitateprivind accesul la resurse via JavaScript?
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Same-Origin Security Policy
“restricts how a document or script loaded from one origin can interact with a resource from another origin”
astfel, un program JavaScript trebuie să acceseze doar datele aparținând aceleași origini
– i.e., provenite din același domeniu Internet
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
se permit doar transferuri vizând reprezentări de resursereferitoare la imagini, fișiere CSS
și alte programe JavaScript aparținând aceleași origini
clientserver Web
HTTPJSON, XML,…
APIpublic
APIpublic
HTTPJPG
HTTPJPG
Same-Origin Policy
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Same-Origin Security Policy
previne cazurile în care un document/program încărcatdintr-o origine să poată accesa/modifica proprietăți
ale unui document aparținând altei origini
developer.mozilla.org/Web/Security/Same-origin_policy
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
interactiune web: ajax – studiu de cazconst URL = "https://profs.info.uaic.ro/~busaco/teach/courses/web/";
// realizăm o cerere HEAD pentru a obține meta-date despre o resursălet client = new XMLHttpRequest ();client.open ("HEAD", URL, true);client.send ();client.onreadystatechange = function () {
// am recepționat câmpurile-antet?if (client.readyState == 2) {// semnalăm tipul MIME și data ultimei actualizărialert ("Resursa de tip '" +
client.getResponseHeader ("Content-Type") + "' s-a actualizat la " + client.getResponseHeader ("Last-Modified"));
}}
preluarea cu HEAD a unor meta-date, în mod asincron
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
URL al altui domeniuse încalcă Same Origin Policy
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
caz real: Google Mail
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
CORS (Cross-Origin Resource Sharing)
permite partajarea la nivel de client a resurselorprovenind din domenii Internet diferite
astfel, se pot emite cereri între domenii (cross-origin)
recomandare a Consorțiului Web (2014)www.w3.org/TR/cors/
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Politicile de partajare a resurselor se bazează pe anumite câmpuri din antetul mesajelor HTTP
exemplu (se permit doar cereri GET având în antetul mesajului câmpuri specifice din partea
unui client aparținând unui domeniu Internet):Access-Control-Request-Method: GET
Access-Control-Request-Headers: Content-Type, Accept
Origin: http://localhost:8000
resurse de interes:developer.mozilla.org/en-US/docs/Web/HTTP/CORS
auth0.com/blog/cors-tutorial-a-guide-to-cross-origin-resource-sharing/
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
API-ul furnizând imagini publice cu pisicihttps://aws.random.cat/meow
acceptă cereri GET emise de orice origine a clientului
Access-Control-Request-Method: GET
Access-Control-Allow-Origin: *
caz real #1
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Google Play acceptă cereri POST emise numai de serviciul Google Drive (originea este https://drive.google.com)
ce includ câmpuri-antet vizând autorizarea
Access-Control-Request-Method: POST
Origin: https://drive.google.com
Access-Control-Request-Headers: authorization,x-goog-authuser
câmp nestandardizat
caz real #2
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
Reddit.com permite cereri POST și OPTIONS formulate de orice origine, fiind acceptate anumite câmpuri-antet
(controlul accesului depinde de timp)
Access-Control-Allow-Headers: Content-Type,Origin,Accept,X-Signature
Access-Control-Allow-Methods: POST, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Max-age: 1728000
caz real #3
Dr.
Sab
in B
ura
ga
profs.in
fo.uaic.ro/~busa
co
episodul viitor: ingineria aplicațiilor JavaScript
ⵄ DOM
▣ view
▦model
⧆ template
🛢 storage
☄ events
changes
observes
renders
queries &writes to
emits