2017-02-28 52 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一樣。 –

相關問題