[英]Javascript Traverse DOM until class is reached
我有HTML像:
<div id="hooray" class="section">
<div>
<div>
<div id="click">click</div>
</div>
</div>
</div>
当我单击类click
div
时,我想向上移动DOM直到到达最近的section
并获取id
。
使用JQuery,我会使用像$().closest('div.section')
,但是如何在每个parentNode
中使用纯Javascript而不使用硬编码?
var node = document.getElementById('click').parentNode.parentNode....etc
您可以走向父链,寻找具有适当类的祖先。 此版本的代码允许在感兴趣的对象上有其他类名,因此可以更灵活地使用代码:
function hasClass(elem, cls) {
var str = " " + elem.className + " ";
var testCls = " " + cls + " ";
return(str.indexOf(testCls) != -1) ;
}
function closest(el, cls) {
while (el && el !== document) {
if (hasClass(el, cls)) return el;
el = el.parentNode;
}
return null;
}
因此,从您的点击处理程序中,您可以执行以下操作:
var id;
var target = closest(this, "section");
if (target) {
id = target.id;
// do whatever you want with the id
}
工作演示: http : //jsfiddle.net/jfriend00/6V7HG/
FYI,这个代码的一个版本,它可以采用任意的选择器,因为你基本上必须创建一个CSS选择器解析器然后评估一个给定的对象是否匹配该选择器中的所有需求,因此要复杂得多。 对于这个特定的操作来说,这可能比你想做的更多。
通常,你没有查找id的链,因为你可以直接获取带有该id的元素,所以我提供了一个使用类名的版本。 其他版本(如匹配属性的版本)也可以编写。
此版本比您的特定问题(返回目标元素而不是目标ID)更通用,允许您在更多情况下使用它。 如果你真的只想要一个返回目标id的函数,可以这样做:
function closest(el, cls) {
while (el && el !== document) {
if (hasClass(el, cls)) return el.id;
el = el.parentNode;
}
return null;
}
有很多方法可以做到这一点,你可以试试这个:
document.getElementById('click').onclick = function(e) {
e = e || window.event;
var el = e.target || e.srcElement;
if (el = el.parentNode) do { //its an inverse loop
var cls = el.className;
if (cls) {
cls = cls.split(" ");
if (-1 !== cls.indexOf("section")) {
console.log("here it is: ");
console.log(el);
break;
}
}
} while (el = el.parentNode); //its assignment
if (!el) {
console.log('not found !');
}
console.log('end..');
};
你可以使用Element.closest() :
let closestElement = document.getElementById('click').closest('.section');
这是一个显示其实际效果的片段:
console.log(document.getElementById('click').closest('.section').id);
<div id="hooray" class="section"> <div> <div> <div id="click">click</div> </div> </div> </div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.