this
          this.fieldName                 // access field
          this.fieldName = value;        // modify field
          this.functionName(parameters); // call method
          
          JS
All JavaScript code actually runs inside of an object
By default, code runs in the global window object (so this === window)
windowThe this keyword refers to the current object
          window.onload = function() {
            document.getElementById("textbox").onmouseout = booyah;
          };
          function booyah() { // booyah knows what object it was called on
            this.value = "booyah";
          }
          
          JS
output
Event handlers attached unobtrusively are bound to the element
Inside the handler, that element becomes this
            
          
The elements of a page are nested into a tree-like structure of objects
The DOM has properties and methods for traversing this tree
innerHTML HackingWhy not just code this way?
          function slideClick() {
            document.getElementById("main").innerHTML += "<p>A paragraph!</p>";
          }
          
          JS
Imagine that the new node is more complex:
          function slideClick() {
            document.getElementById("main").innerHTML += <p style='color: red; " +
              "margin-left: 50px;' " + "onclick='myOnClick();'>" +
              "A paragraph!</p>";
          }
          
          JS
          // create a new <h2> node
          let newHeading = document.createElement("h2");
          newHeading.innerHTML = "This is a heading";
          newHeading.style.color = "green";
          
          JS
| Name | Description | 
|---|---|
| document.createElement("tag") | creates and returns a new empty DOM node representing an element of that type | 
| document.createTextNode("text") | creates and returns a text node containing given text | 
Merely creating an element does not add it to the page
You must add the new element as a child of an existing element on the page...
          let p = document.createElement("p");
          p.innerHTML = "A paragraph!";
          document.getElementById("main").appendChild(p);
          
          JS
Every DOM element object has these methods:
| Name | Description | 
|---|---|
| appendChild(node) | places the given node at end of this node's child list | 
| insertBefore(new, old) | places the given node in this node's child list just before old child | 
| removeChild(node) | removes the given node from this node's child list | 
| replaceChild(new, old) | replaces given child with new nodes | 
How would we do each of the following in JavaScript code? Each involves modifying each one of a group of elements...
ul list with id of 'tas' to have a gray background
            Methods in document and other DOM objects:
| Name | Description | 
|---|---|
| getElementsByTagName(tag) | returns array of descendents with the given tag, such as "div" | 
| getElementsByName(name) | returns array of descendents with the specified name (mostly useful for accessing form controls) | 
| querySelector(selector) | returns the first element that would be matched by the given CSS selector string | 
| querySelectorAll(selector) | returns an array of all elements that would be matched by the given CSS selector string | 
Highlights all paragraphs in the document:
          let allParas = document.querySelectorAll("p");
          for (let i = 0; i < allParas.length; i++) {
            allParas[i].style.backgroundColor = "yellow";
          }
          
          JS
          <body>
            <p>This is the first paragraph</p>
            <p>This is the second paragraph</p>
            <p>You get the idea...</p>
          </body>
          
          HTML
This is the first paragraph
This is the second paragraph
You get the idea...
output
Highlight all paragraphs inside of the section with ID 'address':
          let addrParas = document.querySelectorAll("#address p");
          for (let i = 0; i < addrParas.length; i++) {
            addrParas[i].style.backgroundColor = "yellow";
          }
          
          JS
          
            <p>This won't be highlighted!</p>
            <div id="address>
              <p>1234 Street</p>
              <p>Seattle, WA</p>
            </div>
            
          
          
          HTML
This won't be highlighted!
1234 Street
Seattle, WA
output
querySelectorAll Issues
          
            Many students forget to write . or # in front of a class or
            id
          
          // get all buttons with a class of "control"
          let gameButtons = document.querySelectorAll("control");
          let gameButtons = document.querySelectorAll(".control");
          
          JS
            querySelectorAll returns an array, not just a single element; must loop
            over the results
          
document.querySelector returns just the first element that matches, if
              that's what you want
            
          // set all buttons with a class of "control" to have red text
          document.querySelectorAll(".gamebutton").style.color = "red";
          let gameButtons = document.querySelectorAll(".gamebutton");
          for (let i = 0; i < gameButtons.length; i++) {
            gameButtons[i].style.color = "red";
          }
          
          JS
            Q: Can I still select a group of elements using querySelectorAll even if
            my CSS file doesn't have any style rule for that same group? (A: Yes!)
          
            
          
          HTML
          window.onload = function() {
            document.getElementById("clickme").onclick = biggerFont;
          };
          function biggerFont() {
            let button = document.getElementById("clickme");
            let size = parseInt(button.style.fontSize);
            button.style.fontSize = (size + 4) + "pt";
          }
          
          JS
output
The style property lets you set any CSS style for an element
            A catch: you can only use this to read styles set in the html 
            or with the DOM .style. You cannot read css properties from this.
          
          window.getComputedStyle(element).propertyName;
          
          JS (template)
          function biggerFont2() {
            let button = document.getElementById("clickme2");
            let size = parseInt(window.getComputedStyle(button).fontSize);
            button.style.fontSize = (size + 4) + "pt";
          }
          
          JS (example)
output
getComputedStyle method of global window object accesses existing styles
            The following example attempts to add 100px to the top of main, but fails. 
          
            Consider the case when main has top set to "200px". Then
            this code would update style.top to be the invalid value of "200px100px"
          
          let main = document.getElementById("main");
          main.style.top = window.getComputedStyle(main).top + 100 + "px";
          
          JS
A corrected version:
          main.style.top = parseInt(window.getComputedStyle(main).top) + 100 + "px";
          
          JS
          function highlightField() {
            // turn text yellow
            let text = document.getElementById("text");
            if (!text.className) {
              text.className = "highlight";
            } else if (text.className.indexOf("invalid") < 0) {
              text.className += "highlight"; // awkward
            }
          }
          
          JS
            JS DOM's className property corresponds to HTML class
            attribute
          
Somewhat clunky when dealing with multiple space-separated classes as one big string
classList
          function highlightField() {
            // turn text yellow
            let text = document.getElementById("text");
            if (!text.classList.contains("invalid")) {
              text.classList.add("highlight");
            }
          }
          
          JS
            classList collection has methods add, remove,
            contains, and toggle to manipulate CSS classes
          
            Similar to existing className DOM property, but don't have to manually
            split by spaces
          
          function slideClick() {
            let bullet = document.getElementById("removeme");
            bullet.parentNode.removeChild(bullet);
          }
          
          JS
            An odd idiom: obj.parentNode.remove(obj)
          
            
              This is a paragraph of text with a link in it.
            
          
          HTML

Element Nodes (HTML tag)
Text Nodes (text in a block element)
Attribute Nodes (attribute/value pair)
Every node's DOM object has the following properties:
| Name(s) | Description | 
|---|---|
| firstChild, lastChild | start/end of this node's list of children | 
| childNodes | array of all of this node's children | 
| nextSibling, previousSibling | neighboring nodes with the same parent | 
| parentNode | the element that contains this node | 
Complete list of DOM node properties
Browser incompatibility information (IE6 sucks)
                
                  This is a paragraph of text with a
                  link.
                
              
              HTML

          
            
              This is a paragraph of text with a
              link.
            
          
          
          HTML
Q: How many children does the div have?
A: 3
<p>Q: How many children does the paragraph have? The a tag?