Java Script
Java Script
JavaScript will allow us to run code on the client side, meaning no interaction with the server is
necessary while it’s running, allowing our websites to become much more interactive.
In order to add some JavaScript to our page, we can add a pair of <script> tags somewhere in our
HTML page. We use <script> tags to signal to the browser that anything we write in between the
two tags is JavaScript code we wish to execute when a user visits our site. Our first program
might look something like this:
alert('Hello, world!');
The alert function in JavaScript displays a message to the user which they can then dismiss. To
show where this would fit into an actual HTML document, here’s an example of a simple page
with some JavaScript:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello</title>
<script>
alert('Hello, world!');
</script>
</head>
<body>
<h1>Hello!</h1>
</body>
</html>
Events
One feature of JavaScript that makes it helpful for web programming is that it supports Event-
Driven Programming.
An event can be almost anything including a button being clicked, the cursor being moved, a
response being typed, or a page being loaded. Just about everything a user does to interact with a
web page can be thought of as an event. In JavaScript, we use Event Listeners that wait for
certain events to occur, and then execute some code.
Let’s begin by turning our JavaScript from above into a function called hello:
function hello() {
alert('Hello, world!')
}
Now, let’s work on running this function whenever a button is clicked. To do this, we’ll create an
HTML button in our page with an onclick attribute, which gives the browser instructions for
what should happen when the button is clicked:
Variables
JavaScript is a programming language just like Python, C, or any other language you’ve worked
with before, meaning it has many of the same features as other languages including variables.
There are three keywords we can use to assign values in JavaScript:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Count</title>
<script>
let counter = 0;
function count() {
counter++;
alert(counter);
}
</script>
</head>
<body>
<h1>Hello!</h1>
<button onclick="count()">Count</button>
</body>
</html>
querySelector
In addition to allowing us to display messages through alerts, JavaScript also allows us to change
elements on the page. In order to do this, we must first introduce a function
called document.querySelector. This function searches for and returns elements of the DOM. For
example, we would use:
heading.innerHTML = `Goodbye!`;
Just as in Python, we can also take advantage of conditions in JavaScript. For example, let’s say
rather than always changing our header to Goodbye!, we wish to toggle back and forth
between Hello! and Goodbye!. Our page might then look something like the one below. Notice
that in JavaScript, we use === as a stronger comparison between two items which also checks
that the objects are of the same type. We typically want to use === whenever possible.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Count</title>
<script>
function hello() {
const header = document.querySelector('h1');
if (header.innerHTML === 'Hello!') {
header.innerHTML = 'Goodbye!';
}
else {
header.innerHTML = 'Hello!';
}
}
</script>
</head>
<body>
<h1>Hello!</h1>
<button onclick="hello()">Click Here</button>
</body>
</html>
DOM Manipulation
Let’s use this idea of DOM manipulation to improve our counter page:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Count</title>
<script>
let counter = 0;
function count() {
counter++;
document.querySelector('h1').innerHTML = counter;
}
</script>
</head>
<body>
<h1>0</h1>
<button onclick="count()">Count</button>
</body>
</html>
We can make this page even more interesting by displaying an alert every time the counter gets
to a multiple of ten. In this alert, we’ll want to format a string to customize the message, which in
JavaScript we can do using template literals. Template literals requre that there are backticks (`)
around the entire expression and a $ and curly braces around any substitutions. For example,
let’s change our count function
function count() {
counter++;
document.querySelector('h1').innerHTML = counter;
if (counter % 10 === 0) {
alert(`Count is now ${counter}`)
}
}
Now, let’s look at some ways in which we can improve the design of this page. First, just as we
try to avoid in-line styling with CSS, we want to avoid in-line JavaScript as much as possible.
We can do this in our counter example by adding a line of script that changes
the onclick attribute of a button on the page, and removing the onclick attribute from within
the button tag.
document.querySelector('button').onclick = count;
One thing to notice about what we’ve just done is that we’re not calling the count function by
adding parentheses afterward, but instead just naming the function. This specifies that we only
wish to call this function when the button is clicked. This works because, like Python, JavaScript
supports functional programming, so functions can be treated as values themselves.
The above change alone is not enough though, as we can see by inspecting the page and looking
at our browser’s console:
This error came up because when JavaScript searched for an element
using document.querySelector('button'), it didn’t find anything. This is because it takes a small
bit of time for the page to load, and our JavaScript code ran before the button had been rendered.
To account for this, we can specify that code will run only after the page has loaded using
the addEventListener function. This function takes in two arguments:
document.addEventListener('DOMContentLoaded', function() {
// Some code here
});
In the example above, we’ve used an anonymous function, which is a function that is never given
a name. Putting all of this together, our JavaScript now looks like this:
let counter = 0;
function count() {
counter++;
document.querySelector('h1').innerHTML = counter;
if (counter % 10 === 0) {
alert(`Count is now ${counter}`)
}
}
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('button').onclick = count;
});
Another way that we can improve our design is by moving our JavaScript into a separate file.
The way we do this is very similar to how we put our CSS in a separate file for styling:
1. Write all of your JavaScript code in a separate file ending in .js, maybe index.js.
2. Add a src attribute to the <script> tag that points to this new file.
For our counter page, we could have a file called counter.html that looks like this:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Count</title>
<script src="counter.js"></script>
</head>
<body>
<h1>0</h1>
<button>Count</button>
</body>
</html>
And a file called counter.js that looks like this:
let counter = 0;
function count() {
counter++;
document.querySelector('h1').innerHTML = counter;
if (counter % 10 === 0) {
alert(`Count is now ${counter}`)
}
}
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('button').onclick = count;
});
Having JavaScript in a separate file is useful for a number of reasons:
Visual appeal: Our individual HTML and JavaScript files become more readable.
Access among HTML files: Now we can have multiple HTML files that all share the
same JavaScript.
Collaboration: We can now easily have one person work on the JavaScript while another
works on HTML.
Importing: We are able to import JavaScript libraries that other people have already
written. For example Bootstrap has their own JavaScript library you can include to make
your site more interactive.
Let’s get started on another example of a page that can be a bit more interactive. Below, we’ll
create a page where a user can type in their name to get a custom greeting.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello</title>
<script>
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('form').onsubmit = function() {
const name = document.querySelector('#name').value;
alert(`Hello, ${name}`);
};
});
</script>
</head>
<body>
<form>
<input autofocus id="name" placeholder="Name" type="text">
<input type="submit">
</form>
</body>
</html>
We use the autofocus field in the name input to indicate that the cursor should be set
inside that input as soon as the page is loaded.
We use #name inside of document.querySelector to find an element with an id of name.
We can use all the same selectors in this function as we could in CSS.
We use the value attribute of an input field to find what is currently typed in.
We can do more than just add HTML to our page using JavaScript, we can also change the
styling of a page! In the page below, we use buttons to change the color of our heading.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Colors</title>
<script>
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('button').forEach(function(button) {
button.onclick = function() {
document.querySelector("#hello").style.color = button.dataset.color;
}
});
});
</script>
</head>
<body>
<h1 id="hello">Hello</h1>
<button data-color="red">Red</button>
<button data-color="blue">Blue</button>
<button data-color="green">Green</button>
</body>
</html>
Some notes on the page above:
JavaScript Objects
Let’s take a look at how to implement this API into an application by creating a new HTML file
called currency.html and link it to a JavaScript file but leave the body empty:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Currency Exchange</title>
<script src="currency.js"></script>
</head>
<body></body>
</html>
Now, we’ll use something called AJAX, or Asynchronous JavaScript And XML, which allows
us to access information from external pages even after our page has loaded. In order to do this,
we’ll use the fetch function which will allow us to send an HTTP request. The fetch function
returns a promise. We won’t talk about the details of what a promise is here, but we can think of
it as a value that will come through at some point, but not necessarily right away. We deal with
promises by giving them a .then attribute describing what should be done when we get
a response. The code snippet below will log our response to the console.
document.addEventListener('DOMContentLoaded', function() {
// Send a GET request to the URL
fetch('https://api.exchangeratesapi.io/latest?base=USD')
// Put response into json form
.then(response => response.json())
.then(data => {
// Log data to the console
console.log(data);
});
});
One important point about the above code is that the argument of .then is always a function.
Although it seems we are creating the variables response and and data, those variables are just
the parameters of two anonymous functions.
Rather than simply logging this data, we can use JavaScript to display a message to the screen, as
in the code below:
document.addEventListener('DOMContentLoaded', function() {
// Send a GET request to the URL
fetch('https://api.exchangeratesapi.io/latest?base=USD')
// Put response into json form
.then(response => response.json())
.then(data => {
Now, let’s make the site a bit more interactive by allowing the user to choose which currency
they would like to see. We’ll start by altering our HTML to allow the user to input a currency:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Currency Exchange</title>
<script src="currency.js"></script>
</head>
<body>
<form>
<input id="currency" placeholder="Currency" type="text">
<input type="submit" value="Convert">
</form>
<div id="result"></div>
</body>
</html>
Now, we’ll make some changes to our JavaScript so it only changes when the form is submitted,
and so it takes into account the user’s input. We’ll also add some error checking here:
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('form').onsubmit = function() {