Link within a div that has onclick

S

skultetc

Hey all,

I have a div displayed as a block with an onclick event that shows/
hides a different div underneath it. There is a link within the first
div that takes the user to a different page. My problem is that if the
user clicks the link, the onclick is also executed and the div
underneath is shown/hidden before the browser changes pages, which
makes things a little clunky looking. Is there any way to keep the
div's onclick from firing when the link is clicked? Here is some
example source of what I'm talking about:

<div style="display: block; width: 200px;" onclick="show_hide
('div2');">Some text with a <a href="otherpage.htm">link</a></div>
<div id="div2">Some other text</div>
 
R

RobG

Hey all,

I have a div displayed as a block with an onclick event that shows/
hides a different div underneath it. There is a link within the first
div that takes the user to a different page. My problem is that if the
user clicks the link, the onclick is also executed and the div
underneath is shown/hidden before the browser changes pages, which
makes things a little clunky looking. Is there any way to keep the
div's onclick from firing when the link is clicked? Here is some
example source of what I'm talking about:

<div style="display: block; width: 200px;" onclick="show_hide
('div2');">Some text with a <a href="otherpage.htm">link</a></div>
<div id="div2">Some other text</div>

Pass event and a reference to the div from the listener. In the
show_hide function, only hide the element if e.target/srcElement is
the div, e.g.


<script src="text/javascript">

function showHide(e, el, id) {
var tgt, el2;

if (e) {
var tgt = e.target || e.srcElement;

while (tgt && tgt.nodeType != 1) {
tgt = tgt.parentNode;
}
}

if (tgt == el) {
el2 = document.getElementById(id);

if (el2 && el2.style) {
el2.style.display =
(el2.style.display == 'none')? '' : 'none';
}
}
}
</script>

<div style="display: block; width: 200px;" onclick="
showHide(event, this, 'div2');
">Some text with a <a href="otherpage.htm">link</a></div>
<div id="div2">Some other text</div>
 
G

Gabriel Gilini

makes things a little clunky looking. Is there any way to keep the
div's onclick from firing when the link is clicked? Here is some
example source of what I'm talking about:

Yes.

Place this inside your onclick handler:

if (!e) var e = window.event;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();

ps: I'm supposing that you know that the "e" var represents an Event
[1] here, and how event handlers work in DOM Level2.
http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration

Cheers
 
R

RobG

Yes.

Place this inside your onclick handler:

Too late, the click has already reached the div. Cancelling bubbling
then won't stop the div from responding, however it will stop other
elements further up the DOM tree from responding.

if (!e) var e = window.event;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();

Presuming e was passed to the function in the first place. Since the
example was an in-line listener, event must be passed explicitly. And
since you want to stop propagation beyond the A element, the listener
must be on that, not the div.

ps: I'm supposing that you know that the "e" var represents an Event

Only if you assign it. Here's a simplistic working example using your
suggestion:


<script type="text/javascript">

function show_hide(id) {
var es = document.getElementById(id).style;
es.display = es.display == 'none'? '':'none';
}

function cancelProp(e) {
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
}

</script>

<div style="display: block; width: 200px;" onclick="
show_hide('div2');
">Some text with a <a href="otherpage.htm" onclick="
cancelProp(event);
">link</a></div>
<div id="div2">Some other text</div>
 
T

The Natural Philosopher

RobG said:
Too late, the click has already reached the div. Cancelling bubbling
then won't stop the div from responding, however it will stop other
elements further up the DOM tree from responding.
Easy way.

Replace the <A HREF> with a div with its own click handler which simply
chains to another program. Although the event would bubble up to the
containing div, my guess is that it will execute the 'nearest' event
first, and since that cause the window to exit, you should escape before
it changes it. Or use the local event to set a flag which the outer
level event handler can read and use to modify its behaviour.

In fact that may be simplest of all.

Add an onclick handler to the <a> element (or a container for it), that
sets a flag global flag, which if read as true by the outer onclick
handler, causes it to exit soundlessly.
 
G

Gabriel Gilini

Too late, the click has already reached the div.  Cancelling bubbling
then won't stop the div from responding, however it will stop other
elements further up the DOM tree from responding.

True, I overlooked it.
Presuming e was passed to the function in the first place.  Since the
example was an in-line listener, event must be passed explicitly.  And
since you want to stop propagation beyond the A element, the listener
must be on that, not the div.

Same as before, I was thinking about the A element.

[snip]

Cheers
 
G

Gabriel Gilini

Easy way.
Seriously?

Replace the <A HREF> with a  div with its own click handler which simply
chains to another program. Although the event would bubble up to the

So, are you suggesting that one should put a DIV element where an
anchor
should be, and add an event handler to it, emulating a hyperlink
behavior?
containing div, my guess is that  it will execute the 'nearest' event
first, and since that cause the window to exit, you should escape before
it changes it. Or use the local event to set a flag which the outer
level event handler can read and use to modify its behaviour.

That's what "bubbling" means. The event is fired in the EventTarget,
and
then bubbles up in the DOM chain. But you guessed wrong, before the
default
action of clicking a hyperlink is triggered, the registered event
handlers
will fire and the event will bubble, thus making possible to prevent
the
default action - following the hyperlink - in the propagation phase.
In fact that may be simplest of all.

Again, seriously?
I guess that you're not worried with graceful degradation at all.

[snip]

Cheers
 
S

skultetc

Thanks Rob and Gabriel. Putting the cancelProp in the link's onclick
worked like a charm.
 
T

The Natural Philosopher

Gabriel said:
So, are you suggesting that one should put a DIV element where an
anchor
should be, and add an event handler to it, emulating a hyperlink
behavior?

If it fries yer bacon, why not?

That's what "bubbling" means. The event is fired in the EventTarget,
and
then bubbles up in the DOM chain. But you guessed wrong, before the
default
action of clicking a hyperlink is triggered, the registered event
handlers
will fire and the event will bubble, thus making possible to prevent
the
default action - following the hyperlink - in the propagation phase.


Again, seriously?
I guess that you're not worried with graceful degradation at all.

There's enough graceless degradation on most browsers to make me lose
little sleep over graceful..


[snip]

Cheers
 

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

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top