我有一个正在侦听容器元素的事件监听器,我希望在单击时将活动类附加到它的任何子级(.container> div.active)。 (所以不要将活动类附加到.contain> div> ul.active)。
我的问题是我不完全确定.target
到达div.diary
的泡沫是什么?
http://jsbin.com/yereramaxe/edit?html,css,js,output
document.querySelector('.contain').addEventListener('click', diary);
function diary(e) {
if (e.target.className === 'diary') {
//?.classList.add('active');
}
}

* {
font-size:0;
padding:0;
margin:0;
}
.diary {
display:inline-block;
background:red;
width:33.33%;
box-sizing:border-box;
padding:10px;
}
li {
font-size:18px;
}
ul {
list-style-type: none;
}
div > ul > li {
display:inline-block;
width:33.33%;
}
.diary.active {
background:blue;
}

<div class="contain">
<div class="diary">
<ul>
<li>
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</li>
<li>
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</li>
<li>
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</li>
</ul>
</div>
<div class="diary">
<ul>
<li>
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</li>
<li>
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</li>
<li>
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</li>
</ul>
</div>
<div class="diary">
<ul>
<li>
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</li>
<li>
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</li>
<li>
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</li>
</ul>
</div>
</div>
&#13;
答案 0 :(得分:1)
由于e.target
将是实际发生点击的位置,您可以遍历该元素的父层次结构,直到找到相应的父diary
div,然后将active
类附加到那个父元素。
以下是一些代码,用于查找具有相应类名的父级:
function hasClass(elem, cls) {
var str = " " + elem.className + " ";
var testCls = " " + cls + " ";
return(str.indexOf(testCls) !== -1) ;
}
function addClass(elem, cls) {
if (!hasClass(elem, cls)) {
var oldCls = elem.className;
if (oldCls) {
oldCls += " ";
}
elem.className = oldCls + cls;
}
}
function removeClass(elem, cls) {
var str = " " + elem.className + " ";
elem.className = str.replace(" " + cls + " ", " ").replace(/^\s+|\s+$/g, "");
}
function findParentByClass(node, cls) {
while (node && !hasClass(node, cls)) {
node = node.parentNode;
}
return node;
}
将它们放在一起就是这样:
document.querySelector('.contain').addEventListener('click', function(e) {
var diary = findParentByClass(e.target, "diary");
// add active class to parent diary div
if (diary) {
addClass(diary, "active");
}
});
我猜你可能还想将其他.diary
div标记为不再有效。如果是这种情况,那么你可以这样做:
document.querySelector('.contain').addEventListener('click', function(e) {
var actives = document.querySelectorAll('.contain .active');
for (var i = 0; i < actives.length; i++) {
removeClass(actives[i], "active");
}
var diary = findParentByClass(e.target, "diary");
// add active class to parent diary div
if (diary) {
addClass(diary, "active");
}
});
当然,如果.classList
,addClass()
和hasClass()
函数与removeClass()
兼容,那么您可以替换.classList
方法。浏览器支持选择。
答案 1 :(得分:0)
从你的问题来看,我能理解的是,你想得到父母的分数。 &#39; li&#39;你点击了。 尝试这样做:
//Generic function to find an element or it's first ancestor with a given class name
function findParentWithClass(elem, className) {
//You can make this much more safer by going only up to a specific parent container
//If you want to be a bit more safer with checking classname read this http://stackoverflow.com/questions/5898656/test-if-an-element-contains-a-class
if(elem.className == className) {
console.log(elem);
return elem;
} else {
findParentWithClass(elem.parentElement, className);
}
}
function diary(e) {
findParentWithClass(e.target, 'diary');
}
document.querySelector('.contain').addEventListener('click', diary);
函数 findParentWithClass(element,className)检查元素是否具有特定的类名,如果为true,则返回元素,否则,它将转到父元素并检查父元素是否具有类这将以递归的方式发生,直到具有特定&#39; className&#39;找到了。