El navegador crea un objecte image per a cada etiqueta <img ...> que troba a la pàgina i els va col·locant a l'Array document.images. Podem accedir a cada una a través d'aquest Array, utilitzant la forma

    d o c u m e n t . i m a g e s [ n u m ] . p r o p i e t a t

Per exemple, es poden mostrar les adreces de totes les imatges fent un bucle sobre aquest objecte

JavaScript proporciona, a més, un mètode constructor, new Image(), que permet carregar imatges sense haver d'escriure HTML. En tots dos casos, podrem consultar i, depenent del navegador, modificar les propietats de cada imatge. Les instàncies d'aquest objecte poden tenir un identificador i són sensibles a uns events. Són molts recursos, tot plegat.

  Conceptes JavaSript en aquest capítol
Constructor new Image() : crea una instància de l'objecte imatge, buida.
Propietat name : nom de la imatge, si en té.
Propietat src : (ja vista) adreça de l'arxiu. És l'única que permet modificar Netscape 4.7.
Propietat border : el" borde" de la imatge, si en té.
Propietats width i height : amplada i altura, respectivament.
Propietats hspace i vspace : espai buit a l'entorn de la imatge, horitzontal i vertical.
Propietat complete : (ja vista) determina si una imatge ja està totalment carregada.

  1.- Propietats de les imatges
Un cop s'ha carregat una imatge, des de JavaScript o HTML, s'estableixen les seves propietats. Ja n'hem vistes algunes en pràctiques anteriors, però ara les veurem totes. Bé, totes no. D'una banda ens deixem "lowsrc", que carrega un arxiu alternatiu en baixa resolució i està obsoleta. De l'altra, Internet Explorer mostra (i permet modificar) moltes més propietats. Només cal que obrim una pàgina amb l'Inspector d'objectes i mirem document.images[0].

Farem una pàgina amb un parell d'imatges, cadascuna dins d'un vincle. Les imatges han de tenir un nom i el vincle cridarà una funció JavaScript amb aquest nom com a paràmetre:

      <a href = "javascript:propImg( 'nom_de_la_imatge' )">
      <img name="
nom_de_la_imatge" src= . . .

La funció propImg(), que farem a la capçalera de la pàgina, rebrà el nom i crearà una variable local amb l'objecte: var nomImg = document[nom]

A continuació, declarem una variable "txt" que anirem omplint amb text i les propietats. Després de cada propietat escrivim '\n' per tal de forçar un salt de línia dins del text de la variable. No posem la propietat "complete" perquè l'hem vista a l'última pràctica del mòdul anterior i, en aquest cas, sempre és "true". Finalment, enviem una alerta amb el text creat.

<script language="javascript">
function propImg( nom ) {
  var nomImg = document[nom]
  var txt = 'Nom: ' + nomImg.name + '\n'
  txt += 'Arxiu: ' + nomImg.src + '\n'
  txt += 'Mides: ' + nomImg.width + ' x ' + nomImg.height + '\n'
  txt += 'Espai horitzontal: ' + nomImg.hspace + '\n'
  txt += 'Espai vertical: ' + nomImg.vspace + '\n'
  txt += 'Borde: ' + nomImg.border + '\n'
  alert( txt )
}
</script>
</head>

<body ...>
<h2>Propietats de les imatges</h2>
<a href="javascript:
propImg('Desert')">
<img name="Desert" src="images/foto1.jpg" hspace="2" border="0"></a>
<a href="javascript:
propImg('Marroc')">
<img name="Marroc" src="images/foto2.jpg" vspace="1" border="2"></a>
...
 
2.- Precàrrega
No cal crear una instància en JavaScript de les imatges que ja són a la pàgina, en HTML. De vegades, però, sí que l'haurem de crear si fem precàrrega. I, quan cal fer precàrrega? Doncs, en principi, quan hi hagi rollovers o moltes imatges a la pàgina. Cal tenir en compte que, a més del propi "pes" de cada imatge, el navegador ha d'establir una nova connexió, i això pot fer perdre molt de temps. No es guanya massa si la pàgina té un parell d'imatges grans. En canvi, si n'hi ha moltes de petites, la precàrrega és un gran invent.

En qualsevol cas, utilitzem el mètode constructor:

      var foto1 = new Image( [amplada] , [altura] )

Els paràmetres amplada i altura són opcionals. Si no els utilitzem, el constructor els llegeix de la pròpia imatge i els guarda ... quan l'hagi carregada del tot. El constructor, podríem dir, només crea l'estructura, però, de moment, buida. Per omplir-la cal carregar la imatge: 

      foto1.src = "images/natura01.jpg"

És evident que aquest mètode resulta lent. Si tenim moltes imatges, el millor és usar un bucle que les vagi carregant. Si les imatges tenen el mateix patró i van numerades, en tindrem prou amb un Array. Si no és així, i la majoria de vegades no ho serà, en necessitem dos. El primer contindrà les adreces (si més no, la part "diferent") i el segon, els objectes.

// Mètode directe (utilitzant variables)
<script language="javascript">

var foto1 = new Image()
foto1.src = 'images/foto1.jpg'
var foto2 = new Image()
foto2.src = 'images/foto2.jpg'
// ...
</script>

// Array i bucle, per a imatges indexades
<script language="javascript">
var imatge = new Array()
for ( i=1; i<5; i++ ) {
  imatge[i] = new Image()
  imatge[i].src = 'images/foto' + i + '.jpg'
}
</script>

// Utilitzant dos Arrays i un bucle
<script language="javascript">

var arxiu = new Array( 'primera', 'segona', 'tercera', 'quarta' )
var imatge = new Array()
for ( i=0; i<arxiu.lenght; i++ ) {
  imatge[i] = new Image()
  imatge[i].src = 'images/' + arxiu[i] + '.jpg'
}
</script>

 
3.- Intercanvi i rollovers
El que Dreamweaver anomena "imagen de sustitución" i la majoria "rollover" no és més que canviar una imatge per una altra de la mateixa mida, com a resposta a un event, en aquest cas, onMouseOver i el seu company, onMouseOut.

Això es pot fer de diverses maneres i pot tenir altres usos. Per exemple, no és imprescindible que hagi de canviar la imatge que té el ratolí a sobre. Tampoc ho és que només es pugui canviar una imatge, o que els events hagin de ser, necessàriament, aquests.

Per què cal precarregar les imatges que hem de substituir dinàmicament? És veritat que si assignem el nom de l'arxiu a la propietat .src a la pròpia definició dels events - onMouseOut i onMouseOver -, l'invent funciona, però cada cop que fem una substitució, la nova imatge s'intenta tornar a carregar del servidor. Amb la precàrrega, el navegador sap que té les imatges i les carrega a l'instant.

Del que es tracta és d'escriure una funció com a resposta a un event. Si tenim les imatges de la pàgina identificades, les podrem manipular. Internet Explorer ens permet modificar gairebé totes les propietats, Netscape 4.7 només "src", és a dir, el nom de l'arxiu.

En aquest cas, farem una funció chgImg() que no només faci l'intercanvi de la imatge enfocada, sinó que també haurà d'actualitzar una altra imatge. Comencem fent una precàrrega de les 7 imatges: dos botons enrera, dos endavant, les dues fotos que s'han de mostrar quan el ratolí passa sobre els botons i la foto per defecte.

Cridarem la funció des dels vincles, assignada als envents onMouseOut i onMouseOver:

  <a href="#" onMouseOut="chgImg('ant',0)" onMouseOver="chgImg('ant',1)">

Passem com a paràmetres l'identificador de la posició (el mateix que el "name" de la imatge) i el número que correspon a l'índex de l'Array que hem creat a la precàrrega. La funció els identifica com a "id" i "n" i els utilitza per fer l'intercanvi, sempre referit a l'Array:

  document[id].src = imatge[n].src

Aquí s'acaba l'efecte rollover que afecta els botons. Hem intercanviat una imatge per una altra, de la mateixa mida, com a resposta al pas del ratolí. Si no necessitem res més, ja es pot tancar la funció. En aquest cas, però, volem intercanviar una altra imatge en funció de quin sigui el botó sobre el qual ens hem situat, o no. Un condicional i un operador ternari ens ho solucionen.

Hi ha dos estats quan s'analitza el residu de dividir "n" per 2: si és zero (imatges amb índex parell, no som sobre cap botó), assigna la foto per defecte, que té l'índex 6. Si no és zero, assigna la foto 4 o 5, en funció que "n" sigui menor de 2, és a dir, assigna la primera (4) quan som sobre el botó de l'esquerra i la segona (5) quan som sobre el de la dreta.

<script language="javascript">
var imatge = new Array()
var arxiu = new Array( 'b_ant1', 'b_ant2', 'b_pos1', 'b_pos2', 'foto1', 'foto2', 'foto3' )
for ( var i=0; i<arxiu.length; i++ ) {
  imatge[i] = new Image()
  imatge[i].src = "images/" + arxiu[i] + ".jpg"
}
function chgImg( id, n ) {
  document[id].src = imatge[n].src
  if (n%2==0) document[ 'foto' ].src = imatge[6].src
  else document[ 'foto' ].src = imatge[ ( (n<2) ? 4 : 5 ) ].src
}
</script>
</head>

<body ...>
<img name='foto' src='images/foto3.jpg'><br><br>
<a href="#" onMouseOut="
chgImg('ant',0)" onMouseOver="chgImg('ant',1)">
<img name="ant" src="images/b_ant1.jpg" width="28" height="28" border="0"></a>
<a href="#" onMouseOut="
chgImg('pos',2)" onMouseOver="chgImg('pos',3)">
<img name="pos" src="images/b_pos1.jpg" width="28" height="28" border="0"></a>
...
 
En aquest codi hem usat, intencionadament, fotos de diverses mides, i no les hem especificades enlloc. Amb els navegadors que incorporen la versió 2 del DOM, quan es fa l'intercanvi, tot balla. Si, en canvi, ho provem amb Netscape 4.7, la pantalla es manté estable, però les fotos es mostren deformades.

Si no hi ha mesures assignades, l'explorador de Microsoft - que, recordem-ho, permet canviar mesures de forma dinàmica - assigna les originals de la imatge. Navigator 4.7 considera les propietats width i height només de lectura, i no permet que els scripts les modifiquin. Cal tenir-ho molt en compte a l'hora de programar.

Si quan posem la foto per defecte <img name='foto' src='images/foto3.jpg'> especifiquem les mides, els navegadors actuals es comportaràn com Netscape 4.7, i les imatges es veuran deformades. En canvi, no hi ha manera d'aconseguir que Netscape 4.7 les mostri amb les seves mides.

Quina és la solució? Doncs, en principi, utilitzant aquest mètode, no n'hi ha. Sempre que posem una imatge en una pàgina, Netscape 4.7 bloqueja les mesures i, si la volem canviar per una altra, o bé haurà de tenir les mateixes mides, o es veurà deformada.

Però, feta la llei, feta la trampa. Si s'han de tornar a escriure les instruccions per crear l'espai d'una imatge, doncs ho fem, dins d'una capa. Però aquesta és una altra història, que veurem més detalladament als mòduls següents.