in querySelector: how to get the first and get the last elements? what traversal order is used in the dom?

JavascriptDomHtml

Javascript Problem Overview


in a div, have elements (not necessarily 2nd generation) with attribute move_id.

First, would like most direct way of fetching first and last elements of set

tried getting first and last via:

var first = div.querySelector('[move_id]:first');
var last  = div.querySelector('[move_id]:last');

this bombs because :first and :last were wishful thinking on my part (?)

cannot use the Array methods of querySelectorAll since NodeList is not an Array:

var first = (div.querySelectorAll('[move_id]'))[0];
var last  = (div.querySelectorAll('[move_id'])).pop();

this bombs because NodeList does not have method pop()

(yes, one could could use Array methods on top of the NodeList:

var first = div.querySelector('[move_id]');
var last = Array.prototype.pop.call(div.querySelectorAll('[move_id']));

this works, and is what I'm using now, but thinking there has to be something more direct that I'm simply missing)

Second, need to verify that the elements are listed by pre-oder depth-first traversal as per <http://en.wikipedia.org/wiki/Tree_traversal>

Javascript Solutions


Solution 1 - Javascript

To access the first and last elements, try.

var nodes = div.querySelectorAll('[move_id]');
var first = nodes[0];
var last = nodes[nodes.length- 1];

For robustness, add index checks.

Yes, the order of nodes is pre-order depth-first. DOM's document order is defined as,

> There is an ordering, document order, defined on all the nodes in the document corresponding to the order in which the first character of the XML representation of each node occurs in the XML representation of the document after expansion of general entities. Thus, the document element node will be the first node. Element nodes occur before their children. Thus, document order orders element nodes in order of the occurrence of their start-tag in the XML (after expansion of entities). The attribute nodes of an element occur after the element and before its children. The relative order of attribute nodes is implementation-dependent.

Solution 2 - Javascript

:last is not part of the css spec, this is jQuery specific.

you should be looking for last-child

var first = div.querySelector('[move_id]:first-child');
var last  = div.querySelector('[move_id]:last-child');

Solution 3 - Javascript

Adding to the answers here a solution (a bit different to the others proposed):

Using the :last-of-type selector to get the last element of a certain specific tag name:

console.log(
  ":last-of-type  -  ",
  document.querySelector('mark:last-of-type') // <---- 
)

console.log(
  ":last-child    -  ",
  document.querySelector('mark:last-child')
)

<p>
this is <mark>highlighted</mark> and this is <mark>is also</mark> but <strong>not this</strong>.
</p>

Solution 4 - Javascript

Example to get the last input element:

document.querySelector(".groups-container >div:last-child input")

Solution 5 - Javascript

Use element.firstElementChild and element.lastElementChild

If you want to get the first child element, use: node.firstElementChild. (if you want the first child, even if it's a non-element like text, then use: node.firstChild).

If you want to get the last child element, use: node.lastElementChild. (again, if you want to select a non-element child, like text, use use: node.lastChild).

MDN WebDocs Description

From the above-linked MDN webdocs:

>firstElementChild — The Element.firstElementChild read-only property returns an element's first child Element, or null if there are no child elements. > >lastElementChild — The Element.lastElementChild read-only property returns an element's last child Element, or null if there are no child elements.

Wide Browser Support

firstChild and lastChild have extremely wide browser support.

Supported in:

  • Chrome — Version 1
  • Edge — Version 12
  • Firefox — Version 1
  • Internet Explorer — Version 6
  • Opera — Version 12.1
  • Safari — Version 1

Working Demo — firstElementChild & lastElementChild

var mydiv = document.getElementById('my-div');
mydiv.firstElementChild.style.backgroundColor = 'green';
mydiv.lastElementChild.style.backgroundColor = 'green';

<div id="my-div">
    <p>My first paragraph!</p>
    <p>Here is an intermediate paragraph!</p>
    <p>Here is another intermediate paragraph!</p>
    <p>Here is yen another intermediate paragraph!</p>
    <p>My last paragraph!</p>
</div>

Working Demo — firstChild & lastChild

var mydiv = document.getElementById('my-div');
mydiv.firstChild.style.backgroundColor = 'green';
mydiv.lastChild.style.backgroundColor = 'green';

<div id="my-div"><p>My first paragraph!</p><p>Here is an intermediate paragraph!</p><p>Here is another intermediate paragraph!</p><p>Here is yen another intermediate paragraph!</p><p>My last paragraph!</p></div>

Solution 6 - Javascript

You can get the first and last element directly.

//-- first element
console.log( document.querySelector("#my-div").querySelectorAll( "p" )[0] );
//-- last element
console.log( document.querySelector("#my-div").querySelectorAll( "p" )[document.querySelector("#my-div").querySelectorAll( "p" ).length-1] );

<div id="my-div">
  <p>My first paragraph!</p>
  <p>Here is an intermediate paragraph!</p>
  <p>Here is another intermediate paragraph!</p>
  <p>Here is yen another intermediate paragraph!</p>
  <p>My last paragraph!</p>
</div>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questioncc youngView Question on Stackoverflow
Solution 1 - JavascriptAnuragView Answer on Stackoverflow
Solution 2 - JavascriptGuillaume MasséView Answer on Stackoverflow
Solution 3 - JavascriptvsyncView Answer on Stackoverflow
Solution 4 - Javascriptg.breezeView Answer on Stackoverflow
Solution 5 - JavascriptHoldOffHungerView Answer on Stackoverflow
Solution 6 - JavascriptGiuseppe CanaleView Answer on Stackoverflow