DOM, elementler ve içerikleri ile her Åeyi yapmamıza izin verir, ancak önce ilgili DOM nesnesine ulaÅmamız gerekir.
DOM üzerindeki tüm iÅlemler document nesnesiyle baÅlar. Bu nesneden herhangi bir düÄüme eriÅebiliriz.
DOM düÄümleri arasında dolaÅmaya izin veren baÄlantıların bir görüntüsü:
Bunlara daha ayrıntılı deÄinelim.
Ãstte: documentElement ve body
En üstteki aÄaç düÄümleri doÄrudan document özellikleri olarak kullanılabilir:
<html>=document.documentElement- En üstteki belge düÄümü
document.documentElementâtir. Bu,<html>etiketinin DOM düÄümüdür. <body>=document.body- Yaygın olarak kullanılan baÅka bir DOM düÄümü,
<body>elementidir âdocument.body. <head>=document.head<head>etiketidocument.headolarak mevcuttur.
document.body, null olabilir.Bir komut dosyası (script), çalıÅma anında mevcut olmayan bir öÄeye eriÅemez.
Ãzellikle, bir komut dosyası <head> içindeyse, tarayıcı henüz okumadıÄı için document.body kullanılamaz.
Bu nedenle, aÅaÄıdaki örnekte ilk alert null gösterir:
<html>
<head>
<script>
alert( "From HEAD: " + document.body ); // null, there's no <body> yet
</script>
</head>
<body>
<script>
alert( "From BODY: " + document.body ); // HTMLBodyElement, now it exists
</script>
</body>
</html>
null means âdoesnât existâIn the DOM, the null value means âdoesnât existâ or âno such nodeâ.
Children: childNodes, firstChild, lastChild
There are two terms that weâll use from now on:
- Child nodes (or children) â elements that are direct children. In other words, they are nested exactly in the given one. For instance,
<head>and<body>are children of<html>element. - Descendants â all elements that are nested in the given one, including children, their children and so on.
For instance, here <body> has children <div> and <ul> (and few blank text nodes):
<html>
<body>
<div>Begin</div>
<ul>
<li>
<b>Information</b>
</li>
</ul>
</body>
</html>
â¦And all descendants of <body> are not only direct children <div>, <ul> but also more deeply nested elements, such as <li> (a child of <ul>) and <b> (a child of <li>) â the entire subtree.
The childNodes collection provides access to all child nodes, including text nodes.
The example below shows children of document.body:
<html>
<body>
<div>Begin</div>
<ul>
<li>Information</li>
</ul>
<div>End</div>
<script>
for (let i = 0; i < document.body.childNodes.length; i++) {
alert( document.body.childNodes[i] ); // Text, DIV, Text, UL, ..., SCRIPT
}
</script>
...more stuff...
</body>
</html>
Please note an interesting detail here. If we run the example above, the last element shown is <script>. In fact, the document has more stuff below, but at the moment of the script execution the browser did not read it yet, so the script doesnât see it.
Properties firstChild and lastChild give fast access to the first and last children.
They are just shorthands. If there exist child nodes, then the following is always true:
elem.childNodes[0] === elem.firstChild
elem.childNodes[elem.childNodes.length - 1] === elem.lastChild
Thereâs also a special function elem.hasChildNodes() to check whether there are any child nodes.
DOM collections
As we can see, childNodes looks like an array. But actually itâs not an array, but rather a collection â a special array-like iterable object.
There are two important consequences:
- We can use
for..ofto iterate over it:
for (let node of document.body.childNodes) {
alert(node); // shows all nodes from the collection
}
Thatâs because itâs iterable (provides the Symbol.iterator property, as required).
- Array methods wonât work, because itâs not an array:
alert(document.body.childNodes.filter); // undefined (there's no filter method!)
The first thing is nice. The second is tolerable, because we can use Array.from to create a ârealâ array from the collection, if we want array methods:
alert( Array.from(document.body.childNodes).filter ); // now it's there
DOM collections, and even more â all navigation properties listed in this chapter are read-only.
We canât replace a child by something else by assigning childNodes[i] = ....
Changing DOM needs other methods. We will see them in the next chapter.
Almost all DOM collections with minor exceptions are live. In other words, they reflect the current state of DOM.
If we keep a reference to elem.childNodes, and add/remove nodes into DOM, then they appear in the collection automatically.
for..in to loop over collectionsCollections are iterable using for..of. Sometimes people try to use for..in for that.
Please, donât. The for..in loop iterates over all enumerable properties. And collections have some âextraâ rarely used properties that we usually do not want to get:
<body>
<script>
// shows 0, 1, length, item, values and more.
for (let prop in document.body.childNodes) alert(prop);
</script>
</body>
Siblings and the parent
Siblings are nodes that are children of the same parent. For instance, <head> and <body> are siblings:
<body>is said to be the ânextâ or ârightâ sibling of<head>,<head>is said to be the âpreviousâ or âleftâ sibling of<body>.
The parent is available as parentNode.
The next node in the same parent (next sibling) is nextSibling, and the previous one is previousSibling.
For instance:
<html><head></head><body><script>
// HTML is "dense" to evade extra "blank" text nodes.
// parent of <body> is <html>
alert( document.body.parentNode === document.documentElement ); // true
// after <head> goes <body>
alert( document.head.nextSibling ); // HTMLBodyElement
// before <body> goes <head>
alert( document.body.previousSibling ); // HTMLHeadElement
</script></body></html>
Element-only navigation
Navigation properties listed above refer to all nodes. For instance, in childNodes we can see both text nodes, element nodes, and even comment nodes if there exist.
But for many tasks we donât want text or comment nodes. We want to manipulate element nodes that represent tags and form the structure of the page.
So letâs see more navigation links that only take element nodes into account:
The links are similar to those given above, just with Element word inside:
childrenâ only those children that are element nodes.firstElementChild,lastElementChildâ first and last element children.previousElementSibling,nextElementSiblingâ neighbour elements.parentElementâ parent element.
parentElement? Can the parent be not an element?The parentElement property returns the âelementâ parent, while parentNode returns âany nodeâ parent. These properties are usually the same: they both get the parent.
With the one exception of document.documentElement:
alert( document.documentElement.parentNode ); // document
alert( document.documentElement.parentElement ); // null
In other words, the documentElement (<html>) is the root node. Formally, it has document as its parent. But document is not an element node, so parentNode returns it and parentElement does not.
This loop travels up from an arbitrary element elem to <html>, but not to the document:
while(elem = elem.parentElement) {
alert( elem ); // parent chain till <html>
}
Letâs modify one of the examples above: replace childNodes with children. Now it shows only elements:
<html>
<body>
<div>Begin</div>
<ul>
<li>Information</li>
</ul>
<div>End</div>
<script>
for (let elem of document.body.children) {
alert(elem); // DIV, UL, DIV, SCRIPT
}
</script>
...
</body>
</html>
More links: tables
Till now we described the basic navigation properties.
Certain types of DOM elements may provide additional properties, specific to their type, for convenience.
Tables are a great example and important particular case of that.
The <table> element supports (in addition to the given above) these properties:
table.rowsâ the collection of<tr>elements of the table.table.caption/tHead/tFootâ references to elements<caption>,<thead>,<tfoot>.table.tBodiesâ the collection of<tbody>elements (can be many according to the standard).
<thead>, <tfoot>, <tbody> elements provide the rows property:
tbody.rowsâ the collection of<tr>inside.
<tr>:
tr.cellsâ the collection of<td>and<th>cells inside the given<tr>.tr.sectionRowIndexâ the position (index) of the given<tr>inside the enclosing<thead>/<tbody>/<tfoot>.tr.rowIndexâ the number of the<tr>in the table as a whole (including all table rows).
<td> and <th>:
td.cellIndexâ the number of the cell inside the enclosing<tr>.
An example of usage:
<table id="table">
<tr>
<td>one</td><td>two</td>
</tr>
<tr>
<td>three</td><td>four</td>
</tr>
</table>
<script>
// get the content of the first row, second cell
alert( table.rows[0].cells[1].innerHTML ) // "two"
</script>
The specification: tabular data.
There are also additional navigation properties for HTML forms. Weâll look at them later when we start working with forms.
Summary
Given a DOM node, we can go to its immediate neighbours using navigation properties.
There are two main sets of them:
- For all nodes:
parentNode,childNodes,firstChild,lastChild,previousSibling,nextSibling. - For element nodes only:
parentElement,children,firstElementChild,lastElementChild,previousElementSibling,nextElementSibling.
Some types of DOM elements, e.g. tables, provide additional properties and collections to access their content.
Yorumlar
<code>kullanınız, birkaç satır eklemek için ise<pre>kullanın. EÄer 10 satırdan fazla kod ekleyecekseniz plnkr kullanabilirsiniz)