DOM Scripting
"Scripting" is a term used when you're writing programs that don't do much on their own; instead scripts usually use other, more advanced programs, or are embedded within them.
"DOM Scripting" means using JavaScript to manipulate the DOM (page elements and contents) inside a web page, either during page load, or in response to user events, like clicking a button or selecting text.
Scripts as attributes
This is the simplest way to execute JavaScript inside a Web page.
This is NOT the best way to execute JavaScript.
<button name="button" onclick="alert('Abracadabra!')">
Magic
</button>
Try it out here:
onclick
is an attribute that contains a script that pops up an alert box. Also known as an event handler.
(We will discuss several other ways to attach event handlers later in this lesson.)
A Script Tag
Without a src
attribute, it defines a script and immediately executes its code:
<script>
var message = "Shazam!"
alert(message)
</script>
A Script Tag with src
With a src
attribute, it loads code from a separate file, and and immediately executes it:
<script src="tictactoe.js"></script>
This code expects a file named tictactoe.js
to exist on the server in the same directory as the HTML file.
The script
tag may appear in the head
or in the body
. Scripts are executed in top-to-bottom order.
HINT: to be sure that your code executes after the page has been fully loaded, put your
<script>
tags at the bottom of the<body>
section.
The document
In a DOM script, the current page is always available via the global variable named document
.
In addition to providing many useful functions, it also provides some properties:
Property | Description |
---|---|
document.URL |
URL of the current page, as a string |
document.location |
URL of the current page, as a Location object |
document.location = 'http://example.com' |
Navigate to a web page |
document.title |
The title of the document, as seen on tabs |
document.title = 'the joy of cooking' |
Updates the title of the document |
Finding an Element by ID
If an element has an id
attribute, you can get a pointer to that element with a single line of code:
let element = document.getElementById(id);
Once you have a pointer to that element, you can manipulate it further. You can also log it to the console for further inspection using:
console.log(element)
https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById
Finding an Element by CSS Selector
let element = document.querySelector('main div.preview > p')
This returns the first Element within the document that matches the specified selector (in this case, the first <p>
that is a direct child of any <div class='preview'>
that is in the main
section).
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
Using an Element
Once you find an element (using getElementById
or any other way), you can start using it.
let header = document.getElementById('header')
let text = header.textContent
There is also a property called innerText
but it's confusing and implemented differently in different browsers.
https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent
LAB: Update an Element
Finding many elements
In addition to getting a single element by its id
or a CSS selector, you can also ask the document to give all elements that match a certain criterion.
let elements = document.getElementsByClassName('profile-picture')
by CSS Class name
let elements = document.getElementsByTagName('h2')
by Element name
let elements = document.querySelectorAll('h2.preview > p')
by CSS Selector expression
These return collection objects, so you must write more code to get the actual element objects, or to check the collection's length.
Event Handler Functions
In JavaScript, event handlers are callback functions.
The classic example of an event handler is "onclick", i.e. "please call this function when the user clicks this button".
To attach an event handler,
1) Find the element, e.g.
let button = document.getElementById('magic');
2) Attach the callback, like this:
// plain function definition
button.addEventListener('click', function magicWord() { alert('Abracadabra!') });
// anonymous arrow function
button.addEventListener('click', () => { alert('Abracadabra!') });
NOTE: using the "fat arrow" for event handlers is a good idea since fat arrows will restore the
this
variable to point to the same object as when the listener was added.
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
LAB: Update Element on Click
Events by Reference
If you have already defined an event handler function, you can attach it by reference, like this:
<button type="button" id="magic">Magic</button>
<script>
function sayMagicWord() {
alert('Shazam!');
}
let button = document.getElementById('magic');
button.addEventListener('click', sayMagicWord)
</script>
NOTE: if you attach a listener by reference, pass the name of the function only! Do not immediately invoke the function, like this:
// BAD CODE, DO NOT USE
button.addEventListener('click', sayMagicWord())
This calls the function sayMagicWord
when the listener is attached and tries to attach the return value of sayMagicWord
(which will likely be undefined
).
Event Parameters
An event handler function can optionally accept a parameter -- usually called event
(or just e
) -- that contains [lots of information about the thing that just happened].
An event object has many properties but the most important one is event.target
, which points to the element where the action took place.
For instance, for a click event, event.target
contains a pointer to the element that was clicked.
<button type="button" id="presto">Presto...</button>
<button type="button" id="abra">Abra...</button>
<script>
var prestoButton = document.getElementById('presto');
var abraButton = document.getElementById('abra');
function sayMagicWord(event) {
if (event.target === prestoButton) {
alert('Change-o!');
} else if (event.target === abraButton) {
alert('Cadabra!');
} else {
alert('Shazam!');
}
console.log({event}); // for debugging
}
prestoButton.addEventListener('click', sayMagicWord)
abraButton.addEventListener('click', sayMagicWord)
</script>
Event Bubbling & Capture
- Events are created by their elements!!!
- After creation they move up the chain by default
- This behavior can be changed by using
event.stopPropagation()
in the listener
<div onclick="alert('outer div')">OUTER DIV
<div onclick="alert('inner div')">INNER DIV
<p onclick="alert('paragraph')">Paragraph</p>
</div>
</div>
Event Diagram
- DOM Scripting
- Scripts as attributes
- A Script Tag
- A Script Tag with src
- The `document`
- Finding an Element by ID
- Finding an Element by CSS Selector
- Using an Element
- LAB: Update an Element
- Finding many elements
- Event Handler Functions
- LAB: Update Element on Click
- Events by Reference
- Event Parameters
- Event Bubbling & Capture
- Event Diagram
- Labs