Desenvolupament web dinàmic frontend amb javascript
Conceptes¶
Sessió 4: Objectes predefinits del llenguatge¶
Objectiu Sessió 4
L'objectiu d'aquesta 4a sessió serà la de treballar els diferents objectes permetent el control complert de la interfície.
Browser Object Model - BOM¶
Ja hem treballat el concepte de DOM (Document Object Model) a les sessions anteriors. De manera bàsica ens permet gestionar activament tots els elements web que conté la interfície generada pel codi HTML.
Tenim també una sèrie d’elements sota el model del navegador BOM (Browser Object Model) que permeten gestionar propietats i mètodes associats a la interfície, però no als elements web, com per exemple l'amplada de la finestra a on es mostra la web.
D’alguna manera tenim que l’objecte Window és el superior i per sota tenim, per exemple el document amb el concepte de DOM. Veiem-ho més complert:
graph TD;
Window-->document;
Window-->navigator;
Window-->screen;
Window-->history;
Window-->location;
Window-->console;
Utilitat
Javascript ens permet accedir directament a aquests objectes sense haver de passar per l’objecte window
L'objecte Window¶
Representa cada finestra oberta del navegador, i si el document conté frames, representa cada frame individual.
Permet obrir i tancar finestres, crear-ne de noves, moure-les i canviar-ne la mida, etc. També és l'objecte que gestiona els esdeveniments de temporització, que permeten executar codi donat un període de temps.
Utilitat
La variable global window
està exposada al codi per defecte, per tant no cal escriue window.
davant de cada propietat o mètode d'aquest objecte.
Per exemple, és el mateix utilitzar window.innerWidth
que directament innerWidth
.
Algunes propietats de window
a tenir en compte són:
propietat | informació que retorna | valor en aquest navegador |
---|---|---|
innerWidth | Amplada interior de la finestra actual en píxels | |
innerHeight | Alçada interior de la finestra actual en píxels | |
outerWidth | Amplada exterior de la finestra actual en píxels, comptant menús i barres laterals | |
outerHeight | Alçada exterior de la finestra actual en píxels, comptant menú superior, barra d'estat, etc. | |
scrollX | Desplaçament horitzontal de la finestra en píxels (només lectura) | |
scrollY | Desplaçament vertical de la finestra en píxels (només lectura) |
Pàgines amb exemples basats en la posició de scroll
L'objecte window també dona accés a l'emmagatzematge local a través de l'objecte Storage
i les seves propietats localStorage i sessionStorage, que veurem més endavant.
Alguns mètodes de window
a tenir en compte són:
mètode | funció que realitza | exemple |
---|---|---|
alert() | Obre una finestra emergent amb un missatge | Prova-ho |
confirm() | Obre una finestra emergent que demana confirmació a un missatge i retorna un booleà en funció de la resposta de l'usuari | Prova-ho |
prompt() | Obre una finestra emergent amb un missatge que retorna la cadena introduida per l'usuari | Prova-ho |
print() | Obre el diàleg d'impressió per la pàgina actual | Prova-ho |
scroll() | Desplaça la finestra a una posició donada | Prova-ho |
Window (MDN)
L'objecte Document¶
Representa tot el contingut del document actual, on cada element és representat com un node que forma part del model d'objectes del document (DOM)
Conté subobjectes que representen els diferents tipus d'elements d'un document: formularis, enllaços, imatges, etc. i té propietats i mètodes per manipular qualsevol element del document (getElementById
, write
, etc.)
Referència
Document (MDN)
L'objecte Navigator¶
Conté informació sobre el navegador i la plataforma sobre la que s'està executant el codi JavaScript.
Permet per exemple identificar el tipus i versió del navegador i el sistema operatiu de treball. Gràcies a això es pot determinar si és necessari prendre alguna decisió que afecti al codi a executar, però cal tenir en compte que és un paràmetre modificable per l'usuari i per tant no sempre serà fiable.
propietat / mètode | informació que retorna | valor en aquest navegador |
---|---|---|
navigator.platform | sistema operatiu | |
navigator.userAgent | agent d'usuari | |
navigator.javaEnabled() | Java habilitat? |
Identificació del navegador
Per raons històriques de compatibilitat, tots els navegadors s'identifiquen com a Mozilla
Navigator (MDN)
L'objecte Screen¶
Conté informació sobre la pantalla del dispositiu que està utilitzant l'usuari.
És útil per poder adaptar la presentació de l'aplicació a la mida disponible, o per mostrar elements centrats a la pantalla.
propietat | informació que retorna | valor en aquest navegador |
---|---|---|
screen.width | amplada de la pantalla en píxels | |
screen.height | alçada de la pantalla en píxels | |
screen.colorDepth | profunditat de color | bits |
Atenció!
La forma recomanada d'adaptar el contingut a la pantalla del dispositiu és utilitzant media queries de CSS.
Screen (MDN)
L'objecte History¶
Conté l'historial del navegador per la finestra o pestanya activa.
Per protegir la privacitat dels usuaris, no permet conèixer la URL de les adreces individuals, sinó només desplaçar-se per la llista i saber-ne la mida. S'utilitza principalment per poder recular una pàgina en el navegador sense necessitat d'especificar una adreça de destinació concreta.
propietat / mètode | informació que retorna | valor en aquest navegador |
---|---|---|
history.length | número d'elements a l'historial | |
history.back() | anar a la pàgina anterior | Vés-hi |
history.forward() | anar a la pàgina següent | Vés-hi |
history.go( -n ) | anar n pàgines enrere | Vés 2 pàgines enrere |
History (MDN)
L'objecte Location¶
Conté informació sobre la URL actual, i en pot extreure parts concretes com el domini, protocol o port.
Permet també recarregar la pàgina actual o carregar una pàgina nova.
propietat / mètode | informació que retorna | valor en aquest navegador |
---|---|---|
location.href | URL completa de la pàgina actual | |
location.protocol | Protocol que utilitza la URL | |
location.host | Nom del servidor i port | |
location.hostname | Domini de la URL | |
location.port | Port la de URL, si en forma part | |
location.pathname | Part corresponent a la ruta de la URL | |
location.search | Paràmetres de la URL si n'hi ha, incloent el ? |
|
location.hash | Marcador dins la pàgina, incloent el # |
|
location.reload() | Recarrega la pàgina actual | Recarrega |
location.assign(url) | Carrega la url indicada | Carrega URL |
location.replace(url) | Carrega la url subtituint l'actual a l'historial de navegació | Reemplaça URL |
Propietat útil!
Si modifiquem el valor de location.href
el document carregarà la nova pàgina.
D'aquesta manera podem aconseguir el mateix comportament que en clicar un enllaç, però des de codi JavaScript i sense interacció per part de l'usuari.
Location (MDN)
L'objecte Console¶
L'objecte console proporciona accés a la consola de depuració dels navegadors. Els detalls de com funciona varien de navegador a navegador, però hi ha un conjunt de característiques que de facto són proporcionades generalment.
propietat / mètode | informació o acció | exemple |
---|---|---|
console.clear() | Neteja la consola | Console.clear() |
console.log | Escriu l'expressió a la consola | Console.log |
Funcionalitat molt útil!
Ens anirà molt bé usar-lo com a métode de depuració o seguiment del que fa un codi javascript
Console (MDN)
Controlem el temps¶
Sota l'objecte window tenim uns mètodes que ens permeten temporitzar esdeveniments o accions.
setInterval() Executa indefinidament una funció cada interval de mil·lisegons donat
function missatge() {
console.log("Ha passat un segon");
}
// S'executarem la funció missatge cada segon indefinidament
let intervalMissatge = setInterval( missatge, 1000);
clearInterval() Cancel·la un setInterval() en progrés, sempre que l'haguem assignat a una variable:
setTimeout() Executa una sola vegada una funció després d'un nombre de mil·lisegons donat
function missatge() {
alert("Han passat cinc segons");
}
// S'executarem la funció missatge un sol cop després de 5 segons
let intervalMissatge = setTimeout( missatge, 5000);
clearTimeout() Cancel·la un setTimeout() en progrés, sempre que l'haguem assignat a una variable:
Els mètodes setInterval i setTimeout són intercanviables:
function missatge() {
/// ...
let temps = 1000;
setTimeout(missatge, temps);
}
// setTimeout funcionant com un setInterval,
// es reinicia cada cop que acaba el temps
setTimeout(missatge, 1000);
Avantatge
La variable temps podria tenir diferents valor en funció de condicions del codi.
function missatge() {
/// ...
if (condicioFinal) clearInterval(interval);
}
// setInterval funcionant com un setTimeout,
// la funció determina si continua o l'aturem
let interval = setInterval(missatge, 1000);
Avantatge
Podem aturar el comptador en funció de condicions del codi cada cop que s'executa la funció.
Important
Els intervals de temps d'aquests dos mètodes no són exactes, ja que estan en funció del temps que necessiti la funció que es crida per executar-se. Si el temps necessari per executar la funció és major que l'interval de repetició establert, s'anirà acumulant un error de temps a cada execució. Si necessitem comptar temps exactes és millor utilitzar l'objecte Date.
requestAnimationFrame¶
requestAnimationFrame()
és una funció de JavaScript que permet sincronitzar la teva animació amb la taxa de refresc del navegador, oferint un rendiment més suau i eficaç per a animacions gràfiques o canvis visuals continus al DOM.
- callback: Una funció que s'executarà abans de pintar el següent frame. Rep com a argument un timestamp que representa el temps, en mil·lisegons, des que la pàgina es va carregar.
- requestID: Un identificador únic que es pot utilitzar per cancel·lar l'animació amb cancelAnimationFrame(requestID).
Exemple
const box = document.getElementById("box");
let position = 0;
function animate(timestamp) {
position += 1; // Incrementa la posició
box.style.transform = translateX(${position}px);
if (position < 300) {
requestAnimationFrame(animate); // Demana el següent frame
}
}
requestAnimationFrame(animate); // Inicia l'animació
Alguns objectes més 💡¶
JavaScript disposa d'una sèrie d'objectes predefinits i independents del navegador que podem utilitzar en tot moment, entre ells:
Math¶
Permet realitzar operacions matemàtiques.
Conté una sèrie de constants matemàtiques (PI
, E
, etc.) que actuen com a propietats, així com diferents mètodes relacionats amb operacions matemàtiques.
Tingueu en compte que...
L'objecte Math no té constructor. És estàtic, per tant les seves propietats i mètodes es poden utilitzar directament sense crear-ne primer una instància.
Math (MDN) JavaScript Math Object (W3Schools) JavaScript Math Reference (W3Schools)
String¶
Permet manipular cadenes de text.
Té una sola propietat (length
) i diversos mètodes per operar sobre cadenes.
Tingueu en compte que...
El constructor d'objectes string no es sol utilitzar
és més eficient utilitzar-lo com a tipus de dades, i l'assignació crea l'objecte implícitament
String (MDN)
Date¶
Serveix per treballar amb dates i hores.
Per treballar amb l'objecte Date
cal crear-ne una instància amb new
indicant la data que volem representar.
Si ometem els paràmetres ens retorna la data actual del sistema.
Podem representar qualsevol altra data utilitzant el format:
any, indexMes, dia, hora, minut, segon, mil·lisegon
Tingueu en compte que...
Només l'any i el mes són obligatoris:
new Date(any, indexMes)
new Date(any, indexMes, dia)
new Date(any, indexMes, dia, hora)
new Date(any, indexMes, dia, hora, minut)
new Date(any, indexMes, dia, hora, minut, segon)
new Date(any, indexMes, dia, hora, minut, segon, mil·lisegon)
Els camps omesos es consideren com: dia 1 del mes i hora 00:00:00.000
Important!
Els mesos es numeren amb un índex a partir de 0 (gener) i fins a 11 (desembre) Cal tenir present que hem de posar un número menys del que normalment correspondria al calendari
new Date(); // Data i hora actuals
new Date(2010, 4); // 01/05/2010 a les 00:00:00
new Date(2024, 11, 25); // Dia de Nadal a les 00:00:00
new Date(2024, 0, 15, 23, 30); // 15/01/2024 a les 23:30:00
Date (MDN)
Canvas¶
Un canvas és un element HTML que representa una àrea d'imatge a la pàgina.
Amb javascript
podem gestionar i manipular imatge de mapa de bits.
Abans de res caldrà tenir l'element HTML
Podrem accedir a aquest element i crear un contexte en 2d. tot seguit dibuixem
canvas (MDN)
Canvas
<!doctype html>
<html lang="ca">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Exemple 9</title>
</head>
<body>
<canvas id="myCanvas" width="300" height="150"></canvas>
<button>Dibuixa rectangle</button>
<script>
const boto = document.querySelector("button");
boto.addEventListener("click", function() {
const myCanvas = document.getElementById("myCanvas");
const ctx = myCanvas.getContext("2d");
ctx.fillStyle = "red";
ctx.fillRect(20, 20, 150, 100);
});
</script>
</body>
</html>
SVG¶
Un SVG és un gràfic vectorial que podem inserir al nostre HTML.
El podem incloure i controlar amb javascript
com si fos un element més del DOM i modificar els seus atributs dinàmicament.
Ho farem amb:
SVG
Exemples¶
Exemple Rellotge
Tenim aquest resultat:
<script>
function actualitzaHora() {
// guardem la data i hora actual a una variable
let d = new Date()
// guardem cada valor de l'hora (h:m:s) per separat
let h = d.getHours().toString().padStart(2, "0")
let m = d.getMinutes().toString().padStart(2, "0")
let s = d.getSeconds().toString().padStart(2, "0")
// cadena que conté tots els valors de l'hora amb els separadors
let hora = h + ":" + m + ":" + s
// escrivim la cadena amb l'hora dins de l'objecte HTML "rellotge"
document.getElementById("rellotge").innerHTML = hora
}
// creem un temporitzador que invoca la funció "actualitzaHora" cada 1000 mil·lisegons (1s)
setInterval( actualitzaHora, 1000 )
// forcem l'actualització sense esperar el primer interval
actualitzaHora()
</script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Exemple</title>
<style>
body {
background-color: lightgrey;
}
#rellotge {
font-family: 'Montserrat', sans-serif;
text-shadow: 2px 2px 5px rgba(0,0,0,0.3);
font-weight: bold;
font-size: 3em;
padding: 0.25em 0.5em;
border: 4px solid black;
background-color: white;
position: fixed;
bottom: 10px;
right: 10px;
}
</style>
</head>
<body>
<span id="rellotge"></span>
<script>
function actualitzaHora() {
// guardem la data i hora actual a una variable
let d = new Date()
// guardem cada valor de l'hora (h:m:s) per separat
let h = d.getHours().toString().padStart(2, "0")
let m = d.getMinutes().toString().padStart(2, "0")
let s = d.getSeconds().toString().padStart(2, "0")
// cadena que conté tots els valors de l'hora amb els separadors
let hora = h + ":" + m + ":" + s
// escrivim la cadena amb l'hora dins de l'objecte HTML "rellotge"
document.getElementById("rellotge").innerHTML = hora
}
// creem un temporitzador que invoca la funció "actualitzaHora" cada 1000 mil·lisegons (1s)
setInterval( actualitzaHora, 1000 )
// forcem l'actualització sense esperar el primer interval
actualitzaHora()
</script>
</body>
</html>
Tenim un <span>
que és on mostrarem el rellotge
Tenim una funció function actualitzaHora()
on obtenim la data i hora actual let d = new Date()
Llavors obtenim exactament la hora, minut i segon
// guardem cada valor de l'hora (h:m:s) per separat
let h = d.getHours().toString().padStart(2, "0")
let m = d.getMinutes().toString().padStart(2, "0")
let s = d.getSeconds().toString().padStart(2, "0")
// cadena que conté tots els valors de l'hora amb els separadors
let hora = h + ":" + m + ":" + s
ja només ens queda mostrar-la modificant el codi HTML a dins de l'element Rellotge.
Tot plegat la màgia radica a la funció de setInterval( actualitzaHora, 1000 )
, que fa la crida a la funció actualitzaHora
, justament cada segon (1000 ms).
p2-s4-exe-Rellotge.html p2-s4-exe-Rellotge.html :fontawesome-solid-download:
Exemple Scroll
Tenim aquest resultat:
<script>
const box = document.querySelector('#caixa')
window.addEventListener("scroll", function (e) {
let scrollPercentage = (document.documentElement.scrollTop + document.body.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight)
box.style.right = scrollPercentage * (window.innerWidth - 120) + "px"
})
</script>
<!DOCTYPE html>
<html lang="ca">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Exemple scroll</title>
<style>
body {
height: 5000px;
color: white;
background-image: url('media/leaves.jpg');
}
h1 {
position: fixed;
font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
}
#caixa {
position: fixed;
width: 100px;
height: 100px;
background-color: red;
right: 0px;
top: 100px;
}
</style>
</head>
<body>
<h1>Fes scroll per veure l'animació del requadre</h1>
<div id="caixa"></div>
<script>
const box = document.querySelector('#caixa')
window.addEventListener("scroll", function (e) {
let scrollPercentage = (document.documentElement.scrollTop + document.body.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight)
box.style.right = scrollPercentage * (window.innerWidth - 120) + "px"
})
</script>
</body>
</html>
Tenim un <div>
que és on mostrarem la caixa
Obtenim l'element amb queryselector
Llavors programem l'esdeveniment Scroll
window.addEventListener("scroll", function (e) {
let scrollPercentage = (document.documentElement.scrollTop + document.body.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight)
box.style.right = scrollPercentage * (window.innerWidth - 120) + "px"
})
Calculem el percentatge segons la posició de l'scroll i l'alçada
Finalment modifiquem la posició de la caixa des de la posició dreta.
p2-s4-exe-Scroll.html p2-s4-exe-Scroll.html :fontawesome-solid-download: