Key Concepts

CIT190 - JavaScript Programming

Key Concepts - Chapter 5 DOM (Document Object Model)


I. Overview

When discussing the BOM (Browser Object Model) and the DOM (Document Object Model) it is helpful to understand how everything fits together.   The BOM is the umbrella that everything is under.  The DOM is a subset of the BOM.

The BOM is a browser specific convention that refers to the objects exposed by the web browser.  These objects include:  history, frames, location, navigator (the type of browser you are using), screen and document.

The DOM begins with the Document node of the BOM (see illustration below)

DOM and BOM

II. More on the DOM:

When a web page is loaded, the browser creates a Document Object Model of the page.  The DOM is standardized and specifies how to interact with XML and HTML.   The HTML DOM model is constructed as a tree of objects.  The illustration below outlines the tree hierachy.

dom
Retrieved from https://www.w3schools.com/js/js_htmldom.asp January 2018

The HTML DOM is a standard for how to get, change, add, or delete HTML elements.   The HTML DOM defines all HTML elements as objects. It identifies properties of the objects and methods used to access the objects.  It also defines events for all HTML objects. 

The HTML DOM can be accessed with JavaScript (and with other programming languages). 

A few keypoints to remember  about the DOM include:

In the HTML DOM (Document Object Model), everything is a node:

node tree

The Element Object represents an HTML element.  Element objects can have parent or child nodes.  The child nodes can be element nodes, text nodes or comment nodes.   When you have an html element inside another one, it is a child of the outer element.  For example, when you have <li> elements inside <ol> elements, the <li> element is a child of the <ol> element which makes the <ol> element the parent.  If you think about your code, it isn't unusual to see many elements nested inside other elements

Example:

<section>
    <div>
        <p></p>
        <ol>
            <li></li>
            <li></li>
        </ol>
    </div>
</section>

In the example above, <section> is a parent to <div>.  <div> is a parent to <p> and <ol>.   <ol> is a parent to <li>.  Elements that occupy the same level in the hierarchy tree are referred to as siblings.  In the example above, <p> and <ol> are siblings and have the same parent, <div> 

To see a visual representation of  the DOM on any page, press F12 to get into the developer window.  You should see your html tags with arrows next to them that allow you to collapse (or expand content).    You can also create an external JavaScript file that writes document properties to the console. This technique provides a lot more information.   Once the page is loaded, you can press F12 and view the console.  Example of a log.js file: log.js    The log.js file is linked into this page, so pressing F12 and selecting the Console tab lets you see the DOM elements written to the console.  The advantage of using this method is you can target things like forms, images and other HTML collections 

JavaScript includes many ways to find and retrieve HTML elements:

1.  methods that return 1 element:   getElementById and querySelector

2.  methods that return > 1 element (NodeLists):  getElementsByTagName, getElementsByClassName, querySelectorAll 

3.  access an HTML collection that was created when the document loaded

JavaScript provides two methods of updating HTML elements.

Method #1:  use a display string that contains text and HTML along with the innerHTML method to update content   (this is the procedure we have been using)

Method#2:  use DOM manipulation commands like createElement(), createTextNode(), appendChild() etc.

III. Finding/Manipulating HTML Elements

JavaScript is often used to manipulate HTML elements.  If you want to access any element in an HTML page, you always start by using the document object.

In order to manipulate the elements, you have to find them first.  

Methods of finding elements include:

To see a video demonstration explaining finding elements by id, tag name, class name and CSS selectors, watch: https://youtu.be/mFsS-EMcNGY

To see a video demonstration explaining finding elements by collections, view: https://youtu.be/nLNxsUdQYtg

A  Finding elements by ID (review)

Syntax: document.getElementById("id");

Use the id attribute of the HTML element to retreive the value  (If the value is not found, it will contain null.)

This method is one of the most popular methods in the HTML DOM, and is used almost every time you want to manipulate, or get data from an element in your document.  To use the getElementById method, ID's should be unique within a page.   If more than one element with the specified ID exists, the getElementById() method returns the first element.

Example (in the example below, the text color is changed to red using getElementById):

<!DOCTYPE html>
<html>
<body>
<p id="demo">Click the button to change the color of this paragraph.</p>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction() {
    var x = document.getElementById("demo");
    x.style.color = "red";
}
</script>
</body>
</html>

Here's the example live:

Click the button to change the color of this paragraph.

 

Quite often programmers will store the location of an element in a variable and then use that variable to manipulate the element

Instead of coding:

     document.getElementById("demo").style.color="red";

They break the code into 2 parts, the location of the element and manipulation of the element

var x = document.getElementById("demo");  //element location
 x.style.color = "red";   // element modification

If you are planning on making multiple changes, it makes sense to store the location in a variable because it will save you time typing.

B  Finding elements by tag name

Syntax:  document.getElementsByTagName(tagname);     To retreive all elements on the page, you need to use:  document.getElementsByTagName( '*' );

The getElementsByTagName() method searches all elements with a given tagname and returns a NodeList object 

A NodeList is a list of HTML elements.   It is similar to an array, but it is NOT the same thing  (you cannot use array methods with a NodeList; therefore, it is not an array). 

To access elements within the list, you need to subscript into the list similar to subscripting into an array.   The first item in a list is retrieved with a subscript of zero.

The length property is used to determine how many items are in the list. 

Example #1 - retrieves the input elements and places the results into a colleciton called inputElements.  The length property is used to determine the number of elements which is displayed using the alert method.

<html>
<head>
<script>
function getElements()
{
    var inputElements=document.getElementsByTagName("input");
    alert(inputElements.length);
}
</script>
</head>
<body>
<input type="text" size="20"><br>
<input type="text" size="20"><br>
<input type="text" size="20"><br><br>
<input type="button" onclick="getElements()" value="How many input elements?">
</body>
</html>

To see a live example, view: getElementByTag-ex1.html

Example #2 - Retrieves all input elements and places them into a list called elements.  A for loop is used to access each element to see if the element is turned on.  Radio button values for each element are added to a display string which is used with innerHTML  to display the information.

<body>
<table id="myTable">
    <tr>
    <td>Your age:</td>
    <td>
        <input type="radio" name="age" value="under 18" checked/>
        <label> under 18</label>
        <input type="radio" name="age" value="18-25"/>
        <label> from 18 to 35</label>
        <input type="radio" name="age" value="36-49"/>
        <label>from 36 to 49</label>
        <input type="radio" name="age" value="50-65"/>
        <label>from 50 to 65</label>
        <input type="radio" name="age" value="over 65"/>
        <label> older than 65</label>
    </td>
    </tr>
</table>
<button type="submit" value="submit" id="submit" onclick="process()">Submit</button>
<p id="selections"></p>
<script>
    function process(){
        var elements = document.getElementsByTagName('input')
        var message="<p>Here are the option button values...</p>";
        for(var i=0; i<elements.length; i++) {
            message+="<p>" + elements[i].value+': '+elements[i].checked + "</p>";
        }
        document.getElementById("selections").innerHTML = message;
    }
</script>
</body>
 

To see this live, view: getElementByTag-ex2.html 

You can use the method to retrieve elements that are located inside other elements (such as li tags).  NOTE:  to access the text between <li> and </li> requires subscripting into the list AND using either textContent or innerHTML. 

Example:

<body>
    <ol id="people">
        <li>John</li>
        <li>Ringo</li>
        <li>Paul</li>
        <li>George</li>
    </ol>
<script>
    var list = document.getElementsByTagName('li')
    for (x=0; x<list.length;x++)
        alert(list[x].innerHTML)
</script>
</body>

To see this run, view:  getElementByTag-ex3.html

C  Finding elements by class name

Syntax: document.getElementsByClassName(classname);

The getElementsByClassName() method returns a NodeList of all elements in the document with the specified class name.  NodeLists can be accessed using an index that begins with zero.   You can use the length property to determine the number of elements returned.

Example - in the example below, the two div elements have a class set to example.  getElementsByClassName is retrieving all elements with a class set to example and storing them in a NodeList called exampleList.  The first element in the list is modified by subscripting into the list at position 0:

<!DOCTYPE html>
<html>
<body>
<div class="example">First div element with class="example".</div>
<div class="example">Second div element with class="example".</div>
<p>Click the button to change the text of the first div element with class="example" (index 0).</p>
<button onclick="myFunction()">Try it</button>
<script>
    function myFunction() {
        var exampleList = document.getElementsByClassName("example");
        exampleList[0].innerHTML = "Hello World!";
    }
</script>
</body>
</html>

To see this run live, view: getElementByClassName-ex1.html

You can retrieve multiple classes at a time and modify the html elements by retrieving the class name and subscripting into the list

Example - retrieves elements with the example and color classes applied.  Displays the number of elements retrieved and then changes the background color of the elements to peachpuff.

<!DOCTYPE html>
<html>
<head>
<style>
div {
    border: 1px solid black;
    margin: 5px;
}
</style>
</head>
<body>
<div class="example"><p>P element in first div with class="example". Div's index is 0.</p></div>
<div class="example color"><p>P element in first div with class="example color". Div's index is 0.</p></div>
<div class="example color"> <p>P element in second div with class="example color". Div's index is 1.</p></div>
<p>Click the button to change the background color of the first div element with the classes "example" and "color".</p>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction() {
    var myList = document.getElementsByClassName("example color");
    alert("The number of elements with the example and color classes applied are: " + myList.length);
    for (x=0; x<myList.length; x++)
        myList[x].style.backgroundColor = "peachpuff";
}
</script>
</body>
</html>

To see this run live, view: getElementByClassName-ex2.html

D.  Finding elements by CSS selectors

If you want to find all HTML elements that matches a specified CSS selector (id, class names, types, attributes, values of attributes, etc), use the querySelectorAll() method.   The querySelectorAll() method returns a NodeList object .  Nodes can be accessed using an index that begins with zero.   You can use the length property to determine the number of elements returned.

Syntax:  document.querySelectorAll("selector");

If you want multiple selectors, you must separate each one using a comma

IMPORTANT:  querySelectorAll returns a static NodeList which means, it is a snapshot of the list at the moment the command was executed.  It will NOT pick up any changes made in the DOM.  If the changes affect the current list, it will throw an exception error if you try to subscript in and the value no longer exists.

Examples:

var paragraphs = document.querySelectorAll("p");

var exampleClass = document.querySelectorAll(".example");

var exampleLength = document.querySelectorAll(".example").length;

var multSelectors = document.querySelectorAll("h2, div, span");

To retreive a selector with an attribute use:  document.querySelectorAll("selector[attribute]");

Examples:

var linkTargets = document.querySelectorAll("a[target]");

You can even use querySelectorAll() with CSS Combinators: 

Example:  The example below would retrieve all <p> elements with a <div> parent element

var paragraphsInDivisions=document.querySelectorAll("div > p");

Once you have created a NodeList, you can adjust the CSS and/or text

To display the text within the HTML tags, you need to use nodeList variable.textContent or innerHTML.  textContent will return null if the element is a document, document type or notation.  NOTE:  The difference between textContent and innerHTML is innerHTML will render text and HTML and textContent will only render text (not html).   If you have something like:  "I love <strong>chocolate</strong>"   innerHTML will boldface chocolate and textContent will not.   If you are using forms where users enter data, textContent is a little safer from HTML injection hacking because it ignores code.

Full Example #1:  The example below displays the NodeList using the nodes on the page

<button type="button" onclick="viewList()">View NodeList</button>
<script>
function viewList()
{
    var contents = "<h3><hr/>Display of NodeList collection on this page:</h3>";
    // stores all NodeList objects in a variable called nodes
    var nodes = document.querySelectorAll("*");
    // concatenates each node to the contents message
    for ( var i = 0; i < nodes.length; i++ )
    {
        contents += "<p>Node=" + nodes[i] + "</p>";
    }
    // displays the message showing the NodeList and text
    document.getElementById( "listing" ).innerHTML = contents;
}
</script>
<p id="listing"></p>

To see the example live, view: nodeListing.html

Full Example #2:  The example below retrieves the textContent of all headings and uses innerHTML to retrieve the text from the paragraphs (it illustrates that you can retrieve text either way).

<button type="button" onclick="viewHeadingList()">View NodeList Heading Tag Content</button>
<button type="button" onclick="viewParagraphList()">View NodeList Paragraph Tag Content</button>
<script>
function viewHeadingList()
{
    var contents = "<h3><hr/>Content of heading tags in this page</h3>";
    // stores all NodeList objects in a variable called nodes
    var nodes = document.querySelectorAll("h1,h2,h3,h4,h5,h6");
    // concatenates each node to the contents message
    for ( var i = 0; i < nodes.length; i++ )
    {
        contents += "<p>Node=" + nodes[i] + " | Content=" + nodes[i].textContent + "</p>";
    }
    // displays the message showing the NodeList and text
    document.getElementById( "listing" ).innerHTML = contents;
}
function viewParagraphList()
{
    var contents = "<h3><hr/>Content of paragraph tags in this page</h3>";
    // stores all NodeList objects in a variable called nodes
    var nodes = document.querySelectorAll("p");
    // concatenates each node to the contents message
    for ( var i = 0; i < nodes.length; i++ )
    {
        contents += "<p>Node=" + nodes[i] + " | Content=" + nodes[i].innerHTML + "</p>";
    }
    // displays the message showing the NodeList and text
    document.getElementById( "listing" ).innerHTML = contents;
}
</script>
<p id="listing"></p>

To see the example live, view:  nodeListing1.html
 

Full Example #3:  The example below retrieves all paragraphs and stores them in a variable called para.  The paragraphs can all be changed to green by clicking a button OR the first 2 paragraphs can be changed to blue by clicking a button

<button type="button" onclick="change()">Change all paragraphs Green</button>
<button type="button" onclick="changeFirst()">Change first and second paragraphs to Blue</button>
<script>
function change()
{
    var para = document.querySelectorAll("p");
    for ( var i = 0; i < para.length; i++ )
    {
        para[i].style.color="green";
    }
}
function changeFirst()
{
    var para = document.querySelectorAll("p");
    para[0].style.color="blue";
    para[1].style.color="blue";
}

</script>

To see the example live, view:  nodeListing2.html

To see a similar, interactive example, view: https://www.w3schools.com/js/tryit.asp?filename=tryjs_dom_nodelist_loop

E  Finding elements by HTML object collection

You can directly access HTML collections including:

To access a collection, you need to use document, a dot and the name of the collection.  To access a single element within the collection, you will have to subscript into the collection.  To determine how many elements are in a collection, use the length property.

So far, we have been working with NodeLists.  A NodeList and an HTML collection are very similar; however, there are a few minor differences:

NodeLIst HTMLCollection
User creates through code Automatically created
Uses length property to determine the number of items Uses length property to determine the number of items
The first item must be accessed using an index number of 0 The first item can be accessed by name, id or with an index number of 0
Can contain attribute nodes and text nodes Cannot contain attribute or text nodes
Most nodelist objects are static (document.getElementByName will return a live NodeList) All HTML collections are live which means they are automatically updated as the page changes.
Not an array and cannot use array methods Not an array and cannot use array methods

Example #1:

The code in the example below is in a page with a large number of links.  The code retrieves all the links using the document.links property   A for loop is used to access each link within the array based on the total number of links in the page (document.links.length is used to get the total number).  document.links[i].innerHTML.link(document.links[i].href) is used to retrieve the actual html used in the page.  The html is then added to a string which is printed at the bottom of the page after all the links have been processed.

<script type = "text/javascript">
function processlinks()
{
var contents = "<h3><hr/>Directory of Links in this page:\n</h3>| ";
// concatenate each link to contents
for ( var i = 0; i < document.links.length; i++ )
{
    contents += "<span class = 'link'>" + document.links[i].innerHTML.link( document.links[i].href ) + "</span> | ";
} // end for

document.getElementById( "links" ).innerHTML = contents;
} // end function processlinks
</script>

To see this live, view: objectCollectionExample.html   (you can see all the code by right clicking and selecting view page source).  The directory of links will display at the bottom of the page (you may ned to scroll down).

Example #2:

The code below looks at the forms in the document, prints the total number of forms and then loops through the document.forms array and displays the id's for each form

<!DOCTYPE html>
<html>
<body>
<form id="Form1"></form>
<form id="Form2"></form>
<form id="Form3"></form>
<form id="Form0"></form>

<p>Number of forms:
<script>
document.write(document.forms.length);
</script></p>

<h3>Names of the forms:</h3>
<p>
<script>
for (x=0;x<document.forms.length; x++) {
    document.write(document.forms[x].id);
    document.write("<br>");
}
</script></p>
</body>
</html>

To view it live, see objectCollectionExample2.html

You can access anything that is in an html element.  For example, in the image tag, src is required and you can retrieve that information.  You can also retrieve the alternate text.   If the image is a thumbnail link, you can retrieve the actual link itself too.

Example - the example displays 4 thumbnail links at the top of the page, it generates the names based on the alternate text specified for each image, it displays the source of the photo and it combines the name and the source to create links to the photos.  The portion of the page used to generate the name, source and links is displayed below the images at the top.  You will notice the javascript code is between an opening <p> and a closing </p> - that is the location the information will display in the page.  The first function, processName is called when the page loads.  At the bottom of the processName function, there is a call to the processSource function and at the bottom of the processSource function is a call to the processLinks function.  If you look at the code used in the processLinks function, you will see that we had to "build" the actual link that is displayed. 

dom collection scripting example

To see this live, view: objectCollectionExample3.html

IV. DOM Navigation using Nodes (HTML Elements)

 You can use the following node properties to navigate between nodes with JavaScript:

DOM elements do not contain text.  The text node contains the text.  The value of the text node can be accessed a few different ways:

1) If you have a nodelist, you can use textContent or innerHTML (nodelists are generated when you use document.querySelectorAll or any get method that returns > 1 element)

2) If you do NOT have a nodelist, you can either:

a)  use innerHTML
or
b)  subscript into the node and use the nodeValue property to access the text

Example #1: The firstChild.nodeValue code below is an example of navigation using DOM Nodes.  The end result of the firstChild.nodeValue and innerHTML statements is the same, the example just shows 2 different ways of getting there.  The exam also shows 2 different ways to update HTML targeted by ID's  (textContent and innerHTML)

<!DOCTYPE html>
<html>
<body>
<h1 id="id01">My wonderful text</h1>
<p id="id02"></p>
<p id="id03"></p>
<script>
document.getElementById("id02").textContent ="display using nodeValue: " + document.getElementById("id01").firstChild.nodeValue;
document.getElementById("id03").innerHTML = "display using innerHTML: " + document.getElementById("id01").innerHTML;
</script>
</body>
</html>

To view the example live, see nodeTraversal.html   

Example #2:  Navigates through child nodes in an ordered list.  NOTE:  The parent element is retrieved using getElementById  (this requires an id attribute in the <ol> tag

<p id="listing"></p>
<button type="button" onclick="viewChildren()">Child Nodes in numbered list</button>
<script>
    function viewChildren()
    {
        var parentNode = document.getElementById("numberedList");
        var contents="";
        for ( var i = 0; i < parentNode.childNodes.length; i++ )
        {
            if (parentNode.childNodes[i].textContent)
            contents += "<p>Child Node=" + parentNode.childNodes[i] + " | Content=" + parentNode.childNodes[i].textContent + "</p>";
        }
        // displays the message showing the NodeList and text
        document.getElementById( "listing" ).innerHTML = contents;
}
</script>
<p id="listing"></p>

To see the example live, view:  nodeTraversal2.html

For more on DOM Navigation, view:  https://www.w3schools.com/js/js_htmldom_navigation.asp

IV. DOM Manipulation using Nodes

 If you like the parent/child lingo, you can manipulate content using nodes. 

You can add, remove and replace elements and their content using nodes

A.  Adding new content with nodes

To add new content you create a new element node, create content that will display, attach the element with it's content and finally append the node to the page in the correct location

Methods used to accomplish this are:  document.createElement,  document.createTextNode and appendChild   The appendChild method is used 2 times, the first time it connects the HTML element with it's text and the second time, it places the new element/text onto the page.

The example below shows how to add a paragraph to a section element.  The code includes comments so you can follow what it is doing (I've also described the actions below). 

line 13:  document.createElement("p")  creates the new <p> tag object called para

line 16:  document.createTextNode(msg) creates the message that will display in the <p> tag and stores it in an object named node

line 18:  connects the <p> tag with the message it will display using the para object to call the appendChild method (the node object containing the text is passed to the method)

line 20:  locates the parent element (id="section") and stores the location of the parent in an object called parent

line 22:  uses the parent object to call the appendChild metod and passes the para object.  This final step adds the new paragraph to the page.

adding with nodes

To see the example live, view: addingHTMLusingNodes.html

Using appendChild adds the element to the end (so it becomes the last child)

If you do NOT want the new element added to the end, you can use the insertBefore method.  Using this method is very similar to appendChild, the difference is you need to find the ID of the location you want to place the new element at in addition to the location of the parent.

The example below shows how to insert a new paragraph between the first and second paragraph.  The code includes comments so you can follow what it is doing (I've also described the actions below). 

line 13:  document.createElement("p")  creates the new <p> tag object called para

line 16:  document.createTextNode(msg) creates the message that will display in the <p> tag and stores it in an object named node

line 18:  connects the <p> tag with the message it will display using the para object to call the appendChild method (the node object containing the text is passed to the method)

line 20:  locates the parent element (id="section") and stores the location of the parent in an object called parent

line 22:  finds the location of the child element where we want the new paragraph inserted and stores the location in a variable called child

line 24:  uses the parent object to call the insertBefore method and passes the para object along with the child object storing the location.  This final step adds the new paragraph to the page in the correct location.

using insert before

To see the example live, view: usingInsertBefore.html

B.  Removing content

Removing content involves:

1.  retrieving the location of the parent using it's ID

2.  retrieving the location of the child using it's ID

3.  having the parent object call the removeChild method and passing the child to the method in the call

Example:  In the example below, the user selects which sentence to remove (1,2 or 3) and the other 2 sentences display  The code includes comments so you can follow what it is doing (I've also described the actions below). 

Line 17:  stores the paragraph# that should be removed

Line 18:  ensures the paragraph#  is valid

Line 21:  targets the parent element using it's ID

Line 23:  targets the paragraph to remove using it's ID

Line 25:  removes the paragraph using the parent object and the removeChild method (the paragraph location is passed to the method in the parameter list)

remove child example

To see the example live, view: removeChildMethod.html

C. Replacing content:

You can replace content using the replaceChild method.  To use the method, you need to:

1.  use document.createElement to create the new tag

2.  use document.createTextNode to create the content for the new tag

3.  connect the new tag with it's content using the appendChild method

4.  retrieve the location of the parent element that contains the content you want to replace

5.  retrieve the location of the actual element containing the content you want to replace

6.  use the replaceChild command to change the content

Example:  In the example below, the quote in paragraph 2 is changed when the user clicks the button.  Here's what the code is doing:

line 17:  document.createElement("p")  creates the new <p> tag object called para

line 18:  document.createTextNode(msg) creates the message that will display in the <p> tag and stores it in an object named node

line 19:  connects the <p> tag with the message it will display using the para object to call the appendChild method (the node object containing the text is passed to the method)

line 20:  locates the parent element (id="section") and stores the location of the parent in an object called parent

line 21:  locates the child element to be replaced (id="p2") and stores the location in an object called child

line 22:  uses the parent object to call the replaceChild method and passes the para object along with the child object storing the location.  This final step replaces the old paragraph with the new paragraph.

replace child example

To see the example live, view: replacementHTMLusingNodes.html

For more information an examples, visit:  https://www.w3schools.com/js/js_htmldom_nodes.asp

V. Changing HTML Elements and their Attributes

To change HTML content or attributes within the tags, you need to change document object properties.

A.  Changing DOM Styles

We have set DOM styles using the following syntax:

document.getElementById("id").style.cssStyle

where id is the id in the element you want to change and cssStyle is the style rule you want to change

Example: document.getElementById("myH1").style.color = "red";

For a review and to see a full list of style object properties you can access and change, view: https://www.w3schools.com/jsref/dom_obj_style.asp

B. Changing Attributes in HTML tags

Using DOM methods, you can access attributes in HTML tags, you can set new attributes and you can change existing attributes.

1) createAttribute() Method and setAttributeNode() Method

To add a new attribute to an element is a 2 step process:

1)  create and store the attribute

2)  add the attribute to the correct tag or node

The createAttribute() method creates an attribute with the specified name, and returns the attribute as an Attr object.

Syntax: var newAtt = document.createAttribute(attributename)

The setAttributeNode() adds the new attribute to the page

Syntax:  htmlElementObject.setAttributeNode(newAtt);

Where htmlElementObject is an object storing the location of the element you want to change

W3C example adapted for class:  the <a> tag is missing the href attribute so the text between the <a> and </a> isn't a link.  Clicking the button in the example adds the href attribute and value to the <a> tag creating the link.   Comments in the code explain what it does.

<!DOCTYPE html>
<html>
<body>
<a id="myAnchor">A Link: Go to w3schools.com</a>
<p>Click the button to create a "class" attribute with the value "www.w3schools.com" and insert it to the a element above.</p>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction() {
    // retrieves the location of the myAnchor ID and stores it in the anchor variable
    var anchor = document.getElementById("myAnchor");
    // creates a new attribute, href and stores it in the att object variable
    var att = document.createAttribute("href");
    // uses the att object variable AND the value property to set the URL
    att.value = "https://www.w3schools.com";
    // uses the anchor object to call the setAttribute method
   //(the att object containing the href attribute and the text value are passed)
    anchor.setAttributeNode(att);
}
</script>
</body>
</html>

To see the example live, view:  setAttributeExample.html

2)  getAttribute() Method or getAttributeNode() Method

The methods retreive an attribute from a specified tag.  The difference is the getAttributeNode() method retrieves an attr object and the getAttribute method does not

If you use getAttributeNode() you need to use properties and methods to access values stored.

a)  getAttribute()

Syntax:  var currentAttribute = document.getElementById("id").getAttribute("attributeName");

The method would be used to see what is currently in the page (that way you could decide if you wanted to change it or not)

The currentAttribute variable would display the value stored by the attributeName

Example:

<!DOCTYPE html>
<html>
<body>
Learn more about JavaScript at <a id="jsAnchor" href="https://www.w3schools.com/jsref/" target="_blank">W3 Schools JS Reference</a>.
<p>Click the button to display the value of the href attribute of the link above.</p>
<button onclick="hrefFunction()">Try it</button>
<p id="demo"></p>
<script>
    function hrefFunction() {
        var currentAttribute = document.getElementById("jsAnchor").getAttribute("href");
        document.getElementById("demo").innerHTML = currentAttribute;
    }
</script>
</body>
</html>

To see it live, view:  getAttributeExample.html   Notice that currentAttribute contains the URL

b)  getAttributeNode()

Syntax:  var currentAttribute = document.getElementById("id").getAttributeNode("attributeName");

To access the value stored, you need to access the value property:  currentAttribute.value

Example:

<!DOCTYPE html>
<html>
<body>
Learn more about JavaScript at <a id="jsAnchor" href="https://www.w3schools.com/jsref/" target="_blank">W3 Schools JS Reference</a>.
<p>Click the button to display the value of the href attribute of the link above.</p>
<button onclick="hrefFunction()">Try it</button>
<p id="demo"></p>
<script>
    function hrefFunction() {
        var currentAttribute = document.getElementById("jsAnchor").getAttributeNode("href");
        document.getElementById("demo").innerHTML = currentAttribute.value;
    }

</script>
</body>
</html>

To see it live, view:  getAttributeNode.html   Because getAttributeNode returns an attr object, we have to use the value property to see the URL

3)  hasAttribute() method

The hasAttribute() method returns true if the specified attribute exists, otherwise it returns false.

The method is typically used in an if statement to see if an attribute exists before changing it

Example:  In the example, we are checking the element with an ID=CIT180 to see if there is a target attribute.  If it doesn't have a target, we create a new target attribute, set the value to _blank and add it to the html tag

 <button onclick="changeAttribute();">Change Attributes</button>
<script>
function changeAttribute(){
    var check = document.getElementById("CIT180").hasAttribute("target");
    var att = document.getElementById("CIT180");
    if (!check) {
        var newAtt = document.createAttribute("target");
        newAtt.value="_blank";
        att.setAttributeNode(newAtt);
    }
}
</script>

To see the example live, view:  checking and setting attributes.html

VI. Difference between textContent, innerText and innerHTML

JavaScript includes several methods for retrieving and updating text. It is important to know how they differ and when to use each one.

A. textContent

  1. The textContent property sets or returns the text content of a specified node, and all its descendants.
  2. It will return the content of ALL elements including those hidden by CSS.
  3. textContent cannot set or return HTML, it only sets or returns the text content.

B. innerText

  1. The innerText property sets or returns the text content of a specified node, and all its descendants.
  2. It will return the content of ALL elements EXCEPT for the script and style elements
  3. innerText cannot return the text of elements that are hidden with CSS.

C. innerHTML

  1. The innerHTML property sets or returns the HTML content of an element.
  2. The property is vulnerable to XSS attacks (cross-site injections) because it includes the HTML and the content. If you are retrieving data from a form, it should be sanitized before updating content using innerHTML. You could also just use textContent to avoid the problem.

Example Retrieving Values:

Gift List:

  1. Drone
  2. Guitar
  3. Zoom Lens
  4. Macro Lens

The code below was used to generate the list and buttons.  You will notice that the second item, Guitar, is hidden.  The only property that displays it is the textContent.   innerText omits it and so does innerHTML.      innerHTML is the only property that keeps the bullets intact, the others omit them because they are HTML elements. 

<p>Gift List:</p>
  <ol id="myList">
    <li>Drone</li>
    <li style="visibility: hidden;">Guitar</li>
    <li>Zoom Lens</li>
    <li>Macro Lens</li>
  </ol>
  <button onclick="getTC();">Click to see the textContent of the list</button>
  <button onclick="getIT();">Click to see the innerText of the list</button>
  <button onclick="getHTML();">Click to see the innerHTML of the list</button>
  <p id="content"></p>
  <script>
function getTC(){
    var c=document.getElementById("myList").textContent;
    document.getElementById("content").innerHTML = "textContent= " + c;
}
function getIT(){
    var i=document.getElementById("myList").innerText;
    document.getElementById("content").innerHTML = "innerText= " + i;
}
function getHTML(){
    var h=document.getElementById("myList").innerHTML;
    document.getElementById("content").innerHTML = "innerHTML= " + h;
}
</script>