Skip to content
Robyn Overstreet edited this page Feb 17, 2015 · 70 revisions

Javascript in the Browser

This week we're adding Javascript into the mix of front-end technologies -- HTML and CSS -- that we worked with last week. Javascript was invented as a client-side, or browser-based, language, and that's still where it's most used.

With just HTML and CSS, there's only a limited amount of interactivity available, such as changing the color of a link when a user hovers over it. With Javascript, we have many more tools to respond to user input and make changes to a page once it's loaded. These three technologies each handle different aspects of a page:

  • HTML - structure and content
  • CSS - look and feel
  • Javascript - behavior

This week's example code is in the Week3 folder in the repo.

Where to put the code

Like CSS, Javascript can go inside an HTML page or can be linked in to HTML from an external page. Many of the examples here use Javascript embedded in HTML for ease of reading, but as your Javascript code grows, you'll likely want to pull it out into a separate file.

Javascript embedded inside HTML goes inside a <script> tag. It is sometimes in the <head> but not always (more on that later).

<!DOCTYPE HTML>
<html>
<head>
	<title>Hello Javascript</title>
	<script>
		console.log("Hello Javascript");
	</script>
</head>
<body>
	<p>This page contains embedded Javascript</p>
</body>
</html>

When linking to an external Javascript file, the <script> tag looks like this instead:

<script language="javascript" type="text/javascript" src="myscript.js"></script>
Note on the demos

In addition to the week 3 code examples in repository, I've put a few examples on jsfiddle.net so you can play around with them live. jsFiddle is a browser-based preview tool that lets you experiment with HTML, CSS, and Javascript and see the results in real time. Sometimes this is handy for trying things out, though you do eventually need to work in your own files. There's no obligation to use jsFiddle -- it's there for your convenience if it's helpful. You don't need an account to use it, but you will need one if you want to save your modifications.

For a walk-through of how to use jsFiddle, see the official tutorial. Note that the tutorial uses the MooTools library, which you won't need for my examples.

DOM Manipulation

One of the primary uses of Javascript is to change the HTML of a page once it's been loaded into the browser. When something on a page changes without the page having to reload, that's usually Javascript. For example, if you type into a search box and you see the search results on the page change as you are typing, that's Javascript.

In order to change the contents of a page, Javascript needs to be able to reach into the HTML and access exactly the elements it wants to manipulate. In this context, the elements in HTML are known as the DOM, or Document Object Model. Essentially, the DOM is just another way of thinking of the structure of a web page, and it's the standard Javascript uses in order to interact with HTML.

A Web page is a document. This document can be either displayed in the browser window, or as the HTML source. But it is the same document in both cases. The Document Object Model (DOM) provides another way to represent, store and manipulate that same document. The DOM is a fully object-oriented representation of the web page, and it can be modified with a scripting language such as JavaScript.

from Mozilla Developers Network's Introduction to DOM

###Accessing Elements Parts of this section are adapted from the larger article Intro to DOM manipulation and events on the p5.js wiki

The examples below use the console.log() function in Javascript. To see the console in the browser, open Developer Tools and click the "Console" tab. This is where you will see the result of anything you output using console.log() in your javascript.

####getElementById()

The getElementById method returns the element on the page with the given id. In the example below, we place a paragraph on the HTML page and give it id "gargoyle". The JS code below searches the page for an element with id "gargoyle", stores it in the variable elt, and then prints in to console. getElementById is a method of document, which is the variable that represents the HTML page.

<html>
  <head></head>
  <body>
    <p id="gargoyle"></p>
  </body>
</html>
var elt = document.getElementById("gargoyle");
console.log(elt);

Notice that in the code below, the script is placed at the end of the <body> tag. This is because in order for Javascript to "see" the page elements, they have to have already been loaded by the time the script is run. (There is a way to make Javascript wait for everything to load before it runs, and we'll cover that in later examples.)

<html>
  <head></head>
  <body>
    <p id="gargoyle"></p>

    <script type="text/javascript">
      var elt = document.getElementById("gargoyle");
      console.log(elt);
    </script>
  </body>
</html>

####getElementsByClassName(), getElementsByTagName()

getElementsByClassName and getElementsByTagName work very similar to getElementById except both return an array of elements instead of just one element. getElementsByClassName returns an array of all elements with the given class, getElementsByTagName returns an array of all elements with given tag. With either method, if none are found, an empty array ([]) is returned.

<html>
  <head></head>
  <body>
    <div class="orange"></div>
    <div class="sponge"></div>
    <script type="text/javascript">
      var elt1 = document.getElementsByClassName("orange");
      console.log(elt1); // returns an array with one element
      var elt2 = document.getElementsByTagName("div");
      console.log(elt2); // returns an array with two elements
    </script>
  </body>
</html>

####querySelector(), querySelectorAll() Some newer Javascript functions offer more fined-tuned control over accessing elements. querySelector() and querySelectorAll() are especially handy because they use CSS syntax to find elements. For example, if you want to find all elements with the class "story", you'd use querySelectorAll(".story"). Just like in CSS, a class is denoted by a dot at the beginning. With querySelector(".story"), you'd get back only the first element of the class, even if there were many. Though here, the result isn't much different than using getElementsByClassName(), the power in querySelector comes when you want to more specificity than just a single class.

For example, in CSS, if you wanted to style only those list tags that appeared in the element with an id of "navbar", you'd write something like this:

#navbar li{
    color: green;
}

With querySelector or querySelectorAll, you could use the same syntax to drill down to exactly the elements you want. For example:

var menu_items = querySelectorAll("#navbar li");

###Modifying elements

####Changing HTML content (.innerHTML)

The innerHTML property is a pointer to the HTML content within a particular element, allowing you to easily access or change the content. The example below is similar to the previous one, but it prints the HTML within the element.

<html>
  <head></head>
  <body>
    <p id="gargoyle">I <b>love</b> pandas.</p>

    <script type="text/javascript">
      var elt = document.getElementById("gargoyle");
      console.log(elt.innerHTML); // I <b>love</b> pandas.
    </script>
  </body>
</html>

You can also change the content within the element, by setting the innerHTML property equal to some new value.

var elt = document.getElementById("gargoyle");
elt.innerHTML = "Veggie burgers are<br>so tasty.";

####Changing an attribute

You can change an element's attribute using a similar form, but replacing "innerHTML" with your desired attribute tag. The example changes the src attribute of an image.

var myImg = document.getElementById("myImageID");
myImg.src = "booya.jpg";

You can also change the style attribute of an element. In this case, you use the style attribute tag, which is followed by another "." and the particular style property to change.

var elt = document.getElementById("firstParagraph");
elt.style.color = "red";
elt.style.background = "pink";
elt.style.padding = "18px";
DEMOS

Event Listeners

The advantage of a front end language like Javascript is that you can respond immediately to a user’s actions without having to reload the page. Javascript calls these actions “events”. An event could be a mouse move, a scroll, a key press, an allotted amount of time, and many others. Here’s a list of the major Javascript events. Notice that not all of them are supported in all browsers. (Or, should you want to see absolutely all events ever conceived, see this doc.)

Javascript won’t tell you automatically when events happen; you have to register an Event Listener to pay attention to that particular event — to “listen for” a mouse click, for example. The function to register an event listener is addEventListener(). It takes two parameters -- the name of the event and the name of the function that will be executed when the event is fired. Notice that the name of the event is in quotes but the name of the function is not.

document.addEventListener('mouseup',clickListener);

function clickListener(){
    alert("You clicked me!");
}

Some common events are keyup, click, drag, focus, blur.

For more information about using event listeners, see the Events section of the p5.js wiki.

DEMOS: Event Listeners

A note on Javascript function syntax

Javascript has a rather unique way of dealing with functions compared to other programming languages. You can add function definitions within other function definitions. The syntax can be very confusing at first. You'll encounter a variety of different approaches when you research how to make things work in Javascript. Let's attempt to demystify a bit.

Named Functions

You're familiar already with defining a function and giving it a name, as in this code:

function doSomething(){
    console.log("something!");
}

In the event listener examples above, we passed the name of a function into another function as a parameter, as in:

document.addEventListener('click',doSomething);

Anonymous Functions

Javascript also lets you write the function itself right into a function call, without giving it a name. That's called an anonymous function and looks like this:

document.addEventListener('click',function(){
    console.log("something!");
});

Why do this? Let's say the only thing you ever need the function doSomething() for is to respond to the click event. Since you only need it in that one place, javascript lets you skip the step of defining and naming it. It also means that you can see what the function does right there in the code, instead of having to search through the script and find the doSomething function. Some people find that easier to read. Others disagree. Whichever you choose to use personally, it's good to be able to understand both approaches.