Introduction to programming

Functions and events

Functions

We've already seen in-built JavaScript functions, but the good news is that you can define your own. Functions allow you to encapsulate specific code in a block, which you can then easily call any time you like, avoiding the need for you to keep writing the same code out over and over again. As you can imagine, this is really useful.

A first function example

We've already looked at some code for creating a random number. Let's now look specifically at generating a random whole number between 1 and 10.

Exercise: Creating a simple function

Create a new template copy; in the browser console, enter the following line a few times:

var randomNumber = Math.floor(Math.random() * 10) + 1;
// Create random number 0-1, multiply it by 10, round down that
// result to nearest whole number, add 1.

Writing this out each time you want a random number will quickly get very boring, so let's put it in a function. Enter the following in the JavaScript area of your template, then save and refresh.

function random10() { // Create a new function called random10
  var randomNumber = Math.floor(Math.random() * 10) + 1;
  // generate random number
  return randomNumber; // return it out of the function
};

Note: This is just one way of creating your own function; there are other ways, but we'll move on, as time is short.

Now every time you want a random number between 1 and 10, you can just call this:

random10();

Try entering the above line in your browser console a few times: Much easier!

So the function contains a line that runs our random number code and stores it in a variable called randomNumber, and a second line that returns the randomNumber variable back out of the function so it can be used outside the code.

The reason this is needed is variable scoping - this allows variables to be accessed in the space they were created in. If they are created inside a function, they can only be used inside that function unless you return them out of it. If they are created not inside any functions, they can be accessed from anywhere inside the program (this is called having Global scope).

Note that open and close brackets have to be included after the function name to run it (invoke it, in proper terminology), so we have to write random10(), not just random10. The () is sometimes called the invocation operator. Try running just random10 in the console to see what happens!

Function arguments

And there's more. We've also already seen that we can give functions input values (called arguments or parameters), for example above, when we gave the Math.floor function a number to round down:

var randomNumber = Math.floor(Math.random() * 10) + 1;
// "Math.random() * 10" is Math.floor()'s argument

So we could go further and give our function a number as an input, so that you can tell it to generate a random number between 1 and whatever you want.

Exercise: Giving our function an argument

Update our function to the following:

function random(input) {
// same function as before, except this time we are allowing our
// function to accept an input value
  var randomResult = Math.floor(Math.random() * input) + 1;
  return randomResult;  
};

Now try running the function in your console a few times, for example:

randomNumber(250)

Cool huh? You can see both the above code examples contained in my basic function example.

A canvas function

Lets go a bit further then, and work on taking some code we created earlier and putting it into a reusable function. For example, my sine wave example from above would look something like this:

var myCanvas = document.getElementById('myCanvas');
var myContext = myCanvas.getContext('2d');

function sineWave(number,y) {
// two arguments are the number of squares to draw, and the y axis
//modifier to start drawing the sine wave at
  for(i=0;i<=number;i++) {
  // the number argument is being used in the exit condition
    myContext.fillStyle = 'rgba(0,0,'
      + (Math.floor(Math.random()*200)) + ',0.5)';
    myContext.fillRect((i*5),(y+(Math.sin(i/6))*50),10,10);
    // ## The y axis modifier is being plugged in here to set a vertical
    // position for the sine wave to start at. 
    // ## i divided by 6 is needed to make the amount the sine wave value
    // changes each time small, so you see an appreciable curve. change
    // the 6 to 4, then 3, then 2, to see what I mean.
    // ## This sin value is then multiplied by 50 to make the sine wave a
    // bit more visible, as sine wave values range between -1 and 1
    // - that would be a very small curve!
  }
};

Here we have a function with two input arguments, the number of squares to draw and the starting position of the sine wave on the y axis. I've then plugged those numbers in to the drawing function as the maximum bound set by the exit condition, and the modifier of the y coordinate (before it was set to a constant 250).

Now we can write

sineWave(200,150);

to draw a sine wave of 150 squares that begins at 200 pixels down the canvas.

If you are writing this out yourself, remember that you need a canvas in your HTML, if you haven't got one already:

<canvas id="myCanvas" width="500" height="500">
</canvas>

Create your own function

Try creating your own reusable function. How about a more complex version that takes in multiple arguments, allowing you to set your own colour as well? Try it! And then try something more complex too.

User interaction with events

Another essential part of programming is user interaction - how do you allow your users to interact with the user interface of your web page, application or whatever it is you are building and make things happen? This is done with event listeners — these are basically listening posts that listen out for an event happening (such as a button being clicked) then fire a notification when that thing happens that you can then do something in response to.

In JavaScript, you can use events in a variety of ways, some of them better than others. In the next example we'll just show one, to give you the idea.

Exercise: Simple events exercise

Let's set up a simple button that generates a message when clicked. First of all, take a new copy of the template file. Add the following to the HTML area:

<button class="welcome">Click me!</button>

And now some JavaScript — put this in your JavaScript area:

var button = document.querySelector('.welcome');
button.onclick = function() {
// so when the button is clicked, we run a nameless (anonymous)
// function containing the alert we want to trigger
  alert("Ouch, that hurt!");
};

If you add these and run the page, the alert message should appear every time you press the button. This function is an anonymous function, meaning it doesn't have a name, and is just acting as a container for the code we want to run. You could also write

var button = document.querySelector('.welcome');

function clicky() {
  alert("Ouch, that hurt!");
};

button.onclick = clicky;

This uses a named function, and does the same thing. This function does have a definite name, which can be referenced later on.

Note that in this case we are not including the invokation operator — the () - after clicky. This is because in this case we just want to reference the named function we are pointing to, but not run it until the button is clicked. The () is already included where we define the function (function clicky() { ... }); we shouldn't include it twice otherwise it will just run immediately when the page loads.

Exercise: a simple number multiplying app

Let's apply what we've learnt in this part of the course to building a simple little app that multiplies two numbers together and gives us the result. To allow the users of our app to enter the numbers to be multiplied, we'll use two form input elements.

Make a new copy of the template, then put the following in its HTML area:

<div class="form">
  <label for="number1">First number: </label><input type="text" class="number1" id="number1">
  <label for="number2">Second number: </label><input type="text" class="number2" id="number2">
  <button class="multiply" id="multiply">Multiply numbers</button>
</div>

Note: For now, don't worry too much about how these work. This is basically the kind of code used to create all those form fields that you have used on websites to register on sites when buying stuff, etc.

We'll also need an element to display the result of the multiplication. Let's just use a simple paragraph — add this to the HTML area:

<p class="result">The result is</p>

Next, we need to create variables to contain all the things we need to do things to. To start off with we just need to reference the button, and the result paragraph, in variables. Remember that they have class attributes, and to reference elements we can use var variableName = document.querySelector(".class");.

Add the following to the JavaScript area:

var multiplyNumbers = document.querySelector(".multiply");
var result = document.querySelector(".result");

Next we need to create a function that multiplies the two values inside the form input elements. We would do it like this:

  1. Use the same function as we did above to grab the input elements by their classess.
  2. Get the current values put inside those form elements by grabbing the result of the above step and appending .value to those variables (you can grab the current value of a form element by doing formElement.value).
  3. Multiply the above two values and store the result in a new variable.
  4. Make the innerHTML of the result paragraph equal to the result of the multiplication

Add the following to the JavaScript area, underneather what is already there:

function multiply() {
  var number1 = document.querySelector(".number1").value;
  var number2 = document.querySelector(".number2").value;
  var value = number1 * number2;
  result.innerHTML = "The result is " + value;
}

Now you need to set an event handler on the button, so that when it is clicked it runs the multiplication function. Add the following line to the bottom of the JavaScript area:

multiplyNumbers.onclick = multiply;

As a bonus step, let's explore a different event that makes the app work a bit differently. There is an event called blur, which is fired on a form element when the element loses focus (this is when you tab out of a form input, or click somewhere else so it stops being selected.)

  1. First of all, delete the button element, and the variable that references it (multiplyNumbers in my above code.)
  2. Now add the following two variable definition lines below the first one — note that here we are grabbing the input elements themselves inside variables, not their values:
  3. var input1 = document.querySelector(".number1");
    var input2 = document.querySelector(".number2");
  4. Now we just need to swap out our event handler lines; replace the original one with the following two:
  5. input1.onblur = multiply;
    input2.onblur = multiply;
  6. Now try it! You should now find that the multiplied value is updated whenever you unfocus a form element.

Another quick improvement that you could make to the code is related to the variable definitions inside the function. Because you've already stored the form elements themselves in variables before the function starts, you can change the first two lines inside the function to this:

var number1 = input1.value;
var number2 = input2.value;

Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License. Share it, make it better, use it for good.