One reason JavaScript is so popular is that it’s relatively easy to add JavaScript to
a web page. All you need to do, at a minimum, is to include HTML script
tags in the page, provide the JavaScript language for the type
attribute, and add whatever JavaScript
you want:
<script type="text/javascript"> ...some JavaScript </script>
Traditionally, script tags are added to the head
element in the document (delimited by
opening and closing head
tags), but
they can also be included in the body
element—or even in both sections.
Example
1-1 shows a complete, valid web page, including a JavaScript
block that uses the built-in alert
function to open a message box containing the “Hello, World!”
text.
Example 1-1. JavaScript block in the document head
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <title>Example 1-1</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript"> var dt = Date( ); // say hello to the world var msg = 'Hello, World! Today is ' + dt; alert(msg); </script> </head> <body> </body> </html>
Copying this into a file and opening the file in any web browser should result in a box popping up as soon as the page as loaded. If it doesn’t, chances are that JavaScript is disabled in the browser, or, something very rare these days, that JavaScript isn’t supported.
Though the example is simple, it does expose the basic components of most JavaScript applications in use today. It deserves a closer look.
Tip
The examples in this book were all designed to validate as XHTML, which means that they include DOCTYPE, document title, and content type. You can discard these when recreating the examples. However, a better approach might be to create a skeleton web page including the DOCTYPE, title, content type, head, and body, and then copy it for most of the examples.
JavaScript, unlike some other languages, is almost always embedded within the context of another language, such as HTML and XHTML (both of which are actual languages, though the moving parts may not be as obvious). By this I mean that there are restrictions in how the script is added to the page. You can’t just plop JS into the page wherever and however you want.
Tip
Even when used in other, non-Web, contexts, JavaScript is frequently part of a document or template.
In Example
1-1, the (X)HTML script
element tag encloses the JavaScript. This lets the browser know that
when it encounters this tag, it shouldn’t process the tag’s contents
as HTML or XHTML. At this point, control over the contents is turned
over to another built-in browser agent, the scripting engine.
Not all script embedded in web pages is JavaScript, and the tag
contains an attribute defining the type of script. In the example,
this is given as a text
/javascript
. Other allowable values for the
type
attribute are:
text
/ecmascript
text
/jscript
text
/vbscript
text
/vbs
The first is an alternative for JavaScript, the next a variation of JavaScript implemented by Microsoft in Internet Explorer, and the next two are for VBScript.
All these type
values
describe the MIME type of the content. MIME, or
Multipurpose Internet Mail Extension, is a way to identify how the
content is encoded (i.e., text
),
and what specific format it is (javascript
). The concept arose with email,
but spread to other Internet uses, such as designating the type of
script in a script block.
By providing a MIME type, those browsers capable of processing the type do so, while other browsers skip over the section. This ensures that the script is accessed only by applications that can process it.
Earlier versions of the script
tag took a language
attribute, and this was used to
designate the version of the language, as well as the type: javascript
as compared to javascript
1.2
. However, the use of language
was deprecated in HTML 4.01, though
it still shows in many JavaScript examples. And therein lies one of
the earliest cross-browser techniques.
Years ago, when working with cross-browser compatibility issues, it wasn’t uncommon to create a specific script for each browser in a separate section or file and then use the language attribute to ensure only a compatible browser could access the code. Looking through some of my old DHTML examples (circa 1997), I found the following:
<script src="ns4_obj.js" language="javascript1.2"> </script> <script src="ie4_obj.js" language="jscript"> </script>
The philosophy of this approach was that only a browser capable of processing JavaScript 1.2 would pick up the one block (Netscape Navigator 4.x, primarily, at that time) and only a browser capable of processing JScript would pick up that file (Internet Explorer 4). Kludgey? Sure, but it also worked through the early years of trying to deal with frequently broken cross-browser DHTML.
Eventually, though, the preference shifted to an approach called object
detection
—a move only encouraged when the language
attribute was deprecated. We’ll look at object detection more closely
in the later chapters, particularly those associated with Ajax. For
now, object detection involves testing to see if a particular object
or property of an object exists, and if so, one batch of JavaScript is
processed; otherwise, a different batch is run.
Returning to the script
tag,
other valid attributes for this tag are src
, defer
, and charset
. The charset
attribute defines the character
encoding used with the script. Unless you need a different character
encoding than what’s defined for the document, this usually isn’t
set.
One attribute that can be quite useful is defer
. If you set defer
to a value of “defer,” it indicates to
the browser that the script is not going to generate any document
content, and the browser can continue processing the rest of the
page’s content, returning to the script when the page has been
processed and displayed:
<script type="text/javascript" defer="defer"> ...no content being generated </script>
Using this can help speed up page loading when you have a larger
JavaScript block or include a larger JS library. The last attribute,
src
, has to do with loading such
libraries, and we’ll explore it next.
In Example
1-1, the JavaScript block is embedded in the head
element of the web page. The script can also be included in the body,
as a modification of the application demonstrates in Example 1-2.
Example 1-2. Embedding JavaScript into the document body
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <title>JavaScript Code Block Example</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <script type="text/javascript"> //<![CDATA[ var dt = Date( ); var msg ='<h3>Hello, World! Today is ' + dt + '</h3>'; document.writeln(msg); //]]> </script> </body> </html>
Note in this example, rather than the alert
function, the DOM document
object is used to write directly to
the page.
There are differing viewpoints on when JS should be included in the head and when in the body, but the following rules apply:
Place the JavaScript in the body when the JavaScript dynamically creates web page content as the page is being loaded.
JavaScript defined in functions and used for
page
events should be placed in thehead
tag, as this is loaded before the body.
A good rule of thumb with script placement is to embed the
script in the body only when the script creates web page contents as
it’s loaded; otherwise, put it in the head
element. This way, the page won’t be
cluttered with script, and the script can always be found in one
location on each page.
Tip
Inserting JavaScript into the body can be avoided altogether by using the DOM to generate new content and attach it to page elements. I’ll be introducing this approach later in the book.
In Example 1-2, the script block was included within a XHTML CDATA section. A CDATA section holds text that the XHTML processor doesn’t interpret.
The reason for the CDATA section is that XHTML processors interpret markup such as the header (H3) opening and closing tags, even when they’re contained within JavaScript strings. Though the page may display correctly, if you try to validate it without the CDATA, you will get validation errors.
JavaScript that is imported into the page using the SRC attribute is assumed to be compatible with XHTML and doesn’t require the CDATA section. Inline or embedded JS, though, should be delimited with CDATA, particularly if it’s included within the BODY element.
For most browsers, you’ll also need to hide the CDATA section opening and closing tags with JavaScript comments (//), or you’ll get a JavaScript error.
Tip
JavaScript Best Practice: The use of both the CDATA section and the JavaScript comments is important enough that these form the first of many JavaScript Best Practices that will be covered in this book.
When using an XHTML DOCTYPE, enclose inline or embedded JavaScript blocks in CDATA sections, which are then commented out using JavaScript comments. And always assume your web pages are XHTML, so always use CDATA.
Of course, the best way to keep your web pages uncluttered is to remove the JavaScript from the page entirely, through the use of JavaScript files. Many of this book’s examples are embedded into the page primarily to make them easier to create. However, the Mozilla Foundation recommends that all inline or embedded JavaScript be removed from a page and placed in separate JS files. Doing this prevents problems with validation and incorrect interpretation of text, regardless of whether the page is processed as HTML or XHTML.
Tip
JavaScript Best Practice: Place all blocks of JavaScript code within external JavaScript files.
As JavaScript became more object-oriented and complex, developers began to create reusable JS objects that could be incorporated into many applications created by different developers. The only efficient way to reuse these objects was to create them in separate files and provide a link to each file in the web page.
JavaScript files are beneficial for reasons other than facilitating reuse. For example, rather than repeat the same code over many pages and have to update it in many places when it changes, the code is created in a file, and any modifications are then made to only one place. Nowadays, all but the most simple JavaScript is created in separate script files. Whatever overhead is incurred by using multiple files is more than offset by the benefits.
To include a JavaScript library or script file in your web page, use this syntax:
<script type="text/javascript" src="somejavascript.js"></script>
The script
element contains
no content, but the closing tag is still required.
Script files are loaded into the page by the browser in the
order in which they occur in the page and are processed in order
unless defer
is used. A script file
should be treated as if the code is actually included in the page; the
behavior is no different between script files and embedded JavaScript
blocks.
The entire second half of the book covers creating and using custom libraries, but Chapter 11 covers many of the basics.
A line that begins with the double-slash (//) is a JavaScript comment, usually an explanation of the surrounding code. Comments in JavaScript are an extremely useful way of quickly noting what a block of code is doing, and whatever dependencies it has. It makes the code more readable and more maintainable.
There are two different types of comments you can use in your own applications. The first, using the double-slash, just comments out a specific line:
// This line is commented out in the code
The second makes use of opening and closing JavaScript comment delimiters, (/*) and (*/), to mark a block of comments that can extend one or more lines:
/* This is a multiline comment that extends through three lines. Multiline comments are particularly useful commenting on a function */
Single-line comments are relatively safe to use, but multiline comments can generate problems if the beginning or ending bracket characters are accidentally deleted.
Typically, single-line comments are used before a block of JS performing a specific process or creating a specific object; multiline comment blocks are used in the beginning of a JavaScript file.
Tip
JavaScript Best Practice: Begin every JavaScript block, function, or object definition with at least one line of comments. In addition, provide a more detailed comment block at the beginning of all JavaScript library files; include information about author, date, and dependencies, as well as a detailed purpose of the script.
Examples 1-1 and 1-2, small as they were, used a powerful set of global, built-in browser objects to communicate with the user.
The first example used the alert
function to create a small pop-up
window (usually called a dialog
window) with the provided message. Though not specifically included in
the text, the alert
dialog is a
function of the window
object—the
top-most object in the Browser Object Model (BOM). The BOM is a basic
set of objects implemented in most modern browsers.
The second example also used an object from the BOM—the document
object—to write the message out to
the page. The document
, window
, and all BOM objects are covered in
Chapter
9.
Tip
The BOM is a variation of the DOM mentioned earlier, and it is sometimes referred to as DOM Version 0.
Examples 1-1 and 1-2 also use
two other built-in objects, though only one is used
explicitly. The explicit object is date
; it accesses today’s date. The second,
implicit, object is string
, which
is the type of object that’s returned when the date
function is called. In fact, the
following are all comparable implementations of the same code:
var dt = String(Date( )); var dt = Date( ).toString( );
The JavaScript built-in objects string
and date
are covered in more detail in Chapter 4.
The global function and built-in object are used within the context of a user-defined function (UDF) in Example 1-1. The typical syntax for creating a UDF is:
function functionname
(params
) { ... }
The keyword function
is
followed by the function name and parentheses containing zero or more
parameters (function arguments), followed by the function code
contained within curly brackets. The function may or may not return a
value. A user-defined function encapsulates a block of JavaScript for
later or repeated processing.
Functions are technically another kind of a built-in JavaScript object. They look like statements, and you don’t need to worry much about the distinction until you’re building lots of them. However, they are objects, and they are complex enough and important enough to have their own chapter, Chapter 5.
In the opening body tag of Example 1-1, an
attribute named onload
is assigned
the hello
function. The onload
attribute is what’s known as an
event handler
. This event
handler, and others, are part of the underlying DOM that each browser
provides. They can attach a function to an event so that when the
event occurs, some code is processed.
There are several events that can be captured in various types of elements, each of which can then be assigned code to be implemented when the event occurs.
Adding an event handler directly to the element tag is one way to attach an event handler. A second technique occurs directly within JavaScript using a syntax such as the following:
<script type="text/javascript"> document.onload=hello( ); function hello( ) { var dt = Date( ); var msg = 'Hello, World! Today is ' + dt; alert(msg); } </script>
Using this approach, you don’t have to add event handlers as attributes into tags, but instead can add them into the JS itself. We’ll get into more details on event handlers in Chapter 6. Though not demonstrated, events are frequently used in conjunction with HTML forms to validate the form data before submittal. Forms are covered in Chapter 7.
Tip
Mozilla has provided a good documentation set covering the Gecko engine (the underlying engine that implements JavaScript within browsers such as Camino and Firefox). The URL for the event handlers is http://www.mozilla.org/docs/dom/domref/dom_event_ref.html.
We’ve looked at the built-in objects and functions, the user-defined function, and event handlers. Now it’s time to take a brief look at the individual lines of JavaScript code.
Examples 1-1 and 1-2 use the
var
keyword to declare the
variables dt
and msg
. By using var
with variables, each is then defined
within a local scope, which means they’re only accessible within the
function in which they’re defined. If I didn’t use var
, the variables would have global scope,
which means the variable would then be accessible by all JavaScript
anywhere in the web page (or within any external JS libraries included
in the page).
Setting the scope of a variable is important if you have both global and local variables with the same name. Example 1-1 doesn’t have global variables of any name, but it’s important to develop good JavaScript coding practices from the beginning. One such practice is to explicitly define the variable’s scope.
Here are the rules regarding scope:
If a variable is declared with the
var
keyword in a function, its use is local to that function.If a variable is declared without the
var
keyword in a function, and a global variable of the same name exists, it’s assumed to be that global variable.If a variable is declared locally with a
var
keyword but not initialized (i.e., assigned a value), it is accessible but not defined.If a variable is declared locally without the
var
keyword, or explicitly declared globally, but not initialized, it is accessible globally but not defined.
By using var
within a
function, you can prevent problems when using global and local
variables of the same name. This is especially critical when using
external JavaScript libraries. (See Chapter 2 for more
details on JS variables and simple data types.)
There are several operators in JavaScript: those for arithmetic (+,–),
those for conditional expressions (<, >), and others detailed
more fully later in the book. Example 1-2
introduces your first operator: the dot (.), which is also known as
the property
operator.
In the following line from Example 1-2, the
property
operator accesses a
specific property of the document object:
document.writeln(msg);
Data elements, event handlers, and object methods are all
considered properties of objects within JavaScript, and all are
accessed via the property
operator.
The examples demonstrated a basic type of JavaScript statement: the assignment. There are several different types of JS statements that assign values, print out messages, look through data until a condition is met, and so on. The last component of our quick first look at JavaScript is the concept of a JS statement, including its terminator: the semicolon (;).
The statement lines in Example 1-1 end with a semicolon. This isn’t an absolute requirement in JavaScript unless you want to type many statements on the same line. If you do, you’ll have to insert a semicolon to separate the individual statements.
When typing a complete statement on one line without a
semicolon, a line break terminates the statement. However, just as
with the use of var
, it’s a good
practice that helps avoid some kinds of mistakes. I use the semicolon
for all of my JS development.
The use of the semicolon, other operators, and statements are covered in Chapter 3.
Ten years ago when most browsers were in their first or second
version, JavaScript support was sketchy, with each browser
implementing a different version. When browsers, such as the
text-based Lynx, encountered the script
tag, they usually just printed the
output to the page.
To prevent this, the script contents were enclosed in HTML
comments: <
!--
and -->
. When HTML comments were used,
non-JS enabled browsers ignored the commented-out script, but newer
browsers knew to execute the script.
It was a kludge, but it was a very widespread kludge. Most web pages with JavaScript nowadays feature the added HTML comments because the script is copied more often than not. Unfortunately, today, some new browsers may process XHTML as strictly XML, which means the commented code is discarded. In these situations, the JavaScript is ignored. As a consequence, HTML comments have fallen out of favor and aren’t used in any examples in this book.
Tip
JavaScript Best Practice: Do not use HTML commenting to “hide” JavaScript. Browsers that don’t understand JS are long gone, and their use conflicts with pages created as XHTML.
Get Learning JavaScript now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.