我有一个将用作菜单的网格,它包含一个由ul设置的顶行,其中显示3个li:在每个li中的内联块有一个ul并且在4 li之下。我已经指定了一个事件监听器来响应点击内部ul下的li,类是“inner” 您可以在此处查看代码:http://jsfiddle.net/jimeast123/qK2Ju/2/ 当我点击前两列中的项目时(您需要避免单击文本),当我点击第三列时没有响应,我得到预期的警报消息。我尝试使用不同数量的列,最后一列永远不会响应。
我的代码: HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>drop down</title>
<style>
body {
margin: 0;
padding: 0;
}
header {
height: 120px;
background-color: #eef;
}
.top {
background-color: #fee;
}
.top li {
display: inline-block;
width: 5.5em;
height: 1.5em;
border: 1px solid black;
text-align: center;
}
li {
list-style: none;
}
.inner {
margin-left: -2.55em;
display:block;
}
li a {
text-decoration: none;
}
.inner li {
display: block;
text-align: center;
background-color: #efe;
}
</style>
</head>
<body>
<!-- heading>h1+nav>ul.top>li*5>(a[href=#]>{menu$})>ul.inner>li*4>a[href=#]>{menu$} -->
<header>
<nav>
<header>
<nav>
<ul class="top">
<li><a href="#">menuA</a>
<ul class="inner" id="one">
<li><a href="#">item1</a></li>
<li><a href="#">item2</a></li>
<li><a href="#">item3</a></li>
<li><a href="#">item4</a></li>
</ul>
</li>
<li><a href="#">menuB</a>
<ul class="inner" id="two">
<li><a href="#">item1</a></li>
<li><a href="#">item2</a></li>
<li><a href="#">item3</a></li>
<li><a href="#">item4</a></li>
</ul>
</li>
<li><a href="#">menuE</a>
<ul class="inner" id="five">
<li><a href="#">item1</a></li>
<li><a href="#">item2</a></li>
<li><a href="#">item3</a></li>
<li><a href="#">item4</a></li>
</ul>
</li>
</ul>
</nav>
</header>
</nav>
</header>
<script src="dropdown.js"></script>
</body>
</html>
的javascript:
if (document.body.addEventListener) {
document.body.addEventListener('click', theHandler, false);
} else {
document.body.attachEvent('onclick', theHandler); //for IE
}
function theHandler(e){
e = e || window.event;
var target = e.target || e.srcElement;
if (target.className.match(/inner/)) {
//console.log("inner class was clicked");
alert("inner class was clicked");
}
}
答案 0 :(得分:3)
用户实际上无法点击.inner
元素,因为当他们尝试这样做时,他们实际最终点击的是.inner
对象中的子对象。因此,您将无法获得该课程的目标。
你有几个选择。首先,如果您的HTML不是使用JS代码动态创建的,那么您可以直接将事件侦听器应用于所有.inner
个对象,而正常的单击事件传播将导致它们在单击子节点时触发。
或者,如果您想将事件处理程序保留在正文中,那么解决方法可能是查看父链是否包含该类(您的目标将是.inner
以下的几个级别)。
function hasClass(elem, cls) {
var str = " " + elem.className + " ";
var testCls = " " + cls + " ";
return(str.indexOf(testCls) != -1) ;
}
function isTargetInClass(target, cls) {
while (target && target !== document.body) {
if (hasClass(target, cls)) {
return true;
}
target = target.parentNode;
}
return false;
}
function theHandler(e){
e = e || window.event;
var target = e.target || e.srcElement;
if (isTargetInClass(target, "inner")) {
//console.log("inner class was clicked");
alert("inner class was clicked");
}
}
答案 1 :(得分:0)
我认为这与您将事件监听器添加到正文的事实有关,而目标可能不是您所希望的(例如,这就是为什么点击文本不起作用)。你最好用这样的东西替换你的代码(需要jQuery):
$('.inner').click(function() {
alert('inner was clicked');
});
这会将点击处理程序添加到具有类inner
此外,你可能想要做一个“检查元素”,看看当你点击它们时的位置是你真正想要的。