简而言之:
点击给定HTML下面的链接,我需要获取具有“analytics”类的父级索引。例如,单击链接“myID2 Link 1”将返回1.
<ul id="myID1" class="analytics" data-attribute="hpg:shocking">
<li><a href="http://myurl.com/">myID1 Link 1</a></li>
<li><a href="http://myurl.com/">myID1 Link 2</a></li>
<li><a href="http://myurl.com/">myID1 Link 3</a></li>
</ul>
<ul id="myID2" class="analytics" data-attribute="hpg:expected">
<li><a href="http://myurl.com/">myID2 Link 1</a></li>
<li><a href="http://myurl.com/">myID2 Link 2</a></li>
<li><a href="http://myurl.com/">myID2 Link 3</a></li>
</ul>
<ul id="myID3" class="analytics" data-attribute="hpg:unexpected">
<li><a href="http://myurl.com/">myID3 Link 1</a></li>
<li><a href="http://myurl.com/">myID3 Link 2</a></li>
<li><a href="http://myurl.com/">myID3 Link 3</a></li>
</ul>
我尝试了什么:
我目前正在使用两个单独的循环,一个用于迭代父项,另一个用于向链接添加单击事件。
// helper function to check parent for a class
function hasParentWithClass(element, classname) {
if (element.className.split(' ').indexOf(classname) >= 0) {
return true;
}
return element.parentNode && hasParentWithClass(element.parentNode, classname);
}
// get all elements with class "analytics"
var analytics = document.querySelectorAll('.analytics');
var containerClass = [];
for (var z = 0; z < analytics.length; z++) {
var inc = z + 1;
containerClass.push(analytics[z].getAttribute('id'));
}
var links = analytics.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
links[i].addEventListener('click', function(e) {
e.preventDefault();
if (hasParentWithClass(this, 'analytics')) {
// output index of parent
} else {
// do nothing
}
}, false);
}
问题:
我正在努力使用第二个循环中第一个循环的逻辑。具体来说,从第二个for循环中搜索var containerClass以获取父级的索引,因为它存储在var containerClass中。 .indexOf对我不好。
实现这一目标的最直接,最有效的方法是什么?
答案 0 :(得分:1)
这比你想象的要简单得多。如果我们将click事件处理程序分配给父元素,我们可以使用事件冒泡来解决问题。当您单击链接时,它不仅会触发您单击的链接的click
事件,而且该事件也将通过该链接的祖先元素“冒泡”。如果我们在父级捕获事件,我们就可以得到它的索引。
另外,正如@Dave Thomas指出的那样,您的列表的HTML结构无效。
// Get all the .analytics elements
var analytics = document.querySelectorAll(".analytics");
// Loop through them
Array.prototype.slice.call(analytics).forEach(function(item, index, arry){
// Set up click event handlers for each of the parents
item.addEventListener("click", function(evt){
// Just access the index of the parent within the group
console.clear();
console.log("The index of the parent is: " + index)
// Now, display the index of the link within its parent .analytics element
// Get all the anchors in the current analytics container
var anchors = Array.prototype.slice.call(item.querySelectorAll("a"));
// Get the index of the anchor within the set of anchors
var idx = Array.prototype.indexOf.call(anchors, evt.target);
console.log("The index of the link within the parent is: " + idx);
});
});
<div id="myID1" class="analytics" data-attribute="hpg:shocking">
<ul>
<li><a href="#">myID1 Link 1</a></li>
<li><a href="#">myID1 Link 2</a></li>
<li><a href="#">myID1 Link 3</a></li>
</ul>
</div>
<div id="myID2" class="analytics" data-attribute="hpg:expected">
<ul>
<li><a href="#">myID2 Link 1</a></li>
<li><a href="#">myID2 Link 2</a></li>
<li><a href="#">myID2 Link 3</a></li>
</ul>
</div>
<div id="myID3" class="analytics" data-attribute="hpg:unexpected">
<ul>
<li><a href="#">myID3 Link 1</a></li>
<li><a href="#">myID3 Link 2</a></li>
<li><a href="#">myID3 Link 3</a></li>
</ul>
</div>
答案 1 :(得分:0)
这是另一种方式:
document.querySelectorAll('li').forEach((item) => {
item.addEventListener('click', (e) => {
const index = Array.from(item.parentNode.children).indexOf((item))
console.log(index);
})
})