DOM Manipulation

Joel Ross
Spring 2024

View of the Day

  • Q&A

  • DOM Manipulation Methods (code together!)

  • Adding Interactivity (code together!)

JavaScript Q&A

The DOM

(Document Object Model)

A structural model of information represented by HTML.
The model is a tree of element nodes.

The DOM provides functions that allows computer programs (e.g., JavaScript) to access and manipulate it.

The DOM

Referencing Elements

Use the document.querySelector() function to get a reference to DOM (HTML) elements, which you can assign to a variable.

The function's argument is a string (in quotes!) of a CSS selector for those elements.

//select the <h1> element
//returned value is an HTML Element
const headingElement = document.querySelector('h1'); 

/* can use any valid CSS selector */
//selects the first element with `class="alert"`
const alertElement = document.querySelector('.alert');

/* querySelectorAll() will select multiple elements */
/* returns a NodeSet, which is like an array */
//select all hyperlinks <a> within the <nav>
const buttonElementsSet = document.querySelectorAll('nav a');

Changing Elements

const paragraph = document.querySelector('p');
const image = document.querySelector('img');
const input = document.querySelector('input');

//change the paragraph's content.
paragraph.textContent = "This is new content!";  

//change the content (including HTML)
paragraph.innerHTML = "This is <em>new</em> content!";

//change element attributes
image.src = 'path/to/different_picture.png'; //change src

//access element properties
const inputttedValue = input.value;

//change element class(es)
paragraph.classList.add('bg-dark'); //give it the `bg-dark` class
paragraph.classList.toggle('bg-dark'); //remove if there, add if not

//add specific CSS property (but better to use a class!)
//note that property names are camelCase
paragraph.style.fontSize = '2rem'; //change font-size

Access element properties to modify the element.

Creating Elements

Create new elements using document.createElement()

New elements need to be added to the existing DOM tree with e.g., appendChild()

//create an element
const newParagraphElem = document.createElement('p');

//give it content/etc
newParagraphElement.textContent = "new content";

//get refefrence to element already on the page
const mainElem = document.querySelector('main');

//append the new element as last child
mainElem.appendChild(newParagraphElem);
<main>
  <p>old content</p>
</main>
<main>
  <p>old content</p>
  <p>new content</p>  
</main>

"Render" Functions

Best practice is to define functions (e.g., named create____ or render____) that will create and return elements.

function createLinkItem(text, url) {
  const aElem = document.createElement('a');
  aElem.textContent = text;
  aElem.src = url;
  return aElem; //returns an element!
}

const linkArray = [{url: 'https://info340.github.io/', title: 'Course Textbook'}, {url: 'https://ischool.uw.edu/', title: 'iSchool'}, {url: 'https://www.google.com/search?q=puppies&tbm=isch', title: 'Puppies'}];

function createLinkList(linkObjList) {
  const ulElem = document.createElement('ul');
  for(const linkObj of linkObjList) {
    //call the render function to create the child element
    const linkELem = createLinkItem(linkObj.title, linkObj.url);

    const liElem = document.createElement('li');
    liElem.appendChild(linkElem); //include the rendered element
    ulElem.appendChild(liElem);
  }
  return ulElem; //returns an element!
}

document.querySelector('nav').appendChild(createLinkList(linkArray));

But how do we make it interactive?

Event Handling

We add interactivity by listening for and responding to "events" created by the computer.

Register a Listener

Use the addEventListener() function to register a "listener". The function takes 2 arguments: the type of event to listen for (a string), and a callback function to run when the event occurs.

the event that occurred

const button = document.querySelector('button');

button.addEventListener('click', function(event) {

  //what to do when button is pressed!
  console.log("you clicked on", event.target);  

});

which element

cause the event

JS Web App Structure

To develop a web app, think about your page as "displaying dynamic content", not "responding to user actions".

  1. Define the data (state) that your app will be displaying
    • ex: the list of tasks, the current recipe, the user's history
       
  2. Define how to render (display) that data using functions
    • ex: createTaskItem(), renderRecipe() 
       
  3. Define responses to user action. When the user does something:
    1. Update the state data
    2. "re-render" the (now-changed) data!

JS Web App Structure

//define data
const state = {
  data: [ {}, {}, {} ],
  ...
}

//define presentation - lots of these kinds of functions
function renderData() {
  //render all the data
  for(let datum of state.data){
    //call helper functions to break things up!
    const dataCardElement = renderDataCard(datum);
    document.querySelector('#main').appendChild(dataCardElement);
  }
}

//define user interaction
button.addEventListener('click', function(event) {
  state.data[i] = ...; //MODIFY THE STATE
  document.querySelector('#main').innerHTML = ''; //CLEAR OLD VIEW
  renderData(); //RE-RENDER CONTENT    
})

renderData() //show initial content!

Handing Form Data

In order to respond to a form submission, you will need to "stop" the normal HTTP request being sent by calling preventDefault() on the event.

const formElement = document.querySelector('#myForm');

//listen for submit events
formElement.addEventListener('submit', function(event) {
  //stop normal behavior (going to a new site)
  event.preventDefault();

  //access what value the user typed in
  const inputElement = document.querySelector('#name-input')
  const userValue = inputElement.value;
  
  //... do something with that value!  
});

Action Items!

Action Items!

  • Review Chapter 1-12, Read: Chapter 14

    • We're skipping chapter 13

  • Problem Set 05 due Friday

  • Any past problem sets due Sunday!

Next time: ES6 syntax