IE6 and Mozilla loosing onclick event

P

Pavils Jurjans

Hello,

Here's the code I am testing with:

// ******************************************************

<html>
<head>
<title> IE6 loosing onclick event </title>

<script>
function bodyClick() {
document.f.trace.value = new Date() + '';
}

function testFn() {
var testTag = document.getElementById("testArea");
testTag.innerHTML = '<div style="background-color:Red"
onclick="testFn()">'+(new Date())+'</div>';
}
</script>

</head>

<body onclick="bodyClick()">
<form name="f">
<input type="text" name="trace" value=""/>
<span id="testArea">
<div style="background-color:Red" onclick="testFn()">Click
here</div>
</span>
</form>
</body>
</html>

// ******************************************************

Although body has onclick handler, it is not triggered when clicked on
the red area. This happens only in cases when the HTML that contains
tag with the onclick attribute which received the event, is overwriten
with a new value. Something like pulling the carpet out from ones
feet. This is not actually the expected behaviour. Why shouldn't the
document element receive onclick event anyway? This mishap causes some
bad things in my DHTML application, where it is assumed that any click
on the document area (except on ActiveX controls/java applets) is
handled by document.onclick handler.
Since this happens on both IE6 and Firebird (0.7), I guess this is
by-design, but it actually escapes me why. Perhaps somebody has better
idea?

Pavils
 
Y

Yann-Erwan Perio

Pavils said:
Although body has onclick handler, it is not triggered when clicked on
the red area. This happens only in cases when the HTML that contains
tag with the onclick attribute which received the event, is overwriten
with a new value.

You're playing with on-the-edge events aspects, which aren't supported
by Mozilla/IE (although successfully implemented by Opera 7). According
to the DOM Events Specification, the body onclick handler should indeed
be triggered.

<URL:http://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html>

<QUOTE>
The target's ancestors are determined before the initial dispatch of the
event. If the target node is removed during the dispatching, or a
target's ancestor is added or removed, the event propagation will always
be based on the target node and the target's ancestors determined before
the dispatch.
</QUOTE>


What probably happens with IE/Mozilla is that the event flow link isn't
saved before the event dispatch; we can reasonably assume that there's
no link at all, and that the browsers just follow the DOM hierarchy
(parentNode/childNodes) to process the event flow - when the target is
removed from the tree, the parentNode property is set to null so the
event cannot bubble toward the root element.
Perhaps somebody has better
idea?

What about adding the listener on the parent node, or change only the
node value, not the node itself?


HTH,
Yep.
 
P

Pavils Jurjans

Hello, Yann-Erwan

You explain this well. This really could be what's happening.
Currently I overcame this, replacing the event handler with function,
that calls window.setTimeout(originalFunction, 0). Now
document.onclick is properly called and then also original function is
handled. It is possible also to save the original event data, so the
only problem is that document.onlcick is now fired before the function
that was supposed to be the original inner tag trigger. But in my
design, that makes no difference.
What about adding the listener on the parent node, or change only the
node value, not the node itself?

In my actual design, the listener tag is much more levels deeper, so
these approaces don't help here. I am working on standardized
framework for client-side DHTML controls, that may have popups and
then some clicking is done on those popups. I handle the clicks on the
popups, but this action mey requere redrawing of the popup HTML, so
there is this on-the-edge event thing. I need to handle
document.onclick, because that helps to determine wether user has
clicked outside of active popup, and thus close it.

Thanks,

Pavils
 
Y

Yann-Erwan Perio

Pavils said:
Currently I overcame this, replacing the event handler with function,
that calls window.setTimeout(originalFunction, 0).

How frightening:) Browsers are event-based, using setTimeout this way,
even if this works, is just a hack - you might suffer a hell in
maintenance, Pavils.

This seems to be a conception issue; if you're ready to accept a global
handler (like your setTimeout thing suggests), then what about just
using document.onclick as a controller, which would then study the
target and redirect to appropriate actions?

document.onclick=function(evt){
var target;
evt=evt||window.event;
target=evt.target||evt.srcElement;
while(target.nodeType!=1) target=target.parentNode;
switch(target.id) {// or target.className, or target.<expando>
case "foo1": doFoo1.call(target, evt); break;
case "foo2": doFoo2.call(target, evt); break;
case "foo3": doFoo3.call(target, evt); break;
default:break;
}
}
I am working on standardized
framework for client-side DHTML controls, that may have popups and
then some clicking is done on those popups. I handle the clicks on the
popups, but this action mey requere redrawing of the popup HTML, so
there is this on-the-edge event thing.

Hmm then I really don't see why adding the listener on a specific DIV
wrapper wouldn't work:

<div onclick="...">
<div id="popupToBeRedrawned">

</div>
</div>


Anyway, your app seems to be quite complicated, so that's just
suggestions:)


HTH
Yep.
 
P

Pavils Jurjans

Hello,
How frightening:) Browsers are event-based, using setTimeout this way,
even if this works, is just a hack - you might suffer a hell in
maintenance, Pavils.

That's true, I'm no less scared, too :) So I am looking for decent
solution
then what about just using document.onclick as a controller, which would then study the target and redirect to appropriate actions?

That's actually a good idea. I'm just being somewhat conservative and
wanting to use basic event handlers, located in tag attributes.
Surely, there's no need to be so restrictive, so I'll try out how to
handle all this with single document.onclick handler. In fact, I wrote
a small class that enables multiple listener functionality, something
that IE is missing. Now I can subscribe my function to a certain
event, and there can be many such subscribers. That gives some freedom
in handling events coming from multiple controls.
Hmm then I really don't see why adding the listener on a specific DIV
wrapper wouldn't work:

<div onclick="...">
<div id="popupToBeRedrawned">

</div>
</div>

Well, no need for that anymore, as I'll redo the event handling so
that it's always document.onclick that get's called.

Regards,

Pavils
 

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
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top