Newsgroup: it.comp.lang.javascript
Titolo: Javascript Intercettare id oggetto cliccato...

Ciao a tutti...
Ho i seguenti problemi...
Dovrei inserire una funzione nel tag <BODY> scatenata dall'evento
onmousedown; fin qui nessun problema:
<BODY onmousedown="MiaFunzione()">
La funzione dovrebbe intercettare il pulsante premuto; anche qui tutto
ok (o quasi...):
function MiaFunzione()
{
alert(event.button)
}
Prima domanda: event.button funziona con tutti i browser?
Il problema nasce ora...
Seconda domanda: Posso intercettare l'id dell'oggetto su cui ho
cliccato? Se ho due oggetti sovrapposti devo intercettare solo l'id
dell'oggetto più avanti (quello sopra gli altri); è possibile?
Esempio:
<BODY onmousedown="MiaFunzione()">
<DIV id="Oggetto1">
<DIV id="Oggetto2">
</DIV>
</DIV>
</BODY>
Spero di essere riuscito a spiegarmi...
Qualcuno riescie ad aiutarmi?

 cliccato? [...]
Si può passare l'oggetto su cui hai cliccato nel seguente modo:
<BODY onmousedown="MiaFunzione(this)">
Dato che però nel nostro caso è necessario passare l'evento, si può
ricavare l'id utilizzando il target dell'evento stesso. Attenzione che
anche qua Mozilla e IE hanno delle proprietà con un nome diverso:
target (Mozilla) oppure srcElement (IE).
La funzione diventa:
function MiaFunzione(event)
{
   if (!event)
     event = window.event;
   var button = event.button;
   var target = event.target;
   if (!target)
     target = event.srcElement;
}
 > [...] Se ho due oggetti sovrapposti devo intercettare solo l'id
 > dell'oggetto più avanti (quello sopra gli altri); è possibile?
L'evento ha una proprietà calcelBubble (IE) oppure un metodo
stopPropagation (Mozilla) che fanno al caso nostro, per cui ecco
l'ultima versione della  funzione:
function MiaFunzione(event)
{
   if (!event)
     event = window.event;
   var button = event.button;
   var target = event.target;
   if (!target)
     target = event.srcElement;
   event.cancelBubble = true;
   if (event.stopPropagation)
     event.stopPropagation();
}
(Testato com Mozilla 1.7.5 e Internet Explorer 6)
Gaetano

 }
Mi piace...posso pubblicarla (con un grazie a te e link alla tua e-mail)?
www.criosoftware.it
-- 
"Emancipate yourselves from mental slavery;
None but ourselves can free our minds"
									    B.M.

 
www.criosoftware.it
Certo:-)
Se vuoi puoi indicare come mail: 
gaetano....@tiscali.it
Gaetano

 dell'oggetto più avanti (quello sopra gli altri); è possibile?
Separando il contenuto dalla forma, e con un pizzico di notazione
nostalgica:
<script type="text/javascript">
	function _GLOBAL_MOUSEDOWN_CALLBACK(evt){
		evt=evt||event||null;
 
		var sender=null;
		if (evt!=null)
			sender=evt.target||evt.srcElement||null;
 
		if (sender!=null)
			alert("sender:"+
sender.id
+"\nbutton:"+evt.button);
 
	};
 
	window.onload=function(){
		if (document.body)
			document.body.onmousedown=_GLOBAL_MOUSEDOWN_CALLBACK;
	}
</script>
<!-- codice di markup di esempio -->
<body>
	<div id="oggetto1">
		some text
		<div id="oggetto2">child text</div>
	</div>
</body>
In questo modo puoi fare a meno di "sporcare" il codice di markup.
-- 
ZER0
~ The Tangent Universe collapsed 5945 days, 8 hours, 25 minutes and 43 seconds ago.
on air ~ "Maki Kimura - Beyond The Bounds"

 gestito come proprieta' dell'oggetto window solo da IE.
Dimenticavo: il valore che ottieni dalla proprieta' button, puo' variare da
implementazione a implementazione.
-- 
ZER0
~ The Tangent Universe collapsed 5945 days, 8 hours, 31 minutes and 45 seconds ago.


 stopPropagation (Mozilla) che fanno al caso nostro, 
Beh, per quella specifica motivazione non e' necessario agire sulla
propagazione: E' gia' stato referenziato l'elemento interessato tramite
target/srcElement.
Tra l'altro mi pare che anche gecko abbia la proprieta' cancelBubble.
-- 
ZER0
~ The Tangent Universe collapsed 5945 days, 8 hours, 37 minutes and 9 seconds ago.


 target/srcElement.
Se non faccio calcelBubble/stopPropagation e ho due elementi annidati
con lo stesso event handler allora la funzione viene invocata due volte.
Tale situzione in IE non è gestibile in modo lineare.
Es.:
<div id="outer" onmousedown="MiaFunzione(event)">
   outer
   <div id="inner" onmousedown="MiaFunzione(event)">
     inner
   </div>
</div>
function MiaFunzione(evt)
{
   var target = evt.target;
   if (!target)
     target = evt.srcElement;
   alert(
target.id
);
}
In questo caso se faccio click su inner l'evento onmousedown verrà
scatenato due volte, prima su div inner e poi sul div outer.
Ma mentre in Mozilla l'evento ha una proprietà currentTarget
che mi dice appunto il target corrente (ovvero proprio prima
inner e poi outer) IE ha solo srcElement che corrisponde sempre
all'elemento iniziale anche se l'evento si sta progando su un'altro
elemento.
Nel nostro esempio tutti e due gli alert visualizzeranno "inner".
Esempio corretto solo per Mozilla:
// funziona solo con Mozilla
function MiaFunzione(evt)
{
   alert(
evt.currentTarget.id
);
}
Quindi: o si usa sempre cancelBubble/stopPropagation, oppure si deve
evitare di impostare la stessa funzione come handler dello stesso
tipo di evento su elementi innestati.
Oppure c'è un ultimo caso. Se io passo il "this" questo è effettivamente
il "target corrente". (Si deve proprio dire che la gestione degli eventi
in IE è stata pensata in maniera curiosa.)
Quindi se si scrive:
<body onmousedown="MiaFunzione(this, event)">
function MiaFunzione(elem, evt)
{
   alert("current target = " + 
elem.id
 + ", button = " + evt.button);
}
Questa funziona bene ma in effetti non è molto elegante.
(Comunque nel caso della domanda iniziale Francesco chiedeva
_esplicitamente_ di non propagare l'evento, quindi l'ultima azione
della funzione rispondeva al suo requisito.)
 > Tra l'altro mi pare che anche gecko abbia la proprieta' cancelBubble.
In effetti ho ricontrollato è l'oggetto Event ha una proprietà
calcelBubble, che però ho notato è una proprietà read only. Ovvero
se faccio
evt.cancelBubble = true
non ottengo nessun effetto.
(Testato solo con Mozilla 1.7.5)
Gaetano

 target/srcElement.
Ho capito cosa intentevi leggendo l'altro post. Ovvero si imposta
l'evento onmousedown solo sul body e si controlla appunto
l'elemento interessato con con target/srcElement.
Dipende però da come è fatto il markup. Se per esempio dentro al
div principale ci sono altri due div nel seguente modo:
<body>
	<div id="oggetto1">
		some text
		<div id="oggetto2">child text</div>
                 <div id="oggetto3">other child text</div>
	</div>
</body>
Se facciamo in questo modo se imposto l'evento sul body la funzione
viene invocata poi in tutti i casi, ovvero sia che io faccia clic su
oggetto1, che oggetto2 e oggetto3.
Se per esempio io voglio che l'evento si abbia solo su oggetto1 e 2, ma
non su oggetto3, allora sono costretto a impostare gli eventi sui
singoli oggetti e poi ad utilizzare cancelBubble/stopPropagation.
In ultima analisi dipende da come è strutturato il markup.
Gaetano

 _esplicitamente_ di non propagare l'evento,
Affatto, come ti ho riportato la sua domanda era di intercettare l'id
dell'oggetto cliccato (spiegando cosa intendeva per "oggetto cliccato");
e questo requisito era gia' stato soddisfatto utilizzando il
target/srcElement.
L'evitare la propagazione dell'evento, per soddisfare tale requisito, non
era assolutamente necessario (tra l'altro in quel contesto dubito che abbia
un qualche senso).
-- 
ZER0
~ The Tangent Universe collapsed 5945 days, 10 hours, 44 minutes and 57 seconds ago.
on air ~ "Puddle of Mudd - Blurry"

 In ultima analisi dipende da come è strutturato il markup.
Esatto. Ma il markup era stato fornito dall'utente, cosi' come la chiara
specifica di voler impostare l'event-handler sul tag body.
-- 
ZER0
~ The Tangent Universe collapsed 5945 days, 10 hours, 47 minutes and 55 seconds ago.


 un qualche senso).
In effetti in questo caso non è necessario evitare la propagazione.
Mi resta però il dubbio che Francesco nella domanda iniziale abbia
fatto l'esempio dell'evento sul body ma poi in realtà debba poi
impostare l'evento su altri oggetti. Leggendo infatti il frammento già
riportato sopra:
"Posso intercettare l'id dell'oggetto su cui ho cliccato? Se ho due
oggetti sovrapposti devo intercettare solo l'id dell'oggetto più
avanti (quello sopra gli altri)"
potrebbe sembrare che si voglia selezione uno ad uno questi oggetti
su cui impostare l'evento.
In caso contrario appunto non c'è bisogno di gestire la propagazione.
Gaetano

 su cui impostare l'evento.
No, altrimenti cadrebbe tutto il post a priori e non avrebbe senso.
Il suo problema e' impostare l'event handler sull'elemento body, ma
riuscire ugualmente a recuperare l'oggetto cliccato, che non
necessariamente deve essere il body, come mostra nel codice di markup che
copia.
Tale problematica ha senso nel contesto proposto, non di certo nel momento
in cui si imposta l'event-handler per singolo tag.
Se rileggi l'inizio del suo post ed il codice di markup che scrive,
dovrebbe essere abbastanza chiaro.
-- 
ZER0
~ The Tangent Universe collapsed 5945 days, 11 hours, 26 minutes and 39 seconds ago.
on air ~ "Videogames Radio"

 Certo:-)
http://www.criosoftware.it/default16.aspx
-- 
"Affacciati affacciati benedici, guardaci
 guardaci...guardaci!
 Tanto sono quasi duemila anni che stai a guardare!"
									    E.B.