JavascriptProva

sabato 28 aprile 2012

Ripasso organico di concetti elementari

Non ho ancora le idee chiare a proposito di alcuni concetti fondamentali.

Succede...

Chiamare una funzione presuppone sempre che questa sia una funzione dell'oggetto window.
Proviamo.
<html>
<head>
<script>
function funzione(){
 alert(this);
}
funzione();

</script>
</head>
<body>
</body>
</html>
E ottengo questo:
[object Window]
Quindi this si riferisce all'oggetto che ha chiamato la funzione!
Ora creo un nuovo oggetto e chiamo la funzione da questo oggetto:
<html>
<head>
<script>
function funzione(){
 alert(this);
}
var mia=new funzione();

</script>
</head>
<body>
</body>
</html>
E ottengo:
[object Object]
perchè adesso è mia a chiamare la funzione, non più window, come è quando non è preposto il nome alla funzione.

Bene. Per ora mi fermo qua.

sabato 21 aprile 2012

Oggetti

Ecco, una funzione può essere usata come oggetto.
Ho istanziato l'oggetto due volte usando parametri diversi:
<html>
<head>
<script>
function funzione(frase){
  alert(frase);
 }
var uno=new funzione("Ciao");
var due=new funzione("Minchia");
</script>
</head>
<body bgcolor=cyan>
</body>
</html>
Sì, funziona... Ricominciamo a reimparare da zero.
Ritorno a occuparmi di Javascript e altro...
<html>
<head>
<script>
function funzione(){
  alert("rieccomi!");
 }
funzione();
</script>
</head>
<body bgcolor=cyan>
</body>
</html>
...un codice semplicissimo come riscaldamento!

giovedì 8 marzo 2012

Studio di uno script di animazione

Spiegazione di uno script di animazione

cerchiamo di capire i principi di questa animazione...

Non viene stabilito soltanto lo spazio dello spostamento dell'elemento, ma anche il tempo.
Si calcola il tempo trascorso e lo si rapporta al tempo totale in cui si vuole che l'elemento compia il suo spostamento.
Sapendo che l'intero spostamento deve essere compiuto in un certo tempo, si aggiunge alla posizione iniziale lo spazio, rapportato all'intero spostamento, in cui l'elemento si dovrebbe trovare in quel dato momento.

Devo percorrere 10 cm in 10 secondi.
Dopo 1 secondo, calcolo il tempo trascorso, e ottengo 1 secondo.
Calcolo, e scopro che 1 secondo è 0,1 rispetto allo spostamento voluto.
Quindi devo aggiungere alla posizione iniziale dell'elemento lo spostamento moltiplicato per 0,1.

Cerco di tradurre questo nella funzione come viene rappresentata...

Calcolo il tempo trascorso:
...
this.start  = new Date().getTime();
...


this.next = function()
   {
      var now = new Date().getTime();
      if( (now - this.start) > time )
         return false;
      return this.ant = easing( (now - this.start) / time, this.ant);
   }
}
in caso di easing lineare il risultato è now-this.start/time, ossia la percentuale del tempo trascorso, che viene passato, se inferiore a 1, come parametro alla callback:
   this.init = function()
   {
      setTimeout(function()
      {
         if(!_this.next()){
            callback(1);
            _this.done = true;
            return;
         }
         callback(_this.next());
         _this.init();
      }, 13);
   }
...la quale callback è
   function(p){
      o.style.left = inizio + ((fine-inizio)*p)+'px';
   }
leggendo o (l'elemento) dalla funzione che la contiene, aggiunge all'inizio la percentuale dello spostamento totale (fine-inizio) pari alla percentuale del tempo trascorso rispetto al totale.

mercoledì 7 marzo 2012

Una palla che si gonfia e si sgonfia in Javascript

Ecco il codice di una palla che si espande e si riduce:
<html>
<head>
<style>
.celeste{
 position:absolute;
 top:200px;
 left:500px;
 width:300px;
 height:300px;
 background:cyan;
 border-radius:400;
 
}


</style>
<script>
function $(id){
 return document.getElementById(id);
}
var intervallo=2;
var tempo=10;
function gonfia(){
 var oggetto=document.getElementById("primo")
 oggetto.style.width=oggetto.offsetWidth+intervallo+"px";
 oggetto.style.height=oggetto.offsetHeight+intervallo+"px";
 oggetto.style.left=oggetto.offsetLeft-(intervallo/2)+"px";
 oggetto.style.top=oggetto.offsetTop-(intervallo/2)+"px";
 if (oggetto.offsetWidth>500 || oggetto.offsetWidth<100) intervallo=-intervallo;
 
 setTimeout(gonfia,tempo);
}
 
window.onload=gonfia;
</script>
</head>

<body>
<div id='primo' class='celeste'></div>


</body>
</html>
Non si può usare come intervallo il valore di 1, perchè non si può dividere un pixel per due, e quindi la palla non si espande uniformemente rispetto a un centro ma cambia posizione.

offsetWidth vs style.width

Devo adesso giustiziare definitivamente i dubbi che mi porto appresso sulla differenza fra offsetWidth, style.width e getComputedStyle.
Per fare questo, mi pongo due elementi, di cui il secondo ha un left in corrispondenza del termine del primo.
Saranno di colore differente.

Per calcolare la posizione del secondo sommo l'ampiezza del primo come style.width alla posizione del margine sinistro del primo (style.left). Ciò è possibile in quanto questo attributo di stile è stato definito all'interno del Javascript, in quanto il Javascript non legge i fogli di stile.
<html>
<head>
<style>
.celeste{
 position:absolute;
 top:100px;
 height:100px;
 background:cyan;
}

.rosso{
 position:absolute;
 top:120px;
 width:400px;
 height:100px;
 background:red;
}
</style>
<script>

function $(id){
 return document.getElementById(id);
}

function posiziona(){
 $("primo").style.left="0px";
 $("primo").style.width="400px";
 $("secondo").style.left=$("primo").offsetLeft+$("primo").style.width;
}
window.onload=posiziona;
</script>
</head>

<body>
<div id='primo' class='celeste'></div>
<div id='secondo' class='rosso'></div>

</body>
</html>
Ecco il posizionamento relativo dei due elementi:

Ora aggiungo un enorme bordo al primo elemento:
...
.celeste{
 position:absolute;
 top:100px;
 height:100px;
 background:cyan;
 border:50px solid blue;
}
...
ed ecco cosa accade:

Ora uso offsetWidth:

Senza bordo:
<html>
<head>
<style>
.celeste{
 position:absolute;
 top:100px;
 height:100px;
 background:cyan;
}

.rosso{
 position:absolute;
 top:120px;
 width:400px;
 height:100px;
 background:red;
}
</style>
<script>
function $(id){
 return document.getElementById(id);
}
function posiziona(){
 $("primo").style.left="0px";
 $("primo").style.width="400px";
 $("secondo").style.left=$("primo").offsetLeft+$("primo").offsetWidth;
}
window.onload=posiziona;
</script>
</head>

<body>
<div id='primo' class='celeste'></div>
<div id='secondo' class='rosso'></div>

</body>
</html>
E il risultato è uguale a prima:

Adesso rimetto l'enorme bordo:
...
.celeste{
 position:absolute;
 top:100px;
 height:100px;
 background:cyan;
 border:50px solid blue;
}
Ed ecco:


Conclusione:
style.width misura soltanto la larghezza dell'elemento senza tenere conto del bordo.
offsetWidth, invece misura anche le dimensioni del bordo.
Infatti, nella seconda immagine, si vede bene come il secondo elemento sia posizionato a una distanza dal margine destro del primo elemento pari a due volte la larghezza del bordo.

Per quanto riguarda getComputedStyle, dovrebbe dare la stessa misura di style.left, in quanto restituirebbe i valori degli attributi di stile, tornando utile per ottenerli qualora questi non siano specificati tramite Javascript ma in un foglio di stile.

Devo fare poi ancora qualche considerazione su offsetLeft e style.left...

Posizione assoluta di un elemento

Fammi un po' annotare questo, che poi me lo dimentico.
Ecco un piccolo script per localizzare la posizione di un elemento all'interno di un documento web:
<html>
<head>
<style>
#contenitore{
 position:absolute;
 left:200px;
 top:200px;
 width:400px;
 height:400px;
 background:cyan;
}

#contenuto{
 position:absolute;
 left:0px;
 top:50px;
 width:200px;
 height:200px;
 background:red;
}
</style>
<script>
function Posizione(oggetto){
 var x=0;
 var y=0;
 var obj=document.getElementById(oggetto);
 do{
  x+=obj.offsetLeft;
  y+=obj.offsetTop
 }while(obj=obj.offsetParent);
 return {x:x, y:y};
}
window.onload=function(){
 var pos=Posizione;
 alert(pos("contenuto").x+" "+pos("contenuto").y);
}
</script>
</head>

<body>
<div id='contenitore'>
 <div id='contenuto'>
 </div>
</div>

</body>
</html>