I have a hierarchy of tags within my HTML which all contain onclick
event handlers. The onclick
is pushed onto the event stack from the leaf back through the root of the hierarchy. I only want to respond to the leaf onclick
event. Can I flush the event stack rather than using a flag?
For instance:
<ul>
<li onclick="nada('1');"><a href="#1">1</a></li>
<li onclick="nada('2');"><a href="#2">2</a>
<ul>
<li onclick="nada('2.1');"><a href="#2.1">2.1</a></li>
<li onclick="nada('2.2');"><a href="#2.2">2.2</a></li>
<li onclick="nada('2.3');"><a href="#2.3">2.3</a></li>
</ul>
</li>
<li onclick="nada('4');"><a href="#4">4</a></li>
<li onclick="nada('5');"><a href="#5">5</a></li>
</ul>
Clicking on 2.2 using this function...
function nada(which)
{
alert(which)开发者_运维知识库;
}
...will result in two alerts for '2.2' and '2'.
What could I add to the nada function to eliminate the alert for '2'?
To stop the event bubbling up to parent elements you have to tell the event
object about it. In IE, you set event.cancelBubble= true
. In other browsers, you call event.stopPropagation()
.
You probably also want to turn off the default link-following action so that the browser doesn't keep jumping up to the top trying to follow the non-existing anchor links like #1
. In IE, you set event.returnValue= false
. In other browsers, you call event.preventDefault()
.
The event
object is accessible as window.event
on IE. On other browsers, it is passed into the event handler function. A way to pass the event into a function that works on both is:
<li onclick="nada('2.1', event);"><a href="#2.1">2.1</a></li>
function nada(n, event) {
alert(n);
if ('stopPropagation' in event) {
event.stopPropagation();
event.preventDefault();
} else {
event.cancelBubble= true;
event.returnValue= false;
}
}
However it would probably be better all round to put the onclick
event on the a
element which it usually belongs. This helps for accessibility, as the a
element will be focusable and keyboard-operable. And it means you don't have to worry about parents' click handlers being called.
(You can style the a
to look like a plain block, if you want.)
You can then also kick out the redundant onclick
links with a bit of unobtrusive scripting:
<ul id="nadalist">
<li><a href="#1">1</a></li>
<li><a href="#2">2</a>
<ul>
<li><a href="#2.1">2.1</a></li>
<li><a href="#2.2">2.2</a></li>
<li><a href="#2.3">2.3</a></li>
</ul>
</li>
<li><a href="#4">4</a></li>
<li><a href="#5">5</a></li>
</ul>
<script type="text/javascript">
var links= document.getElementById('nadalist').getElementsByTagName('a');
for (var i= links.length; i-->0;) {
links[i].onclick= function() {
alert(this.hash.substring(1));
return false;
}
}
</script>
精彩评论