JavaScript: selecting an element

When writing some JavaScript to update elements in a page, I got confused selecting which elements to process. Below is my little crib sheet to help me remember.

Naming of parts.

You can have some HTML like

<div id="colin" name="request" class="myclass">requestor<div>

This division element can be referred to by the id=”colin”. It has an attribute name with a value of request. It has formatting parameters defined in the style sheet class=”myclass”.

If you have an element myDiv, you can use

let myclass=myDiv.getAttribute("class");
myDiv.setAttribute("class", "newclass");
myDiv.setAttribute("id", "newid");
myDiv.setAttribute("name", "newname");
myDiv.setAttribute("newattribute", "new");
myDiv.removeAttribute("name");

The id,class and any attribute look the same, but are slightly different when used to select elements.

Structure

You can have a low level element like a paragraph <p>..</p>

You can have more complex objects like a table <table>…</table> which can have table rows <tr>…</tr>, which can have table cells <td>…</td> which can have other elements such as <p>…</p>.

A division <div..>/div> can be used around text or an element to give it properties, such as a formatting or giving a word an id.

The high level structure is a document. You can create and add element to another element. You can remove elements. If you remove a table element, all of its children, <tr> and<td> are removed as well.

You can have elements which are not part of the document. You can add them to the document.

Locating an element in JavaScript

Originally there was just getElementById:

document.getElementById('newid');

This searches within document and its children for the first element with id=”newid”. If you have more than one element with id=”newid” only the first will be returned.

With a document

<!doctype html>
<html lang="en">
<head>
</head>
<body>
<p id="passed" class="myclass"></p>
<p id="p1" name="Colin">Colin</p>
<p id="p1" name="Jo">Jo</> 
</body>
</html>
var q= document.getElementById('passed');

returns an object called p#passed. This means it is a <p>aragraph object with id=”passed”.

It was quickly found that getElementById was not flexible enough, and so

querySelectorAll and querySelector were created. These are much more flexible.

  • let p=querySelector(“p”) returns the first element of type <p>.
  • let pall=querySelectorAll(“p”) returns a NodeList of all the <p> elements. Each element in the node list represents a <p> element. In my example HTML pall has a length of 3, because there are 3 <p> elements.
  • let p=querySelector(“#p1”) returns the first node with id=”p1″. It returns an element with “p#p1” saying this is a <p> element.
  • let pnl=querySelectorAll(“#p1”) with the above HTML returns a NodeList of length 2 where:
    • pnl[0] is the first node with id=”p1″. It returns an element with “p#p1”
    • pnl[1] is the second node with id=”p1″. It returns an element with “p#p1”.
  • let pnl=querySelectorAll(“p.myclass”) returns all “p” elements with class=”myclass”.
  • let pnl=querySelectorAll(“.myclass”) returns all elements with class=”myclass” regardless of type.
  • let nl=querySelectorAll(“[name=’colin’]”) returns all elements with attribute name=”colin”. With the above example data it returns a nodeList with one element which is a p#p1.

These selectors can be combined so for example you could ask for all <p> nodes within a <table> with id=”mytab” which have name=”colin”.

Finding data in a subtree

Within my HTML page I have

<table id="ztable" frame="box" rules="rows"> 
<tr id="template"> 
   <td id="col0" name="serial"><div><p>data</p></div></td> 
   <td id="col1" name="requestor"><div>requestor<div></td>    
</tr> 
<tr id="tr1"></tr>
</table> 

<table id="table2"> 
<tr id="tr1"></tr>
</table>

I can find the first table, and extract the rows out of it.

let tab = document.getElementById('ztable');
let tr = tab.querySelectorAll("tr");

This locates the table with id=”ztable” then searches within this for all <tr> tags. It returns a node list of length 2. It does not return the row in the second table(table2).

Not found?