JavaScript Basics #3
- JavaScript Basics #1
- JavaScript Basics #2
- JavaScript Basics #3 ā You are here
- JavaScript Basics #4
- JavaScript Basics #5
Starting from this article, we are going to dive into the practical application of the JavaScript language in web development. We’ll talk about how JavaScript, HTML, and CSS can work together to make your web pages more appealing and interactive.
Exploring the DOM structure in JavaScript #
Let’s start with a quick review of the document object model. Here is a simple HTML document:
|
|
Each HTML element can be seen as a box. For example, the example document has the following structure:
For each box, JavaScript automatically creates a corresponding object, which we can interact with to find out more details about that box, such as its content, attributes, etc. This kind of representation is referred to as the document object model, or DOM for short.
The second important feature of this DOM structure is that the boxes are all connected to each other, which means if we pick a starting point, it is possible for us to move to any other node on the page. For example, the <body>
node has three child elements, <h1>
, <p>
and <div>
. The <div>
node has another two paragraphs (<p>
) has child elements. So, to locate the paragraph with a link (<a>
) in this example document, we can go from <html>
to <body>
to <div>
and finally, locate the <p>
node.
JavaScript and HTML #
To import JavaScript code into an HTML document, we can use the <script> </script>
tag.
|
|
It is customary to put the JavaScript code before the end of the <body>
tag. There are two ways to insert JavaScript, just like CSS, you can put it together with HTML, or you can put JavaScript in a separate file. For this tutorial, to make things easier, we’ll put HTML and JavaScript code together.
JavaScript treats each DOM box as an object, and that allows us to access any element in the HTML document using the global binding document
. For example, document.body
refers to the <body>
element of the document.
|
|
Go to Developer Tools -> Console in your browser, and you should see that the correct tag names have been returned.
Notice that the index number we use to locate the <div>
element is 5, that is because the childNodes()
method will return not only element nodes but also text nodes and comment nodes. For example, a paragraph element would have an element node <p>
, and a text node, which is its content.
In web development, it is possible to reach any specific element in the document by starting at document.body
and following a fixed path of properties. However, even though that’s possible, it’s still a bad idea, especially when you have a big HTML document with a complicated relationship tree. It is very easy to make a mistake. Luckily, JavaScript offers us some smarter ways of locating elements in an HTML document.
Locating HTML elements using JavaScript #
We mentioned before that JavaScript treats all HTML elements as objects, which implies there are built-in methods for us to use. In fact, there are several different ways we can locate elements in an HTML file using JavaScript, and they actually work a lot like the selectors we talked about in our CSS course.
For instance, all HTML elements have a getElementsByTagName()
method, which helps us locate elements with a specific tag.
|
|
This method will return a collection of elements with the specified tag, and you can access each one of them by specifying the index number, just like an array.
|
|
However, do not confuse this collection with an actual array, they are very similar, but not entirely the same. We cannot loop over it using for
/of
loop, we have to use the index numbers and run over the elements using a regular for
loop. Or we can transform this collection into an array using Array.from
method.
Once we’ve found the element we are looking for, we can access the attribute and content of that element using the dot (.
) operator, and we can change their values as well:
|
|
The second method is document.getElementById()
, it is used to find one single element, instead of returning a collection of elements. Note that this method does not exist under every element object, there is no document.body.getElementById()
.
|
|
The third method is similar, it helps us locate elements with the same class name. That is getElementsByClassName()
, which searches the entire document to find a collection of elements with the specified class name.
|
|
The last method is the combination of all of them, which is why it is the most commonly used method when we are trying to locate an element in HTML, it is the querySelector()
.
|
|
Adding and deleting elements #
Next, it’s time to talk about how to manipulate these HTML elements once we’ve located them. In fact, almost everything in the DOM structure can be changed.
For instance, we can remove an element like this:
|
|
Or we can create a new element, and add it to the DOM structure:
|
|
As we mentioned before, a paragraph element should have a <p>
element node, followed by a text node representing its content.
We can also replace one element with another:
|
|
In this SECTION, we briefly talked about how to locate and manipulate HTML elements using JavaScript. However, you may have noticed that all the changes are made instantly when we refresh our browser, which is not very interactive. In the next article, we are going to discuss what other events we can use to trigger JavaScript to perform an action.
Event handlers #
In computer programming, an event is a user input, such as mouse and keyboard actions, and the program is usually expected to respond with something. This process is called event handling. Let’s first take a look at a very simple example. We have an HTML document with a paragraph, and we want the page to return a message when it is clicked.
|
|
This time, the output message will only appear in the console when you click on the document, instead of the moment the page is loaded.
Registering event handlers #
The addEventListener()
method is how we can register an event handler for the document node. In fact, we can use the same method to register event handlers for any node in the HTML document. For example:
|
|
Actually, there is an onclick
attribute for the HTML nodes which will have the exact same effect. However, you can only register one handler for each node that way. By using the addEventListener()
method, we are able to register multiple handlers for each node.
|
|
The removeEventListener()
method, call with similar arguments can be used to remove an already registered event handler.
|
|
This button will only work once, after the removeEventListener("click", once)
method is executed, the event handler registered for the button will be removed. The function that is passed to the removeEventListener
has to be the same one that you passed to the addEventListener
method.
Propagation #
For most event types, the event handler registered for the node with children can receive events that happened in the children. For example, if a button inside a paragraph is clicked, the event handler registered for the paragraph will also be able to see that click event.
The event is said to propagate outward. For example, if both the button and the paragraph have an event handler, then the handler registered for the button will go first, then the paragraph, and it will keep propagating outward until it reaches the root of the document.
This feature can be quite useful sometimes, however, it is not always what we want. Luckily, we can stop the propagation using the stopPropagation()
method.
|
|
Sometimes we want to register event handlers for multiple elements on the page. To do this we can use the target
attribute to cast a wide net for a type of event.
|
|
Default actions #
A lot of the events have a default action, for example, when you click on a link, you will be taken to the link’s target, if you press the down arrow, the browser will scroll the page down. You can prevent that default action from being activated by using the preventDefault()
method. Let’s try something completely useless but very interesting.
|
|
Even though this is possible, don’t do this unless you have a very good reason to, or it will be very confusing for the users.
Key events #
Now we have discussed how event handlers work in general, it’s time to take a closer look at all the different types of events. The first one we are going to talk about is the key event.
When a key on your keyboard is pressed, it will trigger a keydown
event, and when it is released, it triggers a keyup
event.
|
|
Looks very simple, however, you do need to be very careful about the keydown
event. It is not a one-time thing, instead, it will keep being triggered over and over again, for as long as the key is being pressed, until it is released. You can experiment with the previous code, and see what happens when you keep the key pressed.
There are also some special keys like CTRL
, ALT
, and SHIFT
. These are called modifier keys, they modify the original value of other keys by forming a key combination. For instance, when you press a key while holding the SHIFT
key, "s"
will become "S"
, "1"
will become "!"
etc. We can register event handlers for key combinations like this:
|
|
Pointer events #
Pointer, as the name suggests, is used to point at things on the screen. There are primarily two ways that you can use to do that, either with a mouse or a touch screen, and they produce different types of events.
Mouse clicks #
Mouse clicks work similarly to key events. When you press a mouse button, a mousedown
event is triggered, and when you release that button, a mouseup
event is triggered. And after the mouseup
event, a complete click is finished, so a click
event will be fired.
|
|
When two clicks happen very close together, a dblclick
(double click) event will be triggered after the second click.
|
|
Mouse motion #
When a mouse pointer moves, a mousemove
event is triggered.
|
|
This can be very useful when you are trying to implement some sort of drag and drop functionality. But to do that, we need to first track the location of the cursor. To get that information, we can either use the event’s clientX
Ā andĀ clientY
Ā properties, which contain the eventās coordinates (in pixels) relative to the top-left corner of the window, orĀ pageX
Ā andĀ pageY
, which are relative to the top-left corner of the whole document.
For example, the following script will output the coordinates of the click events that happened on the page.
|
|
Here is a more complicated example, this program will display a bar, and you can drag it to change its width.
|
|
Notice that we used two different ways to access which button is pushed (The button
property and the buttons
property), and they clearly work differently. Their main difference is that the button
property can only tell you which button (singular) is clicked, while the buttons
property can tell you if a combination of buttons is pushed.
The button
property
0
: Primary button pressed, usually the left button or the un-initialized state1
: Auxiliary button pressed, usually the wheel button or the middle button (if present)2
: Secondary button pressed, usually the right button3
: Fourth button, typically theĀ Browser BackĀ button4
: Fifth button, typically theĀ Browser ForwardĀ button
The buttons
property
0
: No button or un-initialized1
: Primary button (usually the left button)2
: Secondary button (usually the right button)4
: Auxiliary button (usually the mouse wheel button or middle button)8
: 4th button (typically the “Browser Back” button)16
Ā : 5th button (typically the “Browser Forward” button)
The buttons property is able to record button combinations. When more than one button is pressed simultaneously, the values are combined. For example, when the primary and secondary buttons are pressed at the same time, the value will be 3
.
Touch events #
In most cases, the mouse events will also work when the user is using a touch screen. For example, when you are tapping a button on your screen, it will trigger a click
event, it will be the same as clicking it with a mouse pointer.
However, this won’t work in some cases, such as the resizing bar example we talked about before. Because the touch screen doesn’t have multiple buttons, and it can’t track your finger’s position when you are not touching the screen. So to solve this problem, we have a few specific event types triggered only by touch interaction.
When your finger touches the screen, it triggers a touchstart
event, when it moves while touching, it triggers a touchmove
event, and finally, when you lift your finger, it triggers a touchend
event.
Scroll events #
A scroll
event is triggered when you place the cursor on an element and scroll the middle button of your mouse. This can be very useful when you are trying to make your webpage more responsive. For example, when you go to the product showcasing page on Apple’s website, notice that the elements on the page will move as you scroll down.
Here is an example of a progress bar, it starts at 0% and will go to 100% as you scroll down.
|
|
Focus events #
When an element gains focus, a focus
event will be triggered, and when the element loses focus, a blur
event will be triggered. Unlike the other event types we’ve discussed, these two do not propagate.
This is most commonly used on HTML field elements. When you click on a text field and start typing some texts, that field is said to be in focus, and when you move on from that field and click on other elements, that field element loses focus.
This is an example that displays help texts for the text field that is currently in focus.
|
|
Load events #
The load
event is triggered when the entire page finishes loading. This is different from directly putting the code inside the <script>
tag directly without event handlers. The code inside the <script>
tag is run immediately when the tag is encountered. This might be too soon in some cases.
There is also a similar event type called beforeunload
. It is triggered when you close a page, the primary use of this event is to prevent the user from accidentally closing their unsaved work.
If you think my articles are helpful, please consider making a donation to me. Your support is greatly appreciated.