Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Javascript Intercettare id oggetto cliccato...

462 views
Skip to first unread message

Francesco

unread,
Feb 8, 2005, 3:32:45 AM2/8/05
to
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?

Gaetano Bigliardi

unread,
Feb 8, 2005, 6:44:34 AM2/8/05
to
Francesco wrote:
> 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?

Per quanto riguarda Mozilla l'evento non è una proprietà di window
ma viene passato direttamente come parametro all'event handler. Quindi
dovrai fare:

<BODY onmousedown="MiaFunzione(event)">

function MiaFunzione(event)
{
if (!event)
event = window.event;

var button = event.button;
}

>
> Il problema nasce ora...
> Seconda domanda: Posso intercettare l'id dell'oggetto su cui ho

> 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

Cristiano Larghi

unread,
Feb 8, 2005, 6:49:51 AM2/8/05
to
In data Tue, 08 Feb 2005 12:44:34 +0100, Gaetano Bigliardi ha scritto:

> 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();
> }

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.

Gaetano Bigliardi

unread,
Feb 8, 2005, 8:20:23 AM2/8/05
to
Cristiano Larghi wrote:

>
> Mi piace...posso pubblicarla (con un grazie a te e link alla tua e-mail)?
> www.criosoftware.it

Certo:-)

Se vuoi puoi indicare come mail: gaetano....@tiscali.it


Gaetano

ZER0

unread,
Feb 8, 2005, 9:07:55 AM2/8/05
to
On 8 Feb 2005 00:32:45 -0800, Francesco wrote:

> Ho i seguenti problemi...
> Dovrei inserire una funzione nel tag <BODY> scatenata dall'evento
> onmousedown; fin qui nessun problema:

> La funzione dovrebbe intercettare il pulsante premuto; anche qui tutto
> ok (o quasi...):

Premessa: se tutto questo lo stai facendo per simulare il comportamento di
un menu' contestuale (pressione tasto destro su un elemento), esiste un
evento apposito che, tra le altre cose, funziona anche sulle varie shortcut
da tastiera (al contrario ovviamente del mousedown).

L'event handler in questione e' l'oncontextmenu.

> function MiaFunzione()
> {
> alert(event.button)
> }

> Prima domanda: event.button funziona con tutti i browser?

No, in primis perche' - come e' gia' stato detto - l'evento corrente e'
gestito come proprieta' dell'oggetto window solo da IE.

Seconda di poi, solo sui browser abbastanza recenti o che cmq seguono un
minimo le specifiche del DOM w3c. Sulle vecchie versioni di Netscape, ad
esempio, la proprieta' da usare e' "which".

In mancanza di informazioni in merito, continuo il post basandomi su
browser un minimo conformi alle DOM API del w3c.

> Il problema nasce ora...
> Seconda domanda: Posso intercettare l'id dell'oggetto su cui ho
> cliccato?

Certo.

> Se ho due oggetti sovrapposti devo intercettare solo l'id
> 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"

ZER0

unread,
Feb 8, 2005, 9:13:57 AM2/8/05
to
On Tue, 8 Feb 2005 15:07:55 +0100, ZER0 wrote:

>> Prima domanda: event.button funziona con tutti i browser?
>
> No, in primis perche' - come e' gia' stato detto - l'evento corrente e'
> 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.

ZER0

unread,
Feb 8, 2005, 9:19:21 AM2/8/05
to
On Tue, 08 Feb 2005 12:44:34 +0100, Gaetano Bigliardi wrote:

> <BODY onmousedown="MiaFunzione(event)">
>
> function MiaFunzione(event)
> {
> if (!event)
> event = window.event;

Sarebbe bene evitare nomi di variabili che potrebbero gia' esistere, come
"event".

Tra l'altro il controllo successivo che fai e' completamente inutile,
perche' l'evento corrente l'hai passato gia' come parametro.

Quindi con:

<body onmousedown="MiaFunzione(event)">

la funzione e':

function MiaFunzione(evt){
var btn=evt.button;
}

> > [...] 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,

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.

Gaetano Bigliardi

unread,
Feb 8, 2005, 10:59:12 AM2/8/05
to
ZER0 wrote:
> Tra l'altro il controllo successivo che fai e' completamente inutile,
> perche' l'evento corrente l'hai passato gia' come parametro.
>
> Quindi con:
>
> <body onmousedown="MiaFunzione(event)">
>
> la funzione e':
>
> function MiaFunzione(evt){
> var btn=evt.button;
> }

Vero...

>
>
>> > [...] 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,
>
>
> Beh, per quella specifica motivazione non e' necessario agire sulla
> propagazione: E' gia' stato referenziato l'elemento interessato tramite
> 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

Gaetano Bigliardi

unread,
Feb 8, 2005, 11:18:48 AM2/8/05
to
ZER0 wrote:

> Beh, per quella specifica motivazione non e' necessario agire sulla
> propagazione: E' gia' stato referenziato l'elemento interessato tramite
> 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

ZER0

unread,
Feb 8, 2005, 11:27:09 AM2/8/05
to
On Tue, 08 Feb 2005 16:59:12 +0100, Gaetano Bigliardi wrote:

>>> > [...] Se ho due oggetti sovrapposti devo intercettare solo l'id
>>> > dell'oggetto più avanti (quello sopra gli altri); è possibile?

[cut]


>> Beh, per quella specifica motivazione non e' necessario agire sulla
>> propagazione: E' gia' stato referenziato l'elemento interessato tramite
>> target/srcElement.

> Se non faccio calcelBubble/stopPropagation e ho due elementi annidati
> con lo stesso event handler allora la funzione viene invocata due volte.

No, stai confondendo il contesto. Rileggiti il post iniziale.

> Es.:
>
> <div id="outer" onmousedown="MiaFunzione(event)">
> outer
> <div id="inner" onmousedown="MiaFunzione(event)">
> inner
> </div>
> </div>

Per l'appunto.
Ma noi partivamo dal contesto in cui il solo elemento body aveva
l'event-handler impostato.
Se lo devo impostare per ogni tag mi cade il senso del discorso a priori.

> 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.

Infatti. Non era di certo questo il caso in cui eravamo.
Ti ricordo:

"Dovrei inserire una funzione nel tag <BODY> scatenata dall'evento
onmousedown;

(..)


La funzione dovrebbe intercettare il pulsante premuto;

(..)


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?"

> (Comunque nel caso della domanda iniziale Francesco chiedeva


> _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"

ZER0

unread,
Feb 8, 2005, 11:30:07 AM2/8/05
to
On Tue, 08 Feb 2005 17:18:48 +0100, Gaetano Bigliardi wrote:

> Dipende però da come è fatto il markup. Se per esempio dentro al
> div principale ci sono altri due div nel seguente modo:

[cut]


> 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.

Esattamente. Ed e' cio' che chiedeva l'utente.

> 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.

Oppure a gestire la cosa dalla funzione generale.
Non e' questo il punto. Il punto e', dato il contesto fornito dall'utente,
fornire la soluzione adeguata.

> 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.

Gaetano Bigliardi

unread,
Feb 8, 2005, 11:41:17 AM2/8/05
to
ZER0 wrote:

> "Dovrei inserire una funzione nel tag <BODY> scatenata dall'evento
> onmousedown;
> (..)
> La funzione dovrebbe intercettare il pulsante premuto;
> (..)
> 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?"
>
>
>>(Comunque nel caso della domanda iniziale Francesco chiedeva
>>_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).

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

ZER0

unread,
Feb 8, 2005, 12:08:51 PM2/8/05
to
On Tue, 08 Feb 2005 17:41:17 +0100, Gaetano Bigliardi wrote:

[cut]


> 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.

Dal contesto del post, direi proprio di no.
Cio' che desidera fare, come nelle frasi che ti ho riportato, e' appunto
impostare l'event-handler sul body senza necessariamente doverlo impostare
per singolo tag; ma ugualmente riuscire a recuperare l'elemento cliccato.

E per elemento cliccato, vuole intendere:



> "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)"

Questo, appunto.
Ovvero, "non voglio recuperare il body, che e' l'oggetto sul quale ho messo
l'event-handler, e quindi potrebbe essere inteso come 'l'elemento
cliccato'; bensi' solo l'oggetto piu' 'avanti'".

> potrebbe sembrare che si voglia selezione uno ad uno questi oggetti
> 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"

Cristiano Larghi

unread,
Feb 9, 2005, 5:05:54 AM2/9/05
to
In data Tue, 08 Feb 2005 14:20:23 +0100, Gaetano Bigliardi ha scritto:

> Certo:-)
http://www.criosoftware.it/default16.aspx

--
"Affacciati affacciati benedici, guardaci
guardaci...guardaci!
Tanto sono quasi duemila anni che stai a guardare!"
E.B.

0 new messages