[英]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.