3 回答

TA貢獻1155條經(jīng)驗 獲得超0個贊
問題是,當您這樣做時,parents.map(x => x.className)
您將獲得一個包含每個元素的完整類字符串的數(shù)組。所以結(jié)果看起來像(簡化)[ "child4 hello" ]
,你嘗試indexOf("child4")
在那個數(shù)組上做。由于沒有簡單的成員"child4"
,所以失敗了。
這是說明的有問題的代碼:
function getParents (el, _class) {
let doc = document
let parents = []
let p = el.parentNode
while (p !== doc) {
let o = p
parents.push(o)
p = o.parentNode
}
parents.push(doc)
let mappedClassName = parents.map(x => x.className)
console.log("mappedClassName", mappedClassName)
let indexOf = mappedClassName.indexOf(_class);
console.log("indexOf", indexOf)
return parents[indexOf]
}
document.querySelectorAll('.child1').forEach((e,i)=>{
console.log(getParents(e, 'child4'))
})
<div class="parent">
<div class="child5">
<div class="child4 hello"> <!-- problem here -->
<div class="child3">
<div class="child2">
<div class="child1">
3
</div>
</div>
</div>
</div>
</div>
</div>
此代碼適用于字符串:
let indexOf = "child4 hello".indexOf("child4");
console.log(indexOf);
但是,它不一定能正常工作:
//the class is NOT child4
let indexOf = "child42 hello".indexOf("child4");
console.log(indexOf);
您應(yīng)該使用Element.classList進行更準確的類檢查:
let div1 = document.getElementById("one");
let div2 = document.getElementById("two");
let _class = "child4";
console.log(`div1 has ${_class}`, div1.classList.contains(_class))
console.log(`div2 has ${_class}`, div2.classList.contains(_class))
<div id="one" class="child4 hello"></div>
<div id="two" class="child42 hello"></div>
如果你把它與Array#findIndex實現(xiàn)你想要的結(jié)合起來:
function getParents (el, _class) {
let doc = document
let parents = []
let p = el.parentNode
while (p !== doc) {
let o = p
parents.push(o)
p = o.parentNode
}
parents.push(doc)
return parents[parents.map(x => x.classList).findIndex(cl => cl.contains(_class))]
// ^^^^^^^^^ ^^^^^^^^^
}
document.querySelectorAll('.child1').forEach((e,i)=>{
console.log(getParents(e, 'child4'))
})
<div class="parent">
<div class="child5">
<div class="child4">
<div class="child3">
<div class="child2">
<div class="child1">
1
</div>
</div>
</div>
</div>
</div>
</div>
<div class="parent">
<div class="child5">
<div class="child4">
<div class="child3">
<div class="child2">
<div class="child1">
2
</div>
</div>
</div>
</div>
</div>
</div>
<div class="parent">
<div class="child5">
<div class="child4 hello"> <!-- problem here -->
<div class="child3">
<div class="child2">
<div class="child1">
3
</div>
</div>
</div>
</div>
</div>
</div>
您可以通過刪除.map和運行中的邏輯來使代碼稍微短一些.findIndex:
parents.findIndex(x => x.classList.contains(_class))
但是,盡管如此,您的算法只檢查classes。您可以使用以下命令輕松擴展它以使用任何選擇器Element.matches:
function getParents (el, selector) {
let doc = document
let parents = []
let p = el.parentNode
while (p !== doc) {
let o = p
parents.push(o)
p = o.parentNode
}
parents.push(doc)
return parents[parents.findIndex(x => x instanceof Element && x.matches(selector))]
// only check Elements -------------> ^^^^^^^^^^^^^^^^^^^^
}
document.querySelectorAll('.child1').forEach((e,i)=>{
console.log('.child4', getParents(e, '.child4'))
})
document.querySelectorAll('.child1').forEach((e,i)=>{
console.log('#parentTwo.child4', getParents(e, '#parentTwo.child4'))
})
<div class="parent">
<div class="child5">
<div id="parentOne" class="child4">
<div class="child3">
<div class="child2">
<div class="child1">
1
</div>
</div>
</div>
</div>
</div>
</div>
<div class="parent">
<div class="child5">
<div id="parentTwo" class="child4">
<div class="child3">
<div class="child2">
<div class="child1">
2
</div>
</div>
</div>
</div>
</div>
</div>
<div class="parent">
<div class="child5">
<div id="parentThree" class="child4 hello">
<div class="child3">
<div class="child2">
<div class="child1">
3
</div>
</div>
</div>
</div>
</div>
</div>

TA貢獻1828條經(jīng)驗 獲得超4個贊
問題是你得到一個元素列表,你將它們映射到元素' className,當目標元素有更多的child4類時,數(shù)組中的值將是child4 hello,當你正在尋找索引時child4數(shù)組中的值,child4 hello將不匹配。而不是Array.indexOf您可以使用Array.find.
function getParents (el, _class) {
let doc = document
let parents = []
let p = el.parentNode
while (p !== doc) {
let o = p
parents.push(o)
p = o.parentNode
}
parents.push(doc)
return parents.find(e => e.className.includes(_class))
}
document.querySelectorAll('.child1').forEach((e,i)=>{
console.log(getParents(e, 'child4'))
})
<div class="parent">
<div class="child5">
<div class="child4">
<div class="child3">
<div class="child2">
<div class="child1">
1
</div>
</div>
</div>
</div>
</div>
</div>
<div class="parent">
<div class="child5">
<div class="child4">
<div class="child3">
<div class="child2">
<div class="child1">
2
</div>
</div>
</div>
</div>
</div>
</div>
<div class="parent">
<div class="child5">
<div class="child4 hello"> <!-- problem here -->
<div class="child3">
<div class="child2">
<div class="child1">
3
</div>
</div>
</div>
</div>
</div>
</div>
getParents您可以使用Element.closest代替函數(shù)
下面是一個例子:
const parents = Array.from(document.querySelectorAll('.child1')).map(e => e.closest('.child4'));
console.log(parents);
<div class="parent">
<div class="child5">
<div class="child4">
<div class="child3">
<div class="child2">
<div class="child1">
1
</div>
</div>
</div>
</div>
</div>
</div>
<div class="parent">
<div class="child5">
<div class="child4">
<div class="child3">
<div class="child2">
<div class="child1">
2
</div>
</div>
</div>
</div>
</div>
</div>
<div class="parent">
<div class="child5">
<div class="child4 hello">
<!-- problem here -->
<div class="child3">
<div class="child2">
<div class="child1">
3
</div>
</div>
</div>
</div>
</div>
</div>
正如@Khauri 提到的,在第一個示例中,與其使用className屬性并使用字符串函數(shù)來檢查該值是否匹配,不如使用該classList屬性,因為它具有contains函數(shù)。

TA貢獻1854條經(jīng)驗 獲得超8個贊
您可以findIndex
像這樣使用Array 原型: return parents[parents.map(x => x.className).findIndex(x => x.indexOf(_class) > -1)]
function getParents (el, _class) {
let doc = document
let parents = []
let p = el.parentNode
while (p !== doc) {
let o = p
parents.push(o)
p = o.parentNode
}
parents.push(doc)
return parents[parents.map(x => x.className).findIndex(x => x.indexOf(_class) > -1)]
}
document.querySelectorAll('.child1').forEach((e,i)=>{
console.log(getParents(e, 'child4'))
})
<div class="parent">
<div class="child5">
<div class="child4">
<div class="child3">
<div class="child2">
<div class="child1">
1
</div>
</div>
</div>
</div>
</div>
</div>
<div class="parent">
<div class="child5">
<div class="child4">
<div class="child3">
<div class="child2">
<div class="child1">
2
</div>
</div>
</div>
</div>
</div>
</div>
<div class="parent">
<div class="child5">
<div class="child4 hello"> <!-- problem here -->
<div class="child3">
<div class="child2">
<div class="child1">
3
</div>
</div>
</div>
</div>
</div>
</div>
添加回答
舉報