1.2 Three languages of the web
One of the challenging aspects of web development is that the programmer needs to know three different languages: HTML, CSS, and JavaScript. Each language is responsible for a different kind of information that the web browser needs in order to render the final website. HTML defines the structure of the elements on a website, such as the presence of text and images. CSS controls how those elements look. If you want to change the size of an image, the color of a background, or the font of a paragraph, you’ll be using CSS. HTML and CSS are both markup languages. [Need description of what that means]. JavaScript, on the other hand, is a true programming language. In addition to all the normal kinds of computation that programming langauges generally allow, JavaScript is especially good at interacting with HTML and CSS. JavaScript can manipulate the HTML and CSS of a website, allowing the programmer to specify rules about when certain elements on the page should be added or removed (manipulating HTML) and when their appearance should change (manipulating CSS). These interactions can produce very simple results, such as changing the size of an image when the user clicks on it, or very complex ones, such as the development of a video game entirely in HTML, CSS, and JavaScript.
To create a simple experiment in jsPsych, you only need to have a basic familiarity with JavaScript. There is minimal HTML and CSS in the first few experiments in this book. However, if you want maximal flexibility over what content is in the screen and how it appears, you will need to become familiar with HTML and CSS. As you will discover, jsPsych is designed to allow users who are comfortable manipulating HTML and CSS full control over the output. [possible figure here with two different jsPsych examples, one simple one fancy].
1.2.1 HTML
HTML (Hyper Text Markup Language) defines the elements that exist on a webpage. For example, the HTML below defines two paragraphs.
HTML uses tags – like <p>
and </p>
above – to define elements. The type of element is defined by the text in the tag. <p>
tags create paragraphs, <img>
tags create images, and <audio>
tags create audio. Elements begin with the type of element in < >
brackets, and end with the same tag plus a backslash: </ >
.
HTML defines a lot of different elements. [maybe a link here?]. But you don’t need to know all or even most of these to get started with HTML. As long as you understand a few ideas about how to use HTML, you’ll be able to understand HTML markup and modify it to suit your needs.
1.2.1.1 HTML attributes
HTML tags often have additional attributes that control additional properties of the element. One attribute of the <img>
tag is the src
, which defines the source of the image. The <img>
tag below has the src
attribute set to the URL of the jsPsych logo.
Attributes are declared by putting a space between the tag name and the attribute name and =
after the attribute. The value to the right of the =
will be assigned to that attribute. Tags can have multiple attributes separated by a space. The alt
attribute for an img
tag is used to describe the alternate text that would replace the image for users using screen readers or other assistive devices.
Two very useful attributes to know are id
and class
. These are both ways to identify elements on the page so that JavaScript and CSS can interact with them more easily. id
values should typically be unique, and are used when CSS or JavaScript needs to target one particular element on a page. class
values can be applied to many elements on a page, and are used when CSS or JavaScript needs to interact with all the instances of a particular set of elements.
1.2.1.2 Nesting elements in HTML
Elements in HTML can be nested within other elements. For example, a link to another website may be nested within a paragraph.
<p>Please see the <a href="https://www.jspsych.org">jsPsych documentation</a> for more information.</p>
An important aspect of nesting elements is that the inner-most element (<a>
above) must be closed before the element that contains it is closed. The following is wrong because the <p>
element is closed before <a>
, but <a>
started after <p>
.
Nesting allows HTML to naturally reflect the hierarchical structure of a webpage. Webpages often have distinct sections, like navigation and content, that contain many elements. The <div>
element is used to create arbitrary divisions of the page.
1.2.1.3 A bare-bones HTML document.
If you create a text file with a few words in it, save it as a .html
file, and open it in a web browser you’ll find that it is displayed as a web page. In some sense, a file of text is a minimal HTML file. However, most HTML files have a standard set of sections that look something like this.
<!DOCTYPE html>
<html>
<head>
<title>A bare-bones HTML document</title>
</head>
<body>
</body>
</html>
The above has a few HTML-elements, <html>
, <head>
, <title>
, and <body>
, as well as something that looks like an HTML element – <!DOCTYPE html>
but is actually a declaration to the web browser about what kind of document this is and what the root element of the document is. In this case <html>
serves as the root element, which is standard practice.
<head>
defines the head-section of the document, which can contain information about the page that is not directly rendered in the visible page. An example of this is the <title>
element, which controls the title that is displayed in the window or tab of the web browser.
<body>
is the element that contains all of the content that will be displayed.
1.2.2 CSS
CSS (Cascading Style Sheets) is a markup language that defines the visual appearance of elements on a webpage. For example, this CSS rule declares that all text in <p>
tags will be displayed with a 24px font and in red.
CSS rules require the use of a selector. The selector defines the set of elements that the rule applies to. The selector appears before the {
. In the above example, the selector applies the rule to all <p>
elements. Any HTML element type can be used as a selector. For example, the following properties set the background color of the <body>
element to black and the text color to white.
Two common selectors are selection by ID and by class. Recall that the HTML attribute id
can be used to assign a unique name to an element, and the HTML attribute class
can be used to group elements that share something in common together under a shared name. To apply a CSS rule to an element with a particular ID, the #
symbol is placed before the ID.
To apply a CSS rule to all elements that belong to a particular class, the .
symbol is placed before the class name.
Inside the { }
appear a list of style rules that are applied to all elements that match the selector. The set of style rules is enormous, so the important thing is not to memorize different rules that could be applied, but rather to understand the concept of applying rules to elements based on selectors.
1.2.2.1 Where does CSS go in a document?
There are three places where CSS typically appears in an HTML document. Each of these places is equally valid, and the choice of where to include CSS depends on what is easiest. Often CSS will exist in all three locations in a single document.
1.2.2.1.1 External CSS file
One option is to create a separate .css
file and load the file in the HTML document via a <link>
tag in the <head>
element.
styles.css
webpage.html
The <link>
tag has a few attributes that need to be set. The href
attribute is the path to the source file. This path is relative to the location of the .html
file that the <link>
is in. If the .html
and .css
files are in the same folder, then just the name of the .css
file is sufficient. The rel
and type
attributes both describe what kind of content is being loaded.
1.2.2.1.2 <style>
tag
Another option is to include a <style>
tag in the <head>
element of the document.
1.2.2.1.3 style
attribute
HTML elements also support the style
attribute, allowing styles to be set within the tag itself.
<body style="width:600px">
<p style="font-size:18px; font-weight: bold;">The start of a paragraph...</p>
</body>
This method is a little bit different than the first two, because there is no selector or { }
to define the rule. That’s because the style attribute of an element only applies to that element. This method of adding style can be useful when there is only a single element that needs the style rule. This method is also used a lot by jsPsych because (as will become clear much later in the book) it is a relatively easy way to embed style information in JavaScript code that is generating HTML content.
1.2.3 JavaScript
JavaScript is one of the most popular programming languages. Originally created to enable dynamic and interactive content in websites, JavaScript is now used for both websites and general purpose programming. JavaScript is still the dominant language of the web because it is understood by all the major web browsers and is enabled by default.
Some of the things that you can do with JavaScript include:
- Changing HTML and CSS of a website in response to events. For example, a short JavaScript program make it so that when a user clicks a button an image on the page is changed to a new image. Controlling HTML and CSS will be one of the primary ways in which JavaScript is used when building online experiments.
- Recording data about how a user interacts with a webpage. JavaScript has access to information like what keys are being pressed on a keyboard and where the mouse is on the screen. It also has access to the time that these events occur.
- Sending and retrieving data from other applications on the web. For example, JavaScript can communicate with a database to store and access data.
Learning JavaScript is a much bigger task than learning HTML or CSS, but you don’t need to master JavaScript to start using jsPsych. If you learn a few features of the language and understand how JavaScript interacts with HTML and CSS then you’ll be able to start programming the experiments in this book.
1.2.3.1 The JavaScript language
1.2.3.1.2 Variables
Variables are a way to store information. To store the value 3
in the variable x
, we can do the following.
var
, short for variable, is how we declare that something is a variable. The =
sign is called the assignment operator. In this case we would say that we are assigning the value 3
to the the variable x
. In addition to numbers, two other common kinds of values that are assigned to variables are set of characters (called strings
) and the boolean values true
and false
.
Strings are created by placing the set of characters inside either single quotes ' '
or double quotes " "
. Either one is acceptable, but the starting and ending quote type need to match.
Changing the value of a variable that already exists works almost the same as creating a variable, except that you don’t need the var
keyword, because JavaScript already understands that the name refers to a variable.
1.2.3.1.3 Arrays
Arrays allow related data to be stored together in a single variable.
var months_of_the_year = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
They are created with square brackets [ ]
and commas separating each value.
Information in an array is accessed by putting the index of the desired position in the array inside the [ ]
. To get the first item in the array:
Note that array indices begin with 0, not 1. Though sometimes confusing, this is standard practice in most programming languages.
1.2.3.1.4 Objects
Objects also allow related data to be stored together, but unlike arrays each bit of data in an object is named.
There are two primary ways to access the data stored in an object.
Dot notation uses a .
after the variable name.
Bracket notation uses square brackets with the name of the property inside the brackets.
1.2.3.1.5 Operators
Operators perform assignment, arithmetic, comparison, or logical operations between different values.
One operator that has already appeared above is the assignment operator, =
. It takes the value on it’s right and stores it in the variable on the left. Values can be assigned to normal variables, arrays, or objects.
Arithmetic operators perform addition, subtraction, multiplication, and division:
Comparison operators are used to check if two values are equal, or if there is a particular kind of difference between values.
==
checks for equality
!=
checks for inequality
>
checks if the left value is greater than the right. >=
checks if the left value is greater than or equal to the value on the right.
<
checks if the left vaue is less than the right. <=
checks if the left value is less than or equal to the value on the right.
Logical operators determine whether there is a particular relationship between values.
&&
checks if the value on the left AND the value on the right are both true.
true && true; // true
3 > 2 && 1 == 1; // true
var three = 3;
var five = 5;
three < 2 && five > 4; // false
||
checks if the value on the left OR the value on the right is true.
true || false; // true;
3 < 2 || 1 != 1; // false;
var three = 3;
var five = 5;
three < 2 || five > 4; // true;
!
inverts the truth value of whatever appears on the right.
1.2.3.1.6 Functions
Functions, sometimes also called methods, are self-contained sets of code that can be invoked through a name given to the function.
// create a function
function addTwo(x){
return x + 2;
}
// invoke the function
addTwo(6); // outputs 8
Functions are created via the function
keyword. Functions can have 0 or more parameters. In the example above, addTwo
has one parameter called x
. This parameter is defined by putting the desired name of the parameter inside the ( )
that occur immediately after the name of the function. Inside the body of the function, the code between the { }
, x
takes on whatever value is used when the function is called. If the function call is addTwo(6)
, then x
is 6. If the function call is addTwo(1)
, x
is 1. The output of a function is specified by the return
keyword. In the addTwo
function, the statement x + 2
is evaluated and the resulting value is the output of the function. The output can be stored in a variable.
1.2.3.1.7 Control Statements
1.2.3.2 JavaScript + HTML/CSS
JavaScript is the tool that can turn a static website into an interactive one. JavaScript can alter the HTML and CSS of a website, allowing it to indirectly control what appears on the website and how it looks. There are several different approaches for using JavaScript to control the HTML and CSS of a website, and this section only covers a few of the most common.
A powerful JavaScript function is .querySelector()
. This function works in a similar way to CSS selectors. You can provide a selector, and the function will return the first HTML element that matches the selector. Unlike CSS selectors, with .querySelector
you have to specify a root element, which is the HTML element that querySelector
will search in. If you want to search the entire page, you can use the document
root element.
.querySelector()
selects an HTML element, which can then be modified in a few different ways. One task that you might want to accomplish is to change the content of that element, and one way to accomplish this is to change the .innerHTML
property of the element.
Another task is modifying some aspect of the style of the element. All the style properties of an element can be accessed with .style
and then the property name. For example, the following code changes the background color of the <body>
element.
1.2.3.3 Where does JavaScript go in a document?
Like with CSS, there are several ways to include JavaScript in an .html
document.
1.2.3.3.1 <script>
tag with src attribute
JavaScript can be stored in a separate .js
file and then loaded into a document using the <script>
tag.
code.js
function changeColor(){
if(document.querySelector('body').style.backgroundColor == 'white'){
document.querySelector('body').style.backgroundColor = 'black';
} else {
document.querySelector('body').style.backgroundColor = 'white';
}
}
webpage.html
The src
attribute provides the path to the .js
file, relative to the location of the .html
file that contains the <script>
element. If the .html
and .js
files are in the same folder, then the filename alone is sufficient.
The example above creates a function changeColor()
which will change the background-color
style rule for the <body>
element every time it is called. If the current color is white
then it changes to black
; otherwise it changes to white
. This function, once loaded via the <script>
tag, can be called by other JavaScript code in the HTML document.
1.2.3.3.2 <script>
tag with embedded content
The <script>
tag can also be used without the src
attribute, placing the JavaScript directly inside the tag instead.
<head>
<script>
function changeColor(){
if(document.querySelector('body').style.backgroundColor == 'white'){
document.querySelector('body').style.backgroundColor = 'black';
} else {
document.querySelector('body').style.backgroundColor = 'white';
}
}
</script>
</head>
This has the equivalent effect of the first example. The <script>
tag does not necessarily need to appear in the <head>
section. Often the <script>
tag is placed after the end of the <body>
, in order to have the content in the <body>
tag load first. In the minimal HTML document, it would look like this.
1.2.3.3.3 In certain attributes
Some HTML attributes support JavaScript code embedded right in the HTML tag declaration. However, this is mostly an outdated approach at this point, and this method is not recommended. It’s mentioned here in case you come across it. An example of this approach is the onclick
attribute of a <button>
element.
Every time the button is clicked the JavaScript function changeColor
will be called. This function would be defined in a <script>
tag elsewhere in the document. The JavaScript code is not limited to calling a single function. In theory, many statements could be executed by the button click, but in practice most programmers find that trying to embed long bits of JavaScript in HTML attributes produces difficult to read code.
1.2.3.1.1 Comments
In JavaScript, every bit of text is either a comment or code. Comments are there only for the benefit of the programmer or anyone else reading the code. They are ignored by the JavaScript engine.
To comment text on a single line, use two forward slashes
//
To comment multiple lines of text, use
/*
at the start and*/
at the end.