Detect element on OnClick event of body?

N

Noozer

Is it possible to detect where on a page the click occurred when the OnClick
event of the BODY tag is fired?

Thx
 
R

RobG

Noozer said:
Is it possible to detect where on a page the click occurred when the OnClick
event of the BODY tag is fired?

Yes. You can get the x,y coordinates of the cursor or a reference to
the element that was actually clicked on.

Which do you want?

Here is information on finding the location of a click:

<URL:http://www.quirksmode.org/js/events_properties.html>


Here is information on the position of an element:

<URL:http://www.quirksmode.org/js/findpos.html>


Fill yer boots.
 
R

RobG

Danny said:
I gather you want to detect the child clicked on?
From the event object passed as argument or the event. object, get the
.target for mozilla/opera or srcElement for IE/opera, yes Opera does both,
the event.target/event.srcElement returns the child clicked on once the
evnet is on the parent.


function checkwho(ev) {
obj=(window.external) ? event.srcElement : ev.target;
// IE is the only browser with window.external

If the intention is to see if 'event' was passed to the function, the
logical thing to do is to check for that, not some property that you
think might indicate support for one event model or another. You might
also want to keep 'obj' local, there seems no point in it being a global
variable:

function checkwho( ev ) {
ev = ev || window.event;
var obj = ev.target || ev.srcElement;
alert(obj.nodeName)
}
document.body.onclick=checkwho;

The timestamp in your posts indicates that you sent them a day before
the post that they respond to. Can you please check your system clock?
Maybe it's an issue with your news server?
 
N

Noozer

RobG said:
Yes. You can get the x,y coordinates of the cursor or a reference to the
element that was actually clicked on.

Which do you want?

I was looking for the actual element that was clicked on, although finding
the actual X and Y coordinates could be helpful for other items.

BTW, your code doesnt work in IE or Firefox... Firefox does nothing, IE
complains that "nodeName is nul or not an object".

The code from Danny works in IE, but again doesn't do anything in Firefox...
v1.06 if it makes a difference.
 
R

RobG

Noozer wrote:
[...]
I was looking for the actual element that was clicked on, although finding
the actual X and Y coordinates could be helpful for other items.

BTW, your code doesnt work in IE or Firefox... Firefox does nothing, IE
complains that "nodeName is nul or not an object".

If you added it in the head, then yes, it'll fail since the body doesn't
exist when the script runs - it can't add an onclick to an element that
doesn't exist.

The links I posted give you very detailed explanations and working code,
use them in preference to any other code posted in this thread.

To get the posted code to work, add it in a script element just before
the closing body tag, or put it in the head and add the onclick with
window.onload. The following is purely an example, it is not intended
to be for a production web page:

<script type="text/JavaScript">

function showClickedElement( e )
{
e = e || window.event;
var obj = e.target || e.srcElement;
alert(obj.nodeName)
}

window.onload = function()
{
document.body.onclick = showClickedElement;
}
</script>

You should also remember that the body element does not necessarily
extend to the full extent of the window, either in width or height, so
clicking in the window may not fire the body's onclick event.

Adding the onclick to the HTML element works in IE and Firefox (then you
can click anywhere in the window), but the HTML spec does not include an
onclick event for it, so it may not be supported in all browsers.

The code from Danny works in IE, but again doesn't do anything in Firefox...
v1.06 if it makes a difference.

Nope.
 
N

Noozer

BTW, your code doesnt work in IE or Firefox... Firefox does nothing, IE
If you added it in the head, then yes, it'll fail since the body doesn't
exist when the script runs - it can't add an onclick to an element that
doesn't exist.

Doh! Thanks... wasn't thinking.
The links I posted give you very detailed explanations and working code,
use them in preference to any other code posted in this thread.

Will dig in.
To get the posted code to work, add it in a script element just before the
closing body tag, or put it in the head and add the onclick with
window.onload. The following is purely an example, it is not intended to
be for a production web page:

<script type="text/JavaScript">

function showClickedElement( e )
{
e = e || window.event;
var obj = e.target || e.srcElement;
alert(obj.nodeName)
}

window.onload = function()
{
document.body.onclick = showClickedElement;
}
</script>

You should also remember that the body element does not necessarily extend
to the full extent of the window, either in width or height, so clicking
in the window may not fire the body's onclick event.

Not a problem... If they aren't clicking on the content, I'm not interested.

Thanks!
 
G

Gérard Talbot

RobG a écrit :
If the intention is to see if 'event' was passed to the function, the
logical thing to do is to check for that, not some property that you
think might indicate support for one event model or another.

Also, the thing is that next week, maybe 3 browsers will start to
support window.external and those 3 browsers may not support
event.srcElement, therefore triggering later in the code an unresolved
js error.

You might
also want to keep 'obj' local, there seems no point in it being a global
variable:

function checkwho( ev ) {
ev = ev || window.event;

Sorry but that is not the best way to create the code IMO. It brings
unneeded difficulties when debugging. ev is both global and redefined:
from a debugging perspective, this is just creating more complexity.
Mozilla js strict warning feature will report this assignment as
potential problem.
var obj = ev.target || ev.srcElement;

Same here.

Gérard
 
R

Richard Cornford

Gérard Talbot said:
RobG a écrit :

Also, the thing is that next week, maybe 3 browsers will
start to support window.external and those 3 browsers may
not support event.srcElement, therefore triggering later
in the code an unresolved js error.

There is no need to wait until next week. The only way that the
assertion that IE is the only browser that implements a window.external
property is from a position of positive knowledge of _all_ existing
browsers (and all of their versions), to the extent of testing for the
existence of that property on each. If there is one thing that going out
and collection all of the scriptable web browsers that you can find
teaches you it that there is always at lest one more browser out here
that you have never heard off.

There is also the question as to whether IE is the only browser that
follows the IE event model. If another browser employs only a global -
event - object but does not provide window.external - then the code will
fail, while a direct test on the - ev - argument will be definitive
regardless of other features in a browser's object model.
Sorry but that is not the best way to create the code IMO.
It brings unneeded difficulties when debugging. ev is both
global and redefined: from a debugging perspective, this is
just creating more complexity. Mozilla js strict warning
feature will report this assignment as potential problem.

In my opinion (and subject to verifying that - ev - is a viable
reference following the assignment) that operation is optimal. There is
no issue with ev being global (it is not) and no reason not to assign a
value to it.

Mozilla's strict warnings seem to include some irrational (and frankly
silly) warnings, utterly inappropriate to cross browser scripting with
ECMAScript, and I would recommend anyone using that browser for the task
to switch them off and concentrate on real errors. Strict warnings
become counter-productive as soon as they start to include the bogus.

Richard.
 
G

Gérard Talbot

Richard Cornford a écrit :
In my opinion (and subject to verifying that - ev - is a viable
reference following the assignment) that operation is optimal.

The operation may be optimal; the coding manner is not without some
issue related to debugging, code legibility.

There is
no issue with ev being global (it is not) and no reason not to assign a
value to it.

Then how about simply:

function checkwho( ev )
{
var TheEventObject = ev || window.event;

or

function checkwho( ev )
{
var objEvt = ev || window.event;

so that the variable name (value and assignment) does not mask the
passed argument.
Mozilla's strict warnings seem to include some irrational (and frankly
silly) warnings, utterly inappropriate

Sometimes/often, they are useless, inappropriate; sometimes they are
not... the console won't provide long, detailed explanations on the issue.

to cross browser scripting with
ECMAScript, and I would recommend anyone using that browser for the task
to switch them off and concentrate on real errors. Strict warnings
become counter-productive as soon as they start to include the bogus.

Richard.

if(a=b)
{ ... };
will trigger a warning but if you're experienced, you can ignore such
warning. If you're really experienced, you'll avoid assignment when
using an if simply because it makes the code less reliable, reusable and
it does bring side effects, especially in iteration loops.
Some people do
if((a=b))
{ ... };
which is also ok but more mysterious...

Gérard
 
R

Richard Cornford

Gérard Talbot said:
Richard Cornford a écrit :


The operation may be optimal; the coding manner is not
without some issue related to debugging, code legibility.

It is difficult to see a single simple expression statement as having
low legibility, especially when it is such a common formulation and so
should be familiar. The only potential issue I see is that the behaviour
of the logical OR operation in ECMAScript is not the same as that
operation in other languages, such as Java, in that its result is any
value instead of being exclusively boolean. But ECMAScript authors don't
have much excuse for not learning the behaviour of the operators in the
language they are programming, or failing to appreciate the consequences
of ECMAScript being loosely typed.
Then how about simply:

function checkwho( ev )
{
var TheEventObject = ev || window.event;

or

function checkwho( ev )
{
var objEvt = ev || window.event;

Following this variable declaration and assignment it is not possible to
use the - ev - parameter because it is in an unknown state, and the
actual state of the variable used in its place still needs to be
verified before its use. So where is the benefit? You have a property of
the Variable/Activation object called - ev -, where is the benefit in
having another property of the Variable/Activation object created and
used in its place? Why suffer the overhead on each execution of the
function?
so that the variable name (value and assignment) does not
mask the passed argument.

ev = ev || window.event;

- does not "mask" the passed argument, it defaults it when its original
value is unusable. Indeed, function local variable declarations cannot
"mask" a function's formal parameters in ECMAScript. And this is one of
the serious faults in Mozilla's strict warnings as given:-

function f(x){
var x;
....
}

- Mozilla complains that: "Warning: Variable x hides argument", which is
a lie in a language where local variable declarations cannot "hide"
arguments. There is a warning to be given when that code is encountered,
but that warning is that the variable declaration is a futile action.
The actual warning given is bogusly worded and so potentially
misleading.

Sometimes/often, they are useless, inappropriate; sometimes
they are not... the console won't provide long, detailed
explanations on the issue.

Short and accurate warnings, suited to the language being used and its
application, would not be an issue. But as soon as you see warnings
being given in response to optimal practices, being issued
inconsistently, and especially the wording of warnings making false
assertions, it is best to dismiss those warnings as a tool and look for
something better.
if(a=b)
{ ... };
will trigger a warning but if you're experienced, you can
ignore such warning.

Experience may bring the understanding that may make automated linting
unnecessary. My concern here is more the consequences of showing wrong,
irrational and inappropriate warnings to the inexperienced.
If you're really experienced, you'll avoid assignment when
using an if simply because it makes the code less reliable,

Readable for who? ECMAScript authors should appreciate that all
expressions, including assignment expressions, result in values. What is
the problem with using the resulting value of any expression to make a
decision? For example, given the desire to default/normalise the event
object used above, and the need to verify the result:-

function checkwho(ev){
if((ev = (ev || window.event))){
... //function code using - ev
}
}

- gets everything that needs to be done to guard the function code done
in one - if - statment. In terms of execution it is optimal as the
result of each nested expression is directly employed in the
expression/statement that contains it, avoiding the need for that value
to be re-evaluated (in some sense) in later expressions/statements. Very
valuable in an event handler, which should handle its event as quickly
as possible so that the browser can get on with whatever else it needs
to be doing.

The factors that make code re-useable are unlikely to be significantly
influenced by this.
and it does bring side effects, especially in iteration loops.

An assignment inside an - if - statements expression is supposed to have
a side effect, that side effect is the assignment. In the event that all
true results of the - if - expression will require the local use of the
value assigned:-

if((a = document.forms.f.elements[x].value)){
... // code using a
}

- is more efficient than:-

if(document.forms.f.elements[x].value){
a = document.forms.f.elements[x].value;
... // code using a
}

- as it doesn't have to resolve - document.forms.f.elements[x].value -
twice.
Some people do
if((a=b))
{ ... };
which is also ok but more mysterious...

It is not that mysterious if you appreciate that all expressions result
in values. The main motivation for wrapping an assignment inside
parenthesise, rather than placing it directly in the parenthesise that
surround the expression of the - if - statement is to make the result
visually distinct form comparison expressions in the same context. So
that it is clear that the assignment is intended and not a typoed
comparison.

Richard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,169
Latest member
ArturoOlne
Top