2017-02-28 61 views
1

我知道如何使用parentNode,children和id来上下DOM,但我不知道如何通过标签名称来访问兄弟或子元素。如何使用元素标记名称上下DOM树?

这个代码示例有点人为的,但我希望你可以用它来帮助我使用这些元素标签名称进行导航的一般答案。

//fluff to create an example 
 
const outArr = Array(10).fill(0).map((el, i) => { return (
 
    '<p>Title ' + i + '</p>' + 
 
    '<p>Decription ' + i + '</p>' + 
 
    '<span>Other ' + i + '</span>' + 
 
    '<button>Click to Like' + i + '!</button>' 
 
)}); 
 
const output = outArr.join(','); 
 
document.getElementById('ex-container').innerHTML = output; 
 

 
//targeting inside anon event function for simplicity 
 
document.getElementById('ex-container').addEventListener('click', function(e) { 
 
    if (e.target.localName == 'button') { 
 
     const curEl = e.target 
 
     const parent = curEl.parentNode; 
 
     
 
     //I can access the parent node. If I had id's, I know I could targert 
 
     //children with those. How would I target the siblings, and from the 
 
     //parentNode target a specific child by element tagName, such as p? 
 
     console.log('curEl: ', curEl); 
 
     console.log('parent: ', parent); 
 
    } 
 
    e.stopPropagation(); 
 
});
<div id='ex-container'> 
 
<!-- everything goes here --> 
 
</div>

奖励:我如何透过标签名称较近p兄弟姐妹?

+1

你想做的事可以用jQuery或类似的库轻松完成一切。要做到这一点,没有jQuery和直接的DOM功能,请查看https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName和Element上定义的其他函数。 –

+0

“更近”是什么意思?因为在你显示的情况下,最接近''button'的'p'将会是下面带有“Title”的'p',除非它是最后一个'button',在这种情况下它将会不同。 –

+0

@Daniel Williams我知道如何通过tagName来定位元素,我想知道如何在DOM上遍历它们。例如:e.target.parentNode.span(但这不起作用,我在寻找正确的语法)。 –

回答

1

增加了一些属性来解决在源代码中注释的问题(无法理解问题)。详细信息由片段中的/* */发表评论。

代码片段

//fluff to create an example 
 
const outArr = Array(10).fill(0).map((el, i) => { 
 
    return (
 
    '<p>Title ' + i + '</p>' + 
 
    '<p>Decription ' + i + '</p>' + 
 
    '<span>Other ' + i + '</span>' + 
 
    '<button>Click to Like' + i + '!</button>' 
 
) 
 
}); 
 
const output = outArr.join(','); 
 
document.getElementById('ex-container').innerHTML = output; 
 

 
//targeting inside anon event function for simplicity 
 
document.getElementById('ex-container').addEventListener('click', function(e) { 
 
    /* Compare the currentTarget to the target, this way it 
 
    || will give you target to whatever you clicked not just a 
 
    || button 
 
    */ 
 
    if (e.target !== e.currentTarget) { 
 
    const curEl = e.target 
 
    const parent = curEl.parentNode; 
 
    // How would I target the siblings, 
 
    var bigBro = curEl.previousElementSibling; 
 
    var lilBro = curEl.nextElementSibling; 
 
    /* Collect all children of parent */ 
 
    var kids = parent.children; 
 
    // from the parentNode target a specific child by element tagName, such as p? 
 
    /* Same results for both with one difference being the 
 
    || first one is "live" NodeList the other "static" 
 
    || NodeList. 90% of the time, it's safer to go "static" 
 
    || using querySelectorAll() 
 
    */ 
 
    var paragraphsByTag = parent.getElementsByTagName('p'); 
 
    var paragraphsBySel = parent.querySelectorAll('p'); 
 

 
    console.log('curEl: ', curEl); 
 
    console.log('parent: ', parent); 
 
    console.log('bigBro: ', bigBro); 
 
    console.log('lilBro: ', lilBro); 
 
    /* Add .length property to get total number */ 
 
    console.log('Total Kids: ', kids.length); 
 
    /* NodeLists are array-like but not true arrays, so use 
 
    || Array.from() to convert them into true arrays. 
 
    */ 
 
    console.log('Paragraphs are: ', Array.from(paragraphsBySel)); 
 
    } 
 
    /* Specific by tagName is almost an oxymoron. If you 
 
    || want to target a specific element but only have 
 
    || tagNames, then as you commented, by index is the way 
 
    || to go. 
 
    */ 
 
    console.log('The 6th paragraph is: ', Array.from(paragraphsBySel)[5]); 
 

 
    e.stopPropagation(); 
 
});
<div id='ex-container'> 
 
    <!-- everything goes here --> 
 
</div>

+0

我打算继续这样做,因为它在移动方面看起来非常全面,并且涵盖了使用示例中的代码访问儿童的不同方式。我仍然希望能够找到一种方式来实现遍历DOM,并更有效地遍历DOM。例如console.log(e.target == e.target.parentNode.span.previousElementSibling.previousElementSiblingp.nextElementSiblingbutton)//记录为true –

+0

尝试使用jQuery,它具有一个名为[chaining]的功能(http://www.jquery -tutorial.net/introduction/method-chaining/)。链接允许将方法链接在一起。我通常不会向初学者推荐jQuery,因为我认为这会让他们错误地理解JavaScript,但看起来好像你对DOM有很好的把握。如果您正在寻找最完整的遍历DOM的方法,[treewalker](https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker)是一个选项,但其语法和操作是有点不同。 – zer00ne

1

结账document.querySelector()。您可以在节点上使用querySelector()以通过选择器选择子节点。防爆。

const parent = document.getElementById('someID') 
const firstP = parent.querySelector('p:first-child') 

parent将REF的元件用的someID ID,并从那里我们可以使用querySelectorparent以选择第一p标签。

这里有一个工作示例:

const parent = document.getElementById('someID') 
 
const firstP = parent.querySelector('p:first-child') 
 

 
firstP.style.color = 'red'
<div id="someOtherID"> 
 
    <p>First</p> 
 
    <p>Second</p> 
 
    <p>Third</p> 
 
    <p>Fourth</p> 
 
</div> 
 
<div id="someID"> 
 
    <p>First</p> 
 
    <p>Second</p> 
 
    <p>Third</p> 
 
    <p>Fourth</p> 
 
</div>

您可以使用相关document.querySelectorAll()创建匹配元素的数组,做沿着你想要的东西线,像这样:

const parent = document.getElementById('someID') 
 
const pees = parent.querySelectorAll('p') 
 

 
parent.pees = Array.from(pees) 
 

 
parent.pees[0].style.color = 'red'
<div id="someOtherID"> 
 
    <p>First</p> 
 
    <p>Second</p> 
 
    <p>Third</p> 
 
    <p>Fourth</p> 
 
</div> 
 
<div id="someID"> 
 
    <p>First</p> 
 
    <p>Second</p> 
 
    <p>Third</p> 
 
    <p>Fourth</p> 
 
</div>

+0

这绝对有帮助!你知道一种方法,我可以使用通用的附加方法来遍历它吗?比如e.target.parentNode.firstElement.p或类似的东西? –

+0

我已经用另一个例子更新了解决方案。 –

+0

这让我离胜利只有一步之遥。我现在可以通过链接querySelector伪造遍历,比如e.target.parentNode.querySelectorAll('p')[0]。我希望在那里有一个可以遍历标签的方式,就像我可以通过parentNodes,children和id's一样。 –

相关问题