Webové aplikace
JS OOP, časovače, regex, closure,
JS knihovny – Promise, jQuery, Require JS, NodeJS...
Připravil: Ing. Jiří Lýsek, Ph.D.
Verze: 2. 4. 2019
strana 2
Kolem JS je obrovský
ekosystém…
Knihy o JS
• M. Haverbeke: Eloquent JavaScript
– https://eloquentjavascript.net/
• N. C. Zakas: The Principles of Object
Oriented Javascript
strana 3
Objekty
• Konstruktor je pojmenovaná funkce
var Trida = function(p1, …) {…};
Trida.prototype.metoda =
function(p1, …) {…};
var instance = new Trida(p1, …);
instance.metoda(p1, …);
strana 4
Objekty - dědičnost
var Obdelnik = function(w, h) {
this.w = w;
this.h = h;
};
var Ctverec = function(s) {
Obdelnik.call(this, s, s);
};
Ctverec.prototype = new Obdelnik();
Ctverec.prototype.constructor = Ctverec;
strana 5
https://jsfiddle.net/7gmksyxp/
Čtverec je
potomek
obdélníka
(dědí)
Objekty - dědičnost
• nový JS (ES2015) má i klíčové slovo class a umí i extends
– https://babeljs.io/docs/learn-es2015/
– http://www.ecma-international.org/ecma-
262/6.0/
strana 6
Objekty - prototyp
• je sdílený
– lze jej modifikovat i pro existující instance
• neměnit prototyp vestavěných objektů
– např. Array, Object
– polyfill
strana 7
Není to
dobrý
nápad...
Objekty - valueOf, toString
• metody, které je možné implementovat
– valueOf
• použije se při porovnání s operátory <,>,…
– toString
• použije se při nutnosti přetypování na řetězec
strana 8
Objekty - vlastnosti
• Nová vlastnost se automaticky založí při
prvním použití
• Kontrola pomocí in
• Smazání pomocí delete
object.prop = "Neco";
console.log("prop" in object);
delete object.prop;
strana 9
Pozor
na "..."
JS a vlákna
• JS je jednovláknový
• WebWorkers API
– komunikace přes
události
strana 10
JS časovače
var callback = function() {…};
//opakovaně
var i = setInterval(callback, time);
//jednou
var t = setTimeout(callback, time);
//zrušení časovače
clearInterval(i);
clearTimeout(t);
https://jsfiddle.net/cf70nvc0/
strana 11
čas se
zadává
v ms
Regulární výrazy
• Nástroj pro popis pravidel parsování
– /vzor/modifikátory
– /[a-z0-9]+/i
• Použití
– složitější kontrola vstupu
– rozšířené porovnání řetězců
• http://www.w3schools.com/jsref/jsref_
obj_regexp.asp
strana 12
Regulární výrazy
• () dílčí výraz
• [] třída
• ?,*,+ 0/1zn., 0+ zn., 1+ zn.
• . libovolný znak
• \s,\w bílý znak, znak
• ^,$ začátek, konec řetězce
• \. escapování
strana 13
Implementace
• v JS nativněvar pattern = /^[a-z0-9._%+-]+@[a-z0-9.-
]+\.[a-z]{2,6}$/i;
pattern.test(str);
• v PHP funkcípreg_match("/^[a-z0-9._%+-]+@[a-z0-9.-
]+\.[a-z]{2,6}$/i ", $str);
strana 14
reálně je pravidlo pro
email daleko složitější
Uzávěr – closure
• kombinace funkce a "volných"
proměnných
• funkce v JS může použít proměnné z
prostředí, kde je deklarována (i když
nejsou globální)
– Funkce má potom přístup k hodnotám z
těchto proměnných i když je volaná v jiný
čas (události)
strana 15
Uzávěr – closure
function vytvorFunkci() {
var jmeno = "World!";
return function() {
alert("Hello " + jmeno);
};
}
var pozdrav = vytvorFunkci();
pozdrav();
https://jsfiddle.net/wm3pfkrf/
strana 16
Uzávěr – closure – prakticky
• Např. pro vytváření obsluhy událostí v
cyklu
• Nefunguje:
– https://jsfiddle.net/gw3hyp08/
• Funguje:
– https://jsfiddle.net/r3t732a1/
strana 17
V době volání obsluhy
události je už
proměnná i nastavena
na jmena.length
V ES 2015 se
dá použít let
Použití knihoven
• Reálně se API prohlížeče využívá
prostřednictvím knihoven
– fasáda nad API různých prohlížečů (vlastní
API)
– knihovna nás chrání před změnou chování
nativního API prohlížeče a rozdílnou
implementací mezi jeho verzemi
• knihovny: jQuery, YII, Dojo, Prototype,
…
strana 18
Facade VS Polyfill
• Polyfill je zástupná implementace API
prohlížeče (stejné API)
– pokud prohlížeč něco nepodporuje, nastaví
polyfill svou vlastní funkci
– jakmile to prohlížeč podporovat začne, polyfill se vypne (může se změnit chování)
if(!("localStorage" in window)) {
window.localStorage = function() {…};
}
strana 19
Příklad: registrace události pro W3C
kompatibilní a IE6 nebo 7
function addEvent(eventName, handler,
object) {
if(object.addEventListener) {
object.addEventListener(
eventName, handler, false);
} else {
object.attachEvent(
"on" + eventName, handler);
}
};
strana 20
Příklad: registrace události v
jQuery
$("div.trida").click(function(){
$(this).hide();
});
strana 21
CSS selektor, obecně najde
více HTML značek
obsluha
události
this je odkaz na objekt
odpovědný za vyvolání
události
…a je to stejné už od
začátku a ve všech
verzích knihovy
Frameworky a knihovny - přehled
• knihovny
– jQuery, MooTools, Dojo, YUI, Prototype,
Underscore, Sizzle, React, RequireJS …
• frameworky
– AngularJS, Ember, Knockout, Vue …
• GUI prvky
– Bootstrap, Foundation, jQuery UI,
Skeleton, Material design…
strana 22
Frontend knihovny
• Nezávislost na prohlížeči
– Někdy jsou převzaty do prohlížeče
• Použití
– DOM knihovny
• CSS selektory pro hledání prvků
• Práce s DOM a CSS
• Registrace a obsluha událostí
– AJAX komunikace
– Specifické (práce s JSON, Promise, ...)
strana 23
Obecně přináší
lepší/pohodlnější
přístup
Frontend knihovny
• Není dobré kombinovat všechno se
vším
– méně je více
– některé věci kombinovat nejdou (např.
Bootstrap a jQuery UI)
– Propojené ekosystémy (Bootstrap +
jQuery)
strana 24
Promise – ES 2015
• Implementace rozhraní pro obsluhu
asynchronních volání
– Původně knihovna
– Zlepšuje čitelnost kódu
• Jednotný interface,
– https://jsfiddle.net/8po2gLcf/
– https://developer.mozilla.org/cs/docs/We
b/JavaScript/Reference/Global_Objects/P
romise
strana 25
Promise – ES 2015
var p = new Promise(function(resolve, reject) {
if(confirm('Opravdu?')) {
resolve();
} else {
reject();
}
});
p.then(function() {
console.log('Uzivatel potvrdil akci');
}, function() {
console.log('Uzivatel zamitl akci');
});
• https://jsfiddle.net/8mhv1n3r/
strana 26
Většinou v jiném
modulu/souboru
Promise – ES 2015
• Metody:
– Instance:
• .then(resolve, reject) - standardní obsluha
• .catch(callback) - když je vyvolána výjimka
• .finally(callback) – cleanup
– Statické:
• .all() – více promise naráz
strana 27
Modernizr a HTML5shiv
• detekce nových HTML a CSS
vlastností, případná náhrada za vlastní
JS funkce a CSS styly
– polyfill
• http://modernizr.com/
• https://github.com/aFarkas/html5shiv
strana 28
pro starší prohlížeče
Sizzle
• jednoduchá knihovna realizující CSS
selektory pro hledání v DOM
• Vhodná pro jednodušší aplikace nebo
vlastní knihovny
– dnes je nahrazeno querySelector a
querySelectorAll
var elems = Sizzle(selector, context);
var elems = Sizzle("div .trida", elem);
strana 29
je součástí jQuery
jQuery
• nejpoužívanější
• většina volání se provádí přes tovární
(factory) funkci nazvanou "$", která
vrací jQuery objekt
– volání se dají řetězit
strana 30
jQuery
• umožňuje:
– práci s DOM
– práci s událostmi
– AJAX, AJAJ
– efekty a animace
– pluginy pro rozšíření
• např. i knihovny pro UI prvky - jQuery UI
– základ pro jiné knihovny (např.
Bootstrap)
strana 31
jQuery
• nevýhody
– metody mají mnoho kombinací
argumentů a podle nich se chovají
• rozsáhlá dokumentace (až moc)
– odstíní čistý JS (není vhodné pro
začátečníky)
• člověk neví, co je JS a co jQuery
– zavádí vlastní API, které nemusí umět
vše, co potřebujeme (fasáda)
strana 32
jQuery není
framework a není
vhodné pro tvorbu
rozsáhlých aplikací!
jQuery - použití
• stažení jQuery a přidání souboru do
hlavičky pomocí <script>
– http://jquery.com/
– obvykle před spuštěním vlastního JS
strana 33
Hledání v DOM pomocí CSS selektoru
$("#odstavec").…
$("div p.popis").…
$("form input[type=text]").…
• Vrací obecně kolekci prvků
var vse = $("…").get();
var prvni = $("…").get(0);
strana 34
Hledání v kontextu (podstrom)
strana 35
var elem = document.getEle…
$("div.neco", elem).…
hledá jen uvnitř
elem
Umí obalit i existující DOM objekt
nebo HTML
var elem = document.getEle…
$(elem).…
var $h1 = $("<h1>…</h1>");
strana 36
Modifikace DOM
//vlozi jako lastChild
$("…").append("<a href=\"…\">…</a>");
$("…").append( $("h1#presune") );
var element = document.get…
$("…").append( element );
//vlozi jako firstChild
$("…").prepend("<p>test</p>");
strana 37
Modifikace DOM
$("…").empty(); //vyprazdnit
$("…").remove(); //odstranit
$("…").remove("span.jen_toto");
var $elems = $("…").detach(); //odpojit
strana 38
Modifikace DOM
$("…").after("<p>vlozi za</p>");
$("…").before("<p>vlozi pred</p>");
strana 39
Nastavení/zjištění HTML obsahu
$("…").html("<p>novy obsah</p>");
$("…").html(); //vraci HTML
$("…").text("<p>jen text</p>");
$("…").text(); //vraci text
https://jsfiddle.net/2cpy1op7/
strana 40
Pozor na XSS!
Registrace událostí - na objekt
$(window).load(function() {
…
});
$(document).ready(function() {
…
});
strana 41
Registrace událostí - pomocí selektoru
$("…").click(function() {
…
});
$("…").on("…", function() {
…
});
$("…").off("…"[, handler]);
strana 42
selektor obecně vrací pole
známé události
přímo
libovolné
HTML Atributy
$("…").attr("name");
$("…").attr("name", value);
$("img").attr("src", "…");
$("a").attr("href", "…");
$("…").prop("checked");
$("…").removeAttr("name");
$("…").removeProp("name");
strana 43
attr je jen string
HTML Atributy - CSS třídy
$("…").hasClass("name");
$("…").addClass("name");
$("…").removeClass("name");
$("…").toggleClass("name");
https://jsfiddle.net/bu0ftLgv/
strana 44
Modifikace CSS
$("…").css("prop", "value");
$("…").css(
{
"prop1": "value2",
"prop2": "value2"
}
);
https://jsfiddle.net/jdnh0c05/
strana 45
JSON
Data atribut
$("…").data("cokoliv");
$("…").data("cokoliv", …);
<div data-cokoliv="…">…</div>
https://jsfiddle.net/w3w333L6/
strana 46
getter i
setter
AJAX v jQuery
• Metody:
– $.ajax(…)
– $.getJSON(url, callback)
– $.post(…)
– $.get(…)
• Příklad
– https://jsfiddle.net/tjmw224b/
strana 47
jQuery - vlastní funkce - tzv "plugin"
$.fn.nazev = function(p1, p2) {
//this je výsledek volání $("…")
};
$(window).load(function() {
$("…").nazev(…, …);
});
strana 48
jQuery - vlastní funkce - tzv "plugin"
$.fn.makeBold = function() {
//this je jQuery objekt
this.css("font-weight", "bold");
};
$(window).load(function() {
$("span").makeBold();
});
https://jsfiddle.net/wrejvqyf/
strana 49
jQuery UI
• různé prvky
– podobné jako Bootstrap
• možnost upravit a stáhnout online
• http://jqueryui.com/download/
strana 50
v dnešní době asi
překonané
Není vhodné
kombinovat…
Odkazy k jQuery
• http://youmightnotneedjquery.com/
– pokud vyvíjíte knihovnu, netvořte
zbytečné závislosti
• http://vanilla-js.com/
• http://www.caniuse.com
• http://www.jquery.com
strana 51
:-)
RequireJS
• Vhodné pro větší aplikace
• Zavádí do JS správu závislostí
– stromová struktura závislostí místo
ploché
– knihovna načítá skripty sama
• je nutné dodržet konvence pojmenování a
zařazení do složek
• http://requirejs.org/
strana 52
nemusím se
starat o pořadí
načtení <script>
RequireJS - příklad
define("modul1", ["modul2"], function(m2) {
…
return objekt;
});
define("modul2", function() {
…
return objekt;
});
require(["modul1"], function(m1) {
…
});
strana 53
pole závislostí
pole závislostí https://jsfiddle.net/xynLLshy/
Knihovny pro šablonování
• Náhrada za generování HTML značek
a elem.innerHTML/innerText
– Handlebars
• https://handlebarsjs.com/
– Mustache
• https://github.com/janl/mustache.js
– A další...
strana 54
Jaký je v
tom rozdíl?
Ostatní frameworky a knihovny
• někdy zavádí odlišný způsob práce
• každému vyhovuje něco jiného
• čistý JS je dobrý, pokud ho člověk
ovládne
– Pro menší aplikace
– jQuery má omezené využití a vede na
špagetový kód
– problém jsou prohlížeče a odlišnosti v jejich
API + těžkopádné DOM API prohlížeče
strana 55
Problém k zamyšlení
• Lze jen pomocí jQuery pohodlně
realizovat i rozsáhlé prezentace nebo
přímo aplikace?
• Lze nějak zjednodušit tvorbu JS
aplikací?
strana 56
Stahování JS knihoven
• Ručně
– Z konkrétní stránky
• NPM
– Repositář na https://npmjs.com
– Pomocí npm install ...
– Knihovny v node_modules
• Spousta zbytečných souborů
• Bundler nebo jiná
automatizace
strana 57
Něco jako
Composer v
PHP
Jazyky kompilované do JS
• správně tzv. "transpilace"
• lze psát kód v jiném jazyku a
kompilovat jej do JS
– TypeScript (řešení od MS)
– CoffeeScript (zajímavá syntaxe)
– Dart (statické typování, Google)
– …
strana 58
Odkazy
• http://coffeescript.org/
• https://www.dartlang.org/
• http://www.typescriptlang.org/
strana 59
NodeJS
• Běhové prostředí JS
– Umožní spouštět JS jako programy v
příkazové řádce
– Obsahuje a umožňuje používat NPM
– Žádný DOM, žádné XMLHttpRequest
apod.
• https://nodejs.org/
strana 60
Není to prohlížeč!
strana 61
Checkpoint
• Má jQuery ještě smysl?
• Jaký je rozdíl a použití fasády nebo
polyfill knihovny?
• Myslíte, že je nutné o konkrétních JS
knihovnách přednášet nebo je to věc
individuální volby a samostudia?
• Jsou nástroje jako NPM potřeba, co
přináší?
strana 62