Maintained by: David J. Birnbaum (djbpitt@gmail.com)
Last modified:
2021-12-30T03:04:18+0000
JavaScript has become a general-purpose programming language used in a number of contexts, supporting a range of initiatives in software development. In this course, we use JavaScript code on the web, known as client-side JavaScript, to create Dynamic HTML, or DHTML. The difference between plain ol’ HTML and HTML embedded with JavaScript (DHTML) is that the latter is interactive, which is to say that it enables the user to interact with and change the page in the browser.
When a web user types a URL into the browser address bar and a website loads, the user’s
computer is operating as a client, and the website the user sees is a
server (because it is serving
web pages to the client). Right now,
as you read this page, your computer is a client that downloaded this webpage from the
Obdurodon server. How servers know what information to send and where to send it is not
our concern in this course. What you should know, however, is that the client downloads
information from the server, usually via some sort of web browser. The browser knows how
to present the information it downloads because it comes in a standard format, such as
HTML or XML.
When the client (your personal computer, for example) downloads a web page, it may also
download a separate CSS document automatically, without asking for it explicitly, and
that CSS stylesheet will be used to style the HTML or XML in the browser. Whether a
separate CSS stylesheet is delivered alongside a web page depends, as you know, on
whether the author of the web page has incorporated a link in the HTML
<head>
that points to a separate stylesheet.
JavaScript operates similarly; the developer of a web page can include a link to a
separate JavaScript file, which will then be delivered automatically along with the web
page when the user requests the latter. This is called client-side
JavaScript
because the JavaScript code is run locally, that is, it is executed and
processed entirely by the client computer, and does not have to return to the server for
more information. This is the preferred way to let the user modify the browser display;
the slowest part of loading and styling a web page is typically sending a request to the
server and waiting for the information one needs to be returned, so that process is
avoided when possible by using JavaScript. If all of the desired information can already
be accessed by the client, modifying the rendering client-side is much faster than
sending a new request to the server.
JavaScript, like all of the languages we have been working with in this class, understands how to deal with hierarchies. All of our XML and HTML documents have been in hierarchical formats, and JavaScript is just as capable as XPath in being able to traverse and manipulate document hierarchies, and to interact with elements according to their properties. There are some differences, of course, but conceptually, we can use the same types of operations we have been using in all of our X-languages in JavaScript.
The main difference between client-side JavaScript’s understanding of document
hierarchies and our XML-based understanding is that the main entry point to a hierarchy
in JavaScript is no longer the document node (which we address by beginning a path
expression with a slash [/
] in XPath), but what is
called a window object. The reason for this is that JavaScript is capable of
working with the entire browser window, and not just the XML or HTML document it is
rendering. The window object represents a frame or window within your web browser, and
can be referred to with the keyword window
.
Think of window
as a reference to the very top
of your document, much like /
resets the context of
our XPath expressions (that is, starts a new path at the very top of the document
hierarchy). Note that object is a common term within computer science, and
generally refers to a named variable with any number of values or properties. We can
think of XML elements as objects, because not only can they have a text value, but they
can also have a number of properties; for any XML element, its properties can be said to
include both its attributes and its relation to the document: any ancestor, sibling, or
child elements, that is, all of the axes we have become familiar with. To learn
JavaScript, we must adopt this new nomenclature of objects and properties.
The window
object has a property
called document
, which is a Document
object that can be referred to with the keyword
document
(yes, objects can have properties that
are also objects). A Document object represents a Node that is the start of an HTML or
XML document tree. In the case of the window
,
its document
property contains all of the
Element objects that compose our website, in either HTML or XML form. We
will use the document
keyword frequently to
access various elements in our web document. To put this in plain language: a window in
your browser has a document (a Document object that is its document property), and the
document has elements (the Element objects it contains).
Most of the projects in this class will use JavaScript to change the appearance of a web
page in a user’s browser in response to user interactions, so we will focus on how to
accomplish that type of task. User interactions with a document like click, mouseover,
or button press are called events, and we can tell the browser to respond to
specific events by creating a JavaScript event handler. An event handler has
a target, which is the object in the document where the event occurs. A
target might be a button the user can click or a menu tab that will open up into a list
when moused over. Elements in the document
can
have event handler properties; for example, a menu tab in the document might
have the property of being associated with an event handler that knows what to do when a
user mouses over the tab. The components of an event handler, then, are the
target (the element in the document where the event occurs), the
event (what has to happen to the target to cause the event handler to
fire), and the event handler code, which describes what happens when the
event occurs at the target.
All event handlers have names that are the concatenation of the prefix on
and the
name of some event, like click
or mouseover
(that is,
onclick
or
onmouseover
). We can assign these properties to
a specific action that we want to occur when the event happens, that is, on the
occurrence of the event. There are three practical ways of doing this, all of which have
analogs in CSS; we use the second method in our own work, and it’s what you should use
for assignments in this course, including your projects.
onclick
event handler can be deployed for a
particular element by assigning a value to the
@onclick
attribute of that element.<p onclick="stuff();">
will cause a
JavaScript function called stuff()
(which
we write ourselves) to fire whenever the user clicks on that particular
paragraph.<p style="color: red;">
uses inline CSSto color a paragraph red.
<head>
of the HTML document<script type="text/javascript" src="stuff.js">/**/</script>
causes the JavaScript code in an external file called stuff.jsto load and run. To enhance compatibility with older browsers, it is common to write separate start and end tags with
/**/
between them,
instead of a regular XML empty element.<link rel="stylesheet" type="text/css" href="style.css"/>
causes an external CSS stylesheet to be associated with the HTML document. The
stylesheet contains the information that associates styles with specific elements,
just as an external JavaScript file may contain the information to associate event
handlers with their targets, that is, with the elements in the HTML document where
the events occur.<script>
element in the
<head>
of the HTML documenttargetelements within the HTML. Instead, the handlers are assigned within the JavaScript script. The difference between #2 and #3 is that in #2 the
<script>
element links to an external file
that contains JavaScript code, but it does not contain any JavaScript code itself.
With #3 there is no external file, and the raw JavaScript code is written between
the start and end <script>
tags.<script type="text/javascript"> (raw JavaScript code goes here) </script>
<style>
element in the
<head>
of the HTML document.Recall that the preferred way to cause CSS styling to be applied to HTML is to create an
external CSS document and link to it from the HTML. It is possible to write CSS rules
directly inside the HTML, either inside a
<style>
element in the
<head>
(analogously to our #3, above) or in
@style
attributes on individual elements
(analogously to our #1, above), but for a variety of reasons that is rarely the best
approach. Similarly, the preferred way to associate JavaScript with HTML is to use the
second of the methods above, that is, to write all of the JavaScript event handlers
outside the HTML, in a separate JavaScript file, and associate that file with the HTML.
Nonetheless, because the first approach is easier to understand and to code and the
third avoids the step of managing an additional document, we may use them for some
assignments in this course. You can combine these three methods within in a single
document, just as you can combine the different CSS methods.
External JavaScript scripts are, by convention, stored with a .js
file extension
(just as CSS files by convention end in .css
). You can create and edit JavaScript
in <oXygen/>.
How do we describe actions in JavaScript? That is, how do we tell JavaScript what to do
when an event occurs on a target? Functions in JavaScript, as in XPath, perform actions
using a set of input parameters. A simple function in JavaScript called
alert()
takes a single string as its input, and
alerts the user by creating a tiny popup window with the string as a message inside it.
For example, if we wanted a click event for some target to alert the message, Catz r
kewl!
, we would assign the event handler like this:
onclick="alert('Catz r kewl!')"
, which we have
done for this <span> element. We’ve used
strategy #1, inline JavaScript attached to an
@onclick
attribute, to make this happen; you can
see our underlying code by viewing the source of this page.
DOMContentLoaded
eventThe window
has its own
DOMContentLoaded
event, which is triggered when
the content of the document inside it is finished loading the HTML elements and is ready
to be presented in the browser. This lets it function as a bootstrapping event; because
it fires automatically whenever the document loads, it can be used to initialize other
JavaScript functions. We can assign this event handler to a specific action that we
would like to be performed upon the triggering of the
DOMContentLoaded
event.
Event handlers normally listen on the element to which they’re attached. Recall that the
target of the event handler is the element where the event occurs.
For example, the onclick
event listener in the
example above listens for a click on the <span>
that carries the @onclick
attribute, and when the
user clicks on that <span>
, it activates the
alert()
function. Clicking elsewhere doesn’t
trigger the alert; the event handler is listening for clicks only on the
<span>
with which it’s associated.
That’s fine for elements like <span>
, but the
window isn’t an element and doesn’t have attributes, so if we want an event to fire when
the window loads, we need a different strategy. The way to associate a
DOMContentLoaded
event handler with the window
is to use the method
addEventListener('event', function(), false)
writing
window.addEventListener('DOMContentLoaded', alert('Katz are kewl!'), false);"
would mean fire this event (pop up the alert) when the window
.DOMContentLoad
event occurs (that is, when
the window finishes loading the HTML for the document)
When we add a listener, we must provide an event, a function to be triggered when the
event occurs, and a boolean (true
or false
value). This third argument
indicates whether the listener should use event capturing or
bubbling. You don’t need to know about the difference; for our use, we
will always set this value to false
. If you would like to learn more, read here.
Try creating an HTML document, with a paragraph
(<p>
) containing some text, and a span
(<span>
) containing part of the text within that
paragraph. Give the span an @onclick
attribute, the
value of which is an alert (alert()
) that has a
specific message associated with it (inside quotation marks between the parentheses). In
Real Life you’ll want to style the span, so that the text is visibly different from the
rest of the paragraph and your users will know that it’s clickable. You can do that now,
or, for this exercise, you can just remember which portion of the text you assigned an
event handler to. As explained above, in Real Life we don’t use inline
@onclick
attributes (method #1 of the three methods
described), but we’re using it here so you can see the results before moving it out of
inline position, as we do in our real projects.
After you’ve tested that, modify the HTML document by including a
<script>
element within the
<head>
that reads as follows:
<script type="text/javascript">
window.addEventListener('DOMContentLoaded', alert('Insert message here.'), false);
</script>
Note that the XHTML rules require that you include a
@type
attribute on your script element with a value
text/javascript
.
We ended that single line of code with a semicolon. The rules for JavaScript, as for CSS, are that you can include multiple statements in a set of rules, and each must end with a semicolon. The semicolon is optional on the last (or only) statement in both CSS and JavaScript, but we strongly advise including it, so that you won’t forget about it should you go back and add another line. When you’re done, refresh your page, and you should get an alert with the message you wrote in your script before your paragraph’s content is even drawn to the screen.
The resulting HTML document should look something like this:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Your first JavaScript script</title>
<script type="text/javascript">
window.addEventListener('DOMContentLoaded', alert('This message came from loading the window!'), false);
</script>
</head>
<body>
<p>This is a sample paragraph of text meant to <span
onclick="alert('This message came from clicking the span!');"
style="color:blue; text-decoration:underline; cursor:pointer">exemplify the
circumstance</span> of possibly having an HTML paragraph, perchance.</p>
</body>
</html>
The use of JavaScript to modify CSS in memory, changing the appearance of a page that has
already been loaded in the browser, is called DHTML (dynamic HTML
).
You can see it in action at http://zatochnik.obdurodon.org. Clicking on numbers in the SVG at the top or on
individual paragraphs in either of the columns on the sides causes paragraphs to appear
and disappear (toggling the CSS display
property) and
change color and other font properties (toggling the CSS
color
and
font-decoration
properties). Those events also change
the color and opacity of components of the SVG. Some tasks you might want to consider
for your projects might include:
display
property.
For an example, click on a project title at http://www.obdurodon.org.The Tygeron the
experienceside, that side scrolls, and the
innocenceside also scrolls in sync to its
mirror poem,
The Lamb.
legendarea to highlight words associated with those concepts.