This website gives an introduction to Game Design. This webpage forms the 2nd introductory page in the series - providing a more detailed overview of some
basic HTML, Javascript and CSS techniques that will be used throughout this website. The other pages on this website cover: HTML5 Canvas, an object
of the HTML5 DOM that forms the stage for games on the web; Javascript, the language best suited for creating games on the HTML5 Canvas;
and developing CSS techniques (which is a minor feature of game development).
This webpage explains how to write code to do this:
/* ------------------------------------------------------------ *\
|* ------------------------------------------------------------ *|
|* Code Here
|* ------------------------------------------------------------ *|
\* ------------------------------------------------------------ */
In the actual examples, this area will have relevant code.
That is, the sole aim of this webpage is to explain how to combine HTML, Javascript, &/or CSS to create and style a button and then associate an action with
the resulting button.
Each section of this page introduces a new technique. I start each section with an example of the output of the technique, followed by a brief explanation,
then I finish by providing the source code (HTML, Javascript, &/or CSS).
As the above example show, the source code will be hidden initially, to be revealed by you when you click on a button. And so, it is that technique - of hiding,
then revealing, a section of a webpage - that I am going to use to explain some of the basics of HTML, Javascript and CSS. While not very interesting,
it does use Javascript and CSS in a way that is applicable to a wide range of web events (most of them more interesting than hiding/revealing sections of a webpage).
The first part of hiding/revealing a section of a webpage is to simply put the parts of the page to be hidden inside appropriate tags,
give the tags a class name, and give each tag an individual id. I have chosen the <details> tag (As, in HTML5, this tag "Defines
additional details that the user can view or hide"). So that the text to be hidden is enclosed in <details open class="reveal" id=pt#> ...
some text ... </details> (where the class name is "reveal" and pt# will be pt1, pt2, ... etc, i.e. the individual ids in each
case). [1]
When the text to be hidden is inside tags with a class name, you can use CSS to hide the contained text by using the "display: none;"
style.[2] That is, your CSS code will contain:
details .reveal{ display = 'none'; }
which hides the text contained in all of the 'details' tags that have the classname 'reveal'.
The final step is to change the CSS style from "display: none;" to "display:block;", which is done with Javascript (in response to you clicking a button).
By writing the appropriate Javascript code, you can create an "event listener" and "event handler" (these always come in pairs, one to "listen" for the event,
the other to "handle"/respond to the event) to respond to the click of a particular button. The response that we want is simply to change the display
style (in our CSS code) for the relevant details tag (and, as we shall see, we can also get the "handler" to perform a range of other tasks).
The process outlined above is relatively straightforward to accomplish. To introduce a feature that will be useful later on, I am going to
over-complicate this process by adding a transition. Transitions are CSS code that, as its name suggests, transitions from one style to another.
In this case we are going to create two styles of buttons, and we are going to add a simple transition between the two states "unclicked" and "clicked"".
So, that is the overview, which has revealed the steps that we need to complete:
Create an appropriate button (CSS)
Create an "event listener" for that event (Javascript)
Use the "event listener" to change the CSS style for the appropriate tags (Javascript)
Transition between the two CSS styles (Javascript & CSS)
This is what a button looks like simply using the HTML button tag with no CSS styling (in this case <button class="noCSS">Basic?</button>,
where the class attribute was neccessary to distinguish it from the buttons with CSS styling, which I have set as the default buttons).
Here is our button:
and it is still useless!! (because clicking on it does nothing).
This button was created using HTML, in the same way as the button above (<button >Nice?</button>) but it is styled using
CSS.[4] You can make the styling as simple as you wish, or as fancy as you wish. This one is about
half way. (There are "button generator" webpages that will create the CSS for you, which you can then simply download:
Here is an example). The CSS used to create this button,
will be revealed by clicking the button at the end of this section. By clicking on the button, to reveal
the source code, you get your first chance to see the completed task that this page explains: A styled button; A button that responds to being
clicked (an "event"); The revealing of the code relevant to the discussion; and The "transition" of the button to a different style.
At this point, we have completed the first step, we have a styled button. However, as there is no event associated with the "Nice?" button, it is useless (no
matter how many times we click it, nothing will happen). Associating a response to the event, the click, is the next step.
/* ------------------------------------------------------------ *\
|* ------------------------------------------------------------ *|
|* Style the HTML button using CSS
|* ------------------------------------------------------------ *|
\* ------------------------------------------------------------ */
/* This style will apply to all buttons, I remove these styles from specific buttons later */
button {
font-family: 'Quattrocento Sans', sans-serif;
font-size: 14px;
color: #fff;
padding: 10px 20px;
border: 2px solid #000;
cursor: pointer;
/* The groups of three below will, in years to come, be replaced by a single statement (the final statement, in each case).*\
\* Currently, they are necessary because each browser has its own name for these styles. */
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
background: -webkit-linear-gradient(top, #a3a3a3, #000);
background: -moz-linear-gradient(top, #a3a3a3, #000);
background: linear-gradient(top, #a3a3a3, #000);
-webkit-box-shadow: 5px 5px 3px rgba(0,0,0,0.5);
-moz-box-shadow: 5px 5px 3px rgba(0,0,0,0.5);
box-shadow: 5px 5px 3px rgba(0,0,0,0.5);
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
/* For when the mouse "hovers" over the button */
button:hover {
background: -webkit-linear-gradient(top, #acc7a3, #506651);
background: -moz-linear-gradient(top, #acc7a3, #506651);
background: linear-gradient(top, #acc7a3, #506651);
}
/* For when the mouse "clicks" the button */
button:active {
background: -webkit-linear-gradient(top, #858565, #c5c9a9);
background: -moz-linear-gradient(top, #858565, #c5c9a9);
background: linear-gradient(top, #858565, #c5c9a9);
}
/* By using the class attribute "noCSS", this style will apply only to buttons with that attribute *\
\* That is, this is where I remove the styles from buttons with the "noCSS" class attribute */
button.noCSS { /* options to remove styling, not interesting */
}
The simplest way to get a button to respond to being clicked is to include an "event listener" directly in the button
tag:
<button onClick="myFunction()">Click me</button>.
In this case, "onClick" is the event listener and "myFunction()" is the event handler (where
"myFunction()" would be a list of Javascript commands/statements written somewhere else on the page, in 'script' tags, or in an external file). To see how this works,
we can replace "myFunction()" with a function that comes "built-in" to Javascript, called "alert()". So by including the code:
<button onClick="alert('You Clicked Me!!')">Click me</button>,
we get this:
However, this "inline" method is not very flexible. As we shall see, connecting an "event listerer" indirectly gives us more options, especially when there
is more than one button, as is the case here (having multiple buttons means that an event listener has to be associated with each button, which is easier to do
using the indirect method - as it avoids having to repeat the same code for each individual button).
For the moment, lets just concentrate on how to attach an event listener to one button using the indirect method, and then extend that approach to all
buttons at once. We begin by declaring a variable, myButton1, that is, to all intents and purposes, equivalent to the button we want.
We do this by utilizing the id that we gave the button in question, which in this case is "button1":
myButton1 = document.getElementByID("button1"); document.getElementByID("button1") is the Javascript short hand for the Object "button1", which we name myButton1
(Naming the Object that we are interested in is just a way of creating a shorthand, so that we don't have to keep writing out document.getElementByID("button1")
everytime that we want to refer to it. It is important to note, therefore, that the name is equivalent to the Object).
The next step is to attach an event listener and an event handler to myButton1:
myButton1.addEventListener("click", makeClickHandler, false);
Where makeClickHandler is the name that I chose for the event handler, the function that will perform the actions that I require when the button is clicked
(to be discussed in the next section). And that is that.
All that remains now is to extend this to all of the buttons. We do this by declaring an array, containing all of the relevant buttons. To do this, we
use the class attribute that we defined for these buttons, (in this case I chose "expand" as the class attribute). To derive the array containing all of the
buttons with that class attribute we use:
var buttons = document.getElementsByClassName("expand");
To derive the array containing all of the sections that we want to reveal, we use their class attribute (for which I chose 'reveal'):
var details = document.getElementsByClassName("reveal");
Again, we are simply naming these arrays - so that we have a shorthand to refer to in later steps. We then loop through all of the buttons in this array,
associating each with the corresponding area that we want to reveal, adding an event listener to each:
for ( i = 0; i < buttons.length; i++) { addClickHandler(buttons[i], details[i]); }
Where "addClickHandler()" is the function that: a) contains the event handler (with the list of instructions that we want followed when the button is clicked)
and b) attaches this event handler to the appropriate button.
/* ------------------------------------------------------------ *\
|* ------------------------------------------------------------ *|
|* The Button Event Handler
|* ------------------------------------------------------------ *|
\* ------------------------------------------------------------ */
var buttons = document.getElementsByClassName("expand"),
details = document.getElementsByClassName("reveal"),
i;
function addClickHandler(buttons, details) { // outer function, to ensure that, while looping,
// the buttons are "attached" to the appropriate sections of the webpage (scope issue while looping)
function myHandler(event) { // event handler
if (details.style.display === 'block') {
details.style.display = 'none';
} else {
details.style.display = 'block';
}
}
buttons.addEventListener("click", myHandler, false); // event listener
for ( i = 0; i < buttons.length; i++) {
addClickHandler(buttons[i], details[i]);
}
Our basic event handler does only one thing, it changes the CSS associated with the tags "details" from display = 'none' to display = 'block'.
We have to tell Javascript that we want to change the CSS associated with the details tag. We do this by using details.style.display = 'block';
So, to create our "event handler" function, we simply wrap that statement in a function:
Where "click" is a specific command to the event listener (i.e. 'listen for the button to be clicked') and 'myHandler' is the name that I chose for the function that
is the 'event handler' (which contains the commands to be followed when the button is clicked).
[1] "open" in the details tag is required as some browsers have already added the "hide/reveal" functionality. That is, in the coming years,
the "hide/reveal" functionality that I am adding will be a default function of the detail tag.
[2] That is, you write the text as you normally would - i.e. the text is always there on the webpage - but the "display:none" CSS style
ensures that it is hidden from view. The CSS for these tags would simply read "details{ display:none; }" (or "details.reveal{ display:none; }" for "details" tags
with the class "reveal" - if you needed to be more specific, i.e. were using the details tag for other sections of that you did not want to hide/reveal (and so would
give them a different class name)).
[3] Buttons are Objects in HTML - that is, they are containers that have a range of pre-specified "properties". A little
later, we will be using these pre-specified properties to allow our buttons to perform actions. To allow us to see the properties an Object has, there is a Javascript
function getAllProperties() that I have running on this page. It returns a list of any Objects' properties. So, for example, we will, later, give
one of these button Objects an id button0. Using "command+option+i" (for a mac) or "F12" (for windows) we can bring up the console window.
If you copy and paste getAllProperties(button0) into the command line on the console, you will see what properties a generic button Object
contains. Impressive, no? (You can see that one of the properties available to us is "addEventListener", which we will use in the next section). This is an example
of the aspects of a web browser as an interpreter that runs "behind the scenes", and which gives webpage creators an enormous range of features to control.
[4] The CSS code can be included directly in the HTML page (by placing it between <style> css code here </style> tags) but
it is customary to write it in a separate file, getting the HTML page to read it by including a link to the file in the head of the HTML page (for example,
I have this statement in the head of this page that you are reading: <link rel='stylesheet' type='text/css' href='css/gameDesignIntroduction.css'>).
The same is true of Javascript code - except that Javascript code written directly in a HTML page is placed in "script" tags, like
this: <script> javascript code here </script>, and, if written in a separate file, is usually linked at the bottom of the HTML page,
just before the closing "body" tag, as I have done on this page, like so: <script src="js/gameDesignIntroduction.js"></script>