Chapter 1. Implement and manipulate document structures and objects

Web developers today need to understand the complexities of the constructs involved in building interactive and dynamic applications with HTML and JavaScript. The introduction of HTML5 brought a new standard for defining the structure of your webpages as well as changes in how you interact with them via script.

This chapter demonstrates how to create HTML5 documents with the new HTML5 semantic markup. You’ll explore the process of creating the code required to manipulate and interact with HTML5 markup and applying styles to HTML5 elements.


Important: Have you read page xi?

It contains valuable information regarding the skills you need to pass the exam.



Note: Elements Vs. Tags

HTML markup is referred to as both HTML tags and HTML elements. These terms are often used interchangeably. This book refers to the HTML markup as elements.


Objectives in this chapter:

Image Objective 1.1: Create the document structure

Image Objective 1.2: Write code that interacts with UI controls

Image Objective 1.3: Apply styling to HTML elements programmatically

Image Objective 1.4: Implement HTML5 APIs

Image Objective 1.5: Establish the scope of objects and variables

Image Objective 1.6: Create and implement objects and methods

Objective 1.1: Create the document structure

Writing an HTML page can be very easy or very daunting, depending on your objectives. Any HTML page renders in a browser even if it contains only plain text. But this type of web application might not be effective at delivering your intended message or at providing interactivity to keep users coming back to the site for more. This is where HTML markup comes in handy.

HTML enables you to apply a fluid and organized structure to webpages. Paired with a powerful tool such as JavaScript, HTML5 lets you deliver highly interactive content that can pique your users’ interest. This objective focuses on the semantic elements available to you in HTML5, which, along with JavaScript, allow you to create the rich end-user experience that modern web users want and have come to expect.

The purpose of a document’s structure is to tell the browser how the content should be displayed. Without any declarative structure in your page, the browser won’t detect any structure, so it will lay out your content according to the rules implemented by its rendering engine. When using the HTML5 markup presented in this objective, you are telling the browser to take your semantics into account when displaying the page. Going forward, new releases of browsers will incorporate more and more of the HTML5 standards into their rendering engines.

The exam will test your ability to use HTML5 semantic markup to create webpages and your ability to optimize webpages for use on screen readers. The exam will also cover the effect that the HTML5 semantic markup will have on search engine optimization.

Using HTML5 semantic markup

Table 1-1 lists the HTML5 semantic elements as defined by the specification. These elements make up the core of HTML5. As such, understanding the definition and proper usage of each element is critical to successful completion of the exam. In the following sections, you will use each of these semantic markup elements to create a complete document structure.

Image

TABLE 1-1 HTML5 semantic markup


Note: Use Only What you Need

When designing a webpage, you don’t necessarily need to use every available element. Instead, use only the elements you need to get your job done.


Understanding the core structure of an HTML5 page

Although a browser can render any plain text file, to provide any structure to the document the page must contain the basic elements that you are about to learn. Although this book assumes you have a basic understanding of how webpages are structured, the following HTML code demonstrates the basic template of an HTML5 page:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title></title>
</head>
<body>
<!-- page content goes here -->
</body>
</html>

This section elaborates on this basic structure as semantic markup is introduced throughout the objective. All content to be introduced to the page will go within the <body> element because that page section displays content in the browser. As it is now, this code would render nothing more than a blank page. To see some content as you work through the following sections for each semantic element, use the code in Listing 1-1.

LISTING 1-1 HTML5 semantic elements

<body>
    <header>
       <h1>Some fictional company Website</h1>
       <nav>
           <a href="Home.html">Document Structure</a>
           <a href="Blog.html">Writing Code</a>
           <a href="About.html">Styles</a>
       </nav>
    </header>
    <article>
        <header>
            <hgroup>
                <h1>Our first new Article</h1>
            </hgroup>
        </header>
        <section>
            <h1>Section 1</h1>
            <p>Some details about section 1</p>
            <aside>Did you know that 7/10 is 70%</aside>
        </section>
        <section>
            <h1>Section 2</h1>
        </section>
    </article>
    <article>
        <header>
            <hgroup>
                <h1>Second huge article</h1>
            </hgroup>
        </header>
        <p>Provide some useful information in the article</p>
    </article>
    <article>
        <header>
            <hgroup>
                <h1>Third huge article</h1>
            </hgroup>
        </header>
        <p>Provide some useful information in the third article</p>
        <figure>
            <img src="orange.jpg"  style="width:50px; height:50px;"/>
            <figcaption>Fig 1: A really juicy orange.</figcaption>
        </figure>
    </article>
</body>

Using the <header> and <footer> elements

Most webpage documents contain common content at the top and bottom of all pages. Although using the <header> and <footer> elements doesn’t automatically provide this functionality, the elements do provide the ability to define the content in the header and footer of the website.

Typically, a webpage header contains content such as a company logo or banner. In some cases, it might also contain a navigation menu. (See the upcoming “Using the <nav> element” section for this.) Start the example page by adding the <header> element to your page:

<body>
    <header>
       <h1>Some fictional company Website</h1>
...
    </header>
</body>

This HTML code produces the output shown in Figure 1-1:

Image

FIGURE 1-1 A <header> element, which causes the browser to format the text within the element as a heading.

The <header> element isn’t limited to only the start of your page—it provides a semantic way of declaring the header to any area of the webpage. You can use the <header> element as a header to a <section> element or to an <article> element. The <header> element is intended to hold an H1–H6 element as needed; however, you can populate a header with any markup that suits your needs to create the best header for that particular area of the site.

This HTML code produces the output shown in Figure 1-2:

<body>
...
  <header>
       <h1>Some fictional company Website</h1>
  </header>
  <article>
     <header>
           <h1>Our first new Article</h1>
     </header>
...
</body>

Image

FIGURE 1-2 The <header> element with a nested <h1> element

Using the <nav> element

Using the <nav> element in an HTML5 document provides users with navigation through the main elements of the web document or web application as a whole. These main navigation elements could be represented as a list of links across the top of the page to navigate the current website. It could also list your favorite websites along the side of the page, such as in a blog where you list other favorite blogs that you follow.

Typically, the list of links across the top, commonly known as the main menu of the web application, is contained in the header (but doesn’t have to be). A list of favorite URLs would most likely be placed into an <aside> so that the list could be placed off to the side, away from the main content but readily accessible. For the current example, you create a main menu across the top of the page. This HTML code produces the output in Figure 1-3:

<body>
   <header>
     <h1>Some fictional company Website</h1>
     <nav>
        <a href="Home.html">Document Structure</a>
        <a href="Blog.html">Writing Code</a>
        <a href="About.html">Styles</a>
     </nav>
   </header>
...
</body>

Image

FIGURE 1-3 A navigation menu created using the <nav> element

The other main element commonly used under the <header> element is the rightfully named <hgroup>.

Using the <hgroup> element

The <hgroup> element is a semantic method that organizes headers and subheaders. This element typically contains the standard and familiar <h1> to <h6> elements. The <hgroup> element groups related headers in sequence. You can add a new <hgroup> element to your webpage to serve this purpose, like so:

<body>
    ...
    <article>
        <header>
            <hgroup>
                <h1>Our first new Article</h1>
            </hgroup>
        </header>
        <p>Provide some useful information in the article</p>
    </article>
</body>

This HTML code renders the output in Figure 1-4.

Image

FIGURE 1-4 Using the <hgroup> element to group headers

This code example effectively tells the renderer that the article has a main heading (<h1>). You could go on, adding <h2> to <h6> elements if required. How many of these (<h1> to <h6>) elements you use in your <hgroup> element obviously depends on the document structure you want to present.

Now that the page is starting to take shape, you can learn about the two main content elements: <article> and <section>.

Using the <article> element

An <article> element represents a whole and complete composition or entry. Examples of an <article> element could be a magazine article or a blog post, where the content can be redistributed independently and not lose its meaning. Each article is wholly contained within itself. You can have an article with subarticles; however, each subarticle must be a direct extension and related to the root article.

Now that you know about this new <article> element, you can go back to your sample document and organize it with articles:

<body>
...
    <article>
        <header>
            <hgroup>
                <h1>Our first new Article</h1>
            </hgroup>
        </header>
        <section>
            <h1>Section 1</h1>
            <p>Some details about section 1</p>
            <aside>Did you know that 7/10 is 70%</aside>
        </section>
        <section>
            <h1>Section 2</h1>
        </section>
    </article>
    <article>
        <header>
            <hgroup>
                <h1>Second huge article</h1>
            </hgroup>
        </header>
        <p>Provide some useful information in the article</p>
    </article>
    <article>
        <header>
            <hgroup>
                <h1>Third huge article</h1>
            </hgroup>
        </header>
        <p>Provide some useful information in the third article</p>
    </article>
</body>

This HTML code produces the output in Figure 1-5.

Image

FIGURE 1-5 Using the <article> element to segment different articles on the page

You have expanded the document to include three articles. Clearly, you don’t want to put the entire chapter into the sample HTML document, but you’ll add enough to be able to demonstrate the function of each semantic element. Each article added to the document in this example represents an independent part of the document that can be wholly contained. Typically, the first element within the <article> element is a header element or header group. Closely related to the <article> element is the <section> element, which you explore next.

Using the <section> element

The <section> element subdivides pages into sections. You could continue to break down the sample page with additional <article> elements; however, the purpose of the <article> element isn’t to break down a page into more granular details. This is where the <section> element becomes useful. Each <article> element contains zero or more <section> elements to denote the different content sections within the <article> element. Like an <article> element, the first element within a <section> element is typically a header or a header group.

Now you can expand the sample page with <section> elements to produce the output shown in Figure 1-6:

<body>
...
    <article>
        <header>
            <hgroup>
                <h1>Our first new Article</h1>
            </hgroup>
        </header>
        <section>
            <h1>Section 1</h1>
            <p>Some details about section 1</p>
        </section>
        <section>
            <h1>Section 2</h1>
        </section>
    </article>
    ...
</body>

Image

FIGURE 1-6 Using the <section> element within an <article> element

When you view this page in the browser now, you might notice something quite interesting. The <h1> elements inside the <hgroup> elements are rendering differently from the previous <h1> elements in the same article. Considering that you haven’t applied any styles to this page yet, you might expect that all <h1> elements would render in the same style (for example, the same font size) as the <h1> element in the <article> element. However, when you render the page in the browser, you can see that this isn’t the case. This is because of the way the document parser in the browser works through the document to determine the implied hierarchy of the headings, also called the document outline. You see more of this when you learn about screen readers later in this lesson. For now, focus on the <aside> element.

Using the <aside> element

The <aside> element defines any content that doesn’t fall within the main flow or main content of the current page—for example, a sidebar, a note, an alert, or an advertisement. The <aside> element doesn’t place itself automatically to any particular side of the webpage; it merely serves as a way to semantically define a section of text or graphics as an aside. Later you will see how to position an aside using styles. For now, add the following <aside> element to your page for later use:

<body>
     ...
    <article>
        <header>
            <hgroup>
                <h1>Our first new Article</h1>
            </hgroup>
        </header>
        <section>
            <h1>Section 1</h1>
            <p>Some details about section 1</p>
            <aside>Did you know that 7/10 is 70%</aside>
        </section>
        <section>
            <h1>Section 2</h1>
        </section>
    </article>
...
</body>

This HTML code produces the output in Figure 1-7:

Image

FIGURE 1-7 Using an <aside> element within an <article> element

As you can see in the browser output, the <aside> element isn’t treated as special in any way compared to the other elements used to structure your page. However, a little later you can see how much more easily you can style the content by using semantic markup, such as the <aside> element.

Using the <figcaption> and <figure> elements

The <figcaption> and <figure> elements, new in HTML5, provide the semantic elements necessary for adding graphics and figures to webpages. These graphics and figures typically provide a visual representation of information in the textual content and referenced by the text. You often see such images in tutorials or textbooks in which the author directs the reader to a specific figure. As an example, I’ve added some HTML to the end of the previous example:

<body>
...
    <article>
        ...
        <figure>
              <img src="orange.jpg"  style="width:50px; height:50px;"/>
              <figcaption>Fig 1: A really juicy orange.</figcaption>
        </figure>
    </article>
</body>

This HTML code produces the output in Figure 1-8.

Image

FIGURE 1-8 Using the <figure> element to add a graphic or figure to the page

You need to replace the example image with one you already have to get the page to render correctly. However, the essence of what you achieve with the <figcaption> and <figure> elements should be clear.

Using the <progress> element

The <progress> element represents the progress of an objective or task. The two supported types of progress tasks are determinate and indeterminate.

Use a determinate progress task when you know in advance the amount of work to be completed; in other words, you know the starting and ending values. Sample scenarios for this case include downloading a file for which you know the exact size or displaying the progress of a fundraising effort. In both situations, you know the exact status of the task at any particular time, and you also know what the end goal is—either the number of bytes for the file download or the number of dollars for the fundraiser. In these determinate cases, you can specify HTML5 markup such as this:

    <p>Our goal is to have 1000 users:</p>
    <span>0</span>
    <progress value="50" max="1000"></progress>
    <span>1000</span>

The result of this HTML is the progress bar shown in Figure 1-9.

Image

FIGURE 1-9 Using the <progress> element to show progress toward a total

As shown in the preceding code, the <progress> element has two attributes you need to know: value and max. The value attribute lets you specify the current value or position of the <progress> element at a specific point in time. The max attribute tells the browser what the maximum possible value is for the element. The browser uses these two values to determine how much of the element should be colored in. Usually, the value attribute updates dynamically using JavaScript. In Figure 1-10, you can see how the <progress> element’s display changes when the value attribute is updated to 750.

Image

FIGURE 1-10 The effect of the value attribute on the <progress> element

You use indeterminate tasks when you don’t know how long a task will take to complete but still want to show users that some work is occurring and that they should wait. You still use the <progress> element but remove the value attribute. When you don’t specify the value attribute, the browser can infer that the <progress> element represents an indeterminate task. This might be useful for data received from a service where you have no control over or knowledge of how quickly the request will complete or how large the request results will be. The following HTML5 markup demonstrates an indeterminate task:

<p>Data download is in progress, please wait patiently:</p>
<progress max="5"></progress>

This code produces a progress display like the one shown in Figure 1-11:

Image

FIGURE 1-11 Showing indeterminate progress by using moving dots to demonstrate that work is occurring

In Figure 1-11, the blue dots replace the progress bar from the previous determinate example. This visual change to the progress indicator occurred by simply removing the value attribute from the <progress> element. In actuality, the dots are animated, as you would see if you run the code in a browser.

<mark> element

With the <mark> element, you can easily highlight important information or any text you want to emphasize. It has essentially the same function as a highlighter. By wrapping text in a <mark> element and providing a background-color attribute to its style element, you can get the desired highlight effect. The following HTML code demonstrates the <mark> element:

<p>Some very <mark style="background-color:red;">important</mark> information provided
here!</p>

Figure 1-12 shows the output of this HTML. The word “important” is highlighted as a result of the <mark> element being placed around it.

Image

FIGURE 1-12 The effect on text placed inside the <mark> element

Using the <div> element

The new HTML5 semantic elements don’t (with the exception of the <progress> element) necessarily provide any default or altered behavior. Instead, they provide a stronger semantic definition to your webpages. This, in turn, gives you a more reliable and maintainable way to structure your pages and style them consistently. The goal of these elements is to replace the older method of structuring pages—prior to HTML5—by using <div> elements and naming them according to their function. However, note that the <div> element is still part of HTML5 and still plays an important role. Use the new semantic elements as appropriate, but remember that the <div> element is still quite useful for styling content.

This section explored the new semantic elements in HTML5. In the next section, you learn how to create and work with layout containers.

Creating a layout container in HTML

You can lay out a webpage in various ways. An important aim here is to urge you to give serious thought to layout so that your page presentation is user friendly. If users can’t find what they are looking for because the entire page is styled as a single <p> element inside the <body> element, they aren’t likely to keep coming back. In this section, you look at a couple of layout options available in HTML. Chapter 4, “Use CSS in applications,” explains how to use cascading style sheets (CSS) to implement your layouts.

The two most common methods of creating a layout in HTML involve using <div> and <table> elements. In either case, more than likely you will still use CSS to help with positioning and sizing. Chapter 4 goes into more detail about CSS; this section looks specifically at the layout, using only HTML.

Still the catchall container elements, the familiar <div>s are often used to divide the page into various sections to create the layout. For example, you might see this sort of HTML used to achieve layout:

<div id="PageHeader"></div>
<div id="LeftSide"></div>
<div id="RightSide"></div>
<div id="Footer"></div>

The rendering engine displays each <div> according to its rules. To position the divisions dynamically would require CSS.

The main issue with using <div> elements to structure the document is their inability to impart standard semantic meaning to each section. You’ll revisit these examples later, when you explore creating layouts in CSS.

The <div> element allows for more dynamic capability in page layout. For a more static layout declared right in the HTML page, the <table> element is more appropriate. The following HTML defines a table that provides a common blog-site format, with a header section, a left sidebar, a content area, a right sidebar, and a footer area:

<table>
     <tr>
        <td colspan="3" id="Header"></td>
     </tr>
     <tr>
        <td rowspan="3" id="LeftBar"></td>
        <td rowspan="3" id="MainContent"></td>
        <td id="RightSideTop"></td>
     </tr>
     <tr>
        <td id="RightSideMiddle"></td>
     </tr>
     <tr>
        <td id="RightSideBottom"></td>
     </tr>
     <tr>
        <td colspan="3" id="Footer"></td>
     </tr>
</table>

The <table> element is very flexible. Additional elements such as <thead> and <tfoot> provide a more semantic approach to labeling the table cells. The concern with using the <table> element approach is the static nature of the structure. To change the overall structure of a site that uses tables for layout, you need to go to every page and make the changes. It’s worth noting that some methods that make such changes easier have evolved over the years in response to the maintenance headache involved.

Optimizing for search engines

When a website is required to create an online presence, you have to ensure that it can be found among the millions of sites that already exist. Search engine optimization (SEO) is a technique used to make elements of the website easily discoverable and appropriately indexed by search engines, so that when users search for content related to your site, they find your pages. Search engines such as Bing and Google constantly scour the Internet for content. When they find webpages, they go through the HTML and index content such as page and image metadata. They use the indexed data to allow users to search for essentially anything on the Internet and receive relevant results. Clearly, then, a relationship exists between the content on your websites and how easily users can find your sites using a search engine. With the semantic HTML elements discussed in the previous objective in mind, you should note some additional things with respect to the logic search engines use to discover what’s on websites. On the whole, the subject of SEO is far outside the scope of this book and exam; entire books are written on the subject. However, discussing how HTML5 impacts SEO and website design is relevant.

In the past (defined as pre-HTML5), web designers often used <div> elements to segment the page. These elements don’t provide very much context as to what they are intended to contain. But with the semantic markup available in HTML5, you can use more descriptive elements for the page sections. As you saw in the blog-page layout example, the HTML elements alone make clear the intent of each segment of the page. As search engines scour webpages, they detect the markup and know what to take from it to properly index the page.

The <article> and <section> elements are the main ones used by the SEO algorithm. These elements are known to contain the main body of the page. That a page have more than one <article> and/or <section> element is acceptable; they all get indexed. Within each <article> element, the engine then seeks out elements such as <hgroup> or <h1> to get the main topic of the <article> element for relevant indexing. However, this doesn’t mean that if a site doesn’t have <article> or <section> elements, it won’t get indexed and be searchable. This speaks only to the quality of indexing the search engines can conduct to make your site more searchable by end users.

SEO is a great technique to understand when designing websites. Creating a website just to leave it in the dark and hard to find doesn’t serve much purpose. Being found is very important and, when the site is found, you don’t want to limit your audience. Accessibility is also very important.

Next, look at how HTML5 affects the use of screen readers.

Optimizing for screen readers

Screen readers rely on the document outline to parse the structure and present information to the user. Screen-reader programs can read the text on the page and convert it to audio through a text-to-speech algorithm. This is helpful for users who might have difficulty viewing the webpage. As discussed earlier, the way the document gets outlined in HTML5 has changed. Here’s a little more detail.

Prior to HTML5, a page was outlined using only the header elements (<h1> through <h6>). The relative position of each header element to the previous header element within the page created the hierarchy. Screen readers could use this information to present a table of contents to users. However, HTML5 introduced semantic elements to create new sections. This means that <section>, <article>, <nav>, and <aside> elements all define new sections. The introduction of the semantic elements changes how the document outline is created. For example, if the following HTML was going to be the hierarchy of the sample document, you could possibly lay it out like this:

<h1>Fruits and Vegetables</h1>
<h2>Fruit</h2>
<h3>Round Fruit</h3>
<h3>Long Fruit</h3>
<h2>Vegetables</h2>
<h3>Green</h3>
<h3>Colorful</h3>

This produces the expected outline, shown in Figure 1-13.

Image

FIGURE 1-13 The output of a series of header elements to create a document structure

The outline shows the default styles of the different header elements as expected. The heading elements create implied sections and subsections within the document. This is still valid in HTML5. However, you shouldn’t leave the page sectioning set to implied sectioning as presented by the header elements; rather, you should explicitly define the sections by using the appropriate semantics. Also recommended is that <h1> elements be used solely throughout an HTML5 document. To produce the same hierarchy in this fashion, you would need to change your HTML to be like the following:

    <section>
        <h1>Fruits and Vegetables</h1>
        <section>
            <h1>Fruit</h1>
            <section>
                <h1>Round Fruit</h1>
            </section>
            <section>
                <h1>Long Fruit</h1>
            </section>
        </section>
        <section>
            <h1>Vegetables</h1>
            <section>
                <h1>Green</h1>
            </section>
            <section>
                <h1>Colorful</h1>
            </section>
        </section>
    </section>

This HTML produces the same output as shown earlier in Figure 1-13. The difference is that now each <section> element creates a new page section rather than rely on the header elements to create the sections. Screen readers can parse the semantic elements to create the document outline and eventually can provide a much richer user experience because of how HTML5 allows webpage designers to lay out the pages.

Objective summary

Image HTML5 introduced new semantic elements to more clearly define sections of an HTML page. These elements include <section>, <article>, <nav>, <header>, <footer>, <aside>, <progress>, <mark>, <figure>, and <figcaption>.

Image Elements within an HTML page can have their layout controlled when they are included inside structures such as <div> elements and/or HTML tables.

Image HTML5 semantic elements provide the mechanisms necessary to structure the page more easily for accessibility via screen readers.

Image Search engines take advantage of HTML5 semantics by leveraging the <article> element to determine the purpose of the page.

Objective review

Answer the following questions to test your knowledge of the information in this objective. You can find the answers to these questions and explanations of why each answer choice is correct or incorrect in the “Answers” section at the end of this chapter.

1. Which of the following elements aren’t introduced in HTML5?

A. <article>

B. <footer>

C. <hgroup>

D. <input>

2. Which element(s) does the <hgroup> element contain?

A. <h1> to <h6>

B. <header>

C. <nav>

D. All of the above

3. Which HTML5 element would you use to organize content so that the page maximizes a search engine’s algorithm?

A. <div id=“CompanyNews”>

B. <header>Company News</header>

C. <article>Company News</article>

D. All of the above

4. Which HTML5 element should you use to create a more structured layout?

A. <div>

B. <p>

C. <table>

D. <form>

Objective 1.2: Write code that interacts with UI controls

In this objective, you review how to interact with webpages in the browser using code. Web browsers include a powerful environment in which you can control the behavior of webpages. And some new HTML5 elements provide improved interactivity for end users.

You also review how to modify the document object model dynamically, using JavaScript. You review how to implement video and audio in webpages and how to control them programmatically. Finally, you review how to render graphics dynamically or allow users to draw their own graphics.

Adding or modifying HTML elements

The ability to modify an HTML document at run time is very powerful. So far you’ve seen how to create your webpages, lay them out elegantly, and render them for users. In many cases, you should modify the layout of your webpages at run time depending on what your users do. This is where you can take advantage of the power of JavaScript. JavaScript provides the toolkit you need to write code that interacts with webpage elements after they are already rendered into the browser. Before you can start to modify the webpage, you need to know how to access or reference the elements so you can manipulate them.

Document Object Model

The Document Object Model (DOM) is a representation of the structure of your HTML page that you can interact with programmatically. As demonstrated earlier, an HTML page is a hierarchy. The browser produces an outline based on the HTML hierarchy presented to it and displays this in the browser to the user. Behind the scenes, unknown to the user, the browser constructs a DOM. The DOM’s application programming interface (API) is exposed as objects with properties and methods, enabling you to write JavaScript code to interact with the HTML elements rendered to the page.

This notion is very powerful. You can add new elements to the page that didn’t even exist in your original HTML page. You can modify elements to change their behavior, layout, appearance, and content. Theoretically, although this is rarely a recommended practice, you could render a blank HTML page to the browser, build the entire page using JavaScript, and produce the exact same results. Having that power over your webpages is very exciting, even after they are rendered. You start by selecting items in the DOM to get a reference to them.

Selecting items in the DOM

To manipulate the DOM, you need to know how to access it and to obtain references to the elements you want to manipulate. In the next section you look at altering the DOM, but first you need to get elements from the DOM so you can work with them.


Note: The Document Object Model as a Family Tree

The DOM is essentially a collection of nodes arranged in a tree. All the nodes are related to each other. They are one big happy family of children, siblings, parents, grandparents, grandchildren, and so on. This essence of a family tree represents the hierarchy of the DOM and is important to understand as you manipulate the DOM through code.


You have a few choices when it comes to using JavaScript to access the DOM. You can access DOM elements through a global object provided by the browser, called document, or through the elements themselves after you obtain a reference to one. Table 1-2 outlines the core native methods used for selecting elements in the DOM.

Image

TABLE 1-2 Methods available for selecting DOM elements

For the most part, the methods are straightforward to use. In this section, you begin with a simple HTML document structure that you will use in many other examples in this book to highlight various concepts. Create a webpage with the HTML markup in Listing 1-2 to proceed with the following examples.

LISTING 1-2 HTML source to work with the DOM

<body>
    <div id="outerDiv">
        <p class='mainPara'>Main Paragraph</p>
        <ul>
            <li>First List Item</li>
            <li>Second List Item</li>
            <li>Third List Item</li>
            <li>Fourth List Item</li>
        </ul>
        <div id="innerDiv">
           <p class='subPara' id='P1'>Paragraph 1</p>
           <p class='subPara' id='P2'>Paragraph 2</p>
           <p class='subPara' id='P3'>Paragraph 3</p>
           <p class='subPara' id='P4'>Paragraph 4</p>
        </div>
        <table>
            <tr>
                <td>Row 1
                </td>
            </tr>
            <tr>
                <td>Row 2
                </td>
            </tr>
            <tr>
                <td>Row 3
                </td>
            </tr>
            <tr>
                <td>Row 4
                </td>
            </tr>
            <tr>
                <td>Row 5
                </td>
            </tr>
        </table>
        <input type="text"/><input type="submit" value="Submit"/>
    </div>
</body>

This sample page is very simple, but it serves the purpose of demonstrating various ways to access elements through code. To demonstrate this functionality, you need an entry point. Add the following script block to the head section of the webpage:

    <script>
        window.onload = function () {
            ...
        }
    </script>

This should look familiar, but if it doesn’t, you’ll review the concepts later. For now, this code essentially tells the runtime to run your code after the window finishes loading. You can use your code to experiment with the various methods listed in Table 1-2 in this function, starting with getElementById.

The getElementById method returns the element in the page that matches the specific ID value you pass to it. It returns null if no element on the page has the specified ID. Each element on the page should have a unique ID. For example, if you want to reference the <div> element with the ID outerDiv, you would use the following code:

var element = document.getElementById("outerDiv");
alert(element.innerHTML);

The JavaScript alert method, which displays a message box, is used here to show whether you have actually accessed the DOM successfully. The alert isn’t all that useful in the real world but it is for development purposes. When you run the page, notice the message box from the browser with all the innerHTML contents of the <div> you selected out of the DOM with your code (see Figure 1-14).

Image

FIGURE 1-14 A JavaScript alert demonstrating successful access to the DOM

Now that you have successfully obtained a reference to your <div>, you can do anything you want to it dynamically—just as you could have defined or applied such changes to it statically. The getElementById method is great when you know the ID of a specific element in the page that you want to work with, but in other cases you might want to do something to all the elements of a particular type—for example, all paragraph elements. In this case, the getElementsByTagName method is more appropriate. You can use the following code to get a reference to all the <p> elements:

    <script>
        window.onload = function () {
            var paragraphs = document.getElementsByTagName("p");
            alert(paragraphs.length);
        }
    </script>

In this code, the object returned from the getElementsByTagName method is a little different; it’s a special type that acts as a wrapper to all the elements that match your parameter, called a NodeList. This object isn’t especially useful by itself. In fact, it doesn’t really provide anything useful other than a length, which lets you know how many items it contains, and the ability to access each individual item. In the preceding example, the JavaScript alert displays how many items were returned in the list (paragraphs.length). You can see that the method returned all five of the <p> elements in the page, as shown in Figure 1-15.

Image

FIGURE 1-15 A message showing the number of <p> elements

In the same way that you could use the getElementsByTagName method to get all elements of the same type, you can use the getElementsByClassName method to get all elements of the same CSS class. This is useful when you have many elements with the same style but perhaps want to modify them at run time. This method also returns a NodeList. The following snippet demonstrates the usage:

<script>
   window.onload = function () {
        var paragraphs = document.getElementsByClassName("subPara");
        alert("<p> elements with class subPara: " + paragraphs.length);
    }
</script>

Figure 1-16 shows the output of this script.

Image

FIGURE 1-16 A message showing the number of <p> elements with the specified class name subPara

This example adds a little more text to the message box so that it looks different from the previous example, but the idea is the same. All <p> elements with the subPara class assigned to them were returned in a NodeList. You can see that the call returned four HTML elements. When selecting elements in the DOM by class name, the NodeList contains all elements whose class matches the specified class—not just elements of the same type. If, for example, you assigned the class subPara to one of your <div> elements and then ran the function again, the returned NodeList would contain the four <p> elements and the <div> element because they all have the same class. This is important when you intend to iterate over the elements and do something to them. In Figure 1-17, the same JavaScript code is run, but with an added subPara class attribute to a <div> element.

Image

FIGURE 1-17 The same script run with a <div> assigned the class name subPara

This message box is now actually incorrect, because the NodeList contains a single <div> element and the four <p> elements. Keep this behavior in mind concerning the getElementsByClassName method.

All the methods you have looked at so far to find elements in the DOM provide a specific implementation for a specific purpose. If you want a single element by its unique ID, you use the getElementById method; if you want to find an element or all the elements of a specific CSS class, you use the getElementsByClassName method. Now look at some examples that use the much more flexible querySelector and querySelectorAll methods.

The querySelector and querySelectorAll methods allow you to achieve most of what you’ve already done with the other methods. Both methods take a parameter in the form of a CSS selector. The querySelector method returns the first element it finds that matches the selector criteria passed to it, whereas the querySelectorAll method returns all elements that match the selector criteria passed in. The elements are still returned in the form of a NodeList object. Both methods exist not only on the document itself, but also on each element. Therefore, when you have a reference to an element, you can use these methods to search its children without having to traverse the entire document. You can see some simpler examples in this section.

To find all the <p> elements on a page, you can use this syntax:

document.querySelectorAll("p");

To find an element by its unique ID, you can use this syntax:

document.querySelector("#outerDiv");

Put those two lines into your HTML file and try them out. You will explore much more advanced and interesting functionality in Chapter 4. For now, you can use what you’ve seen about finding elements in the DOM to apply that knowledge to adding or modifying the DOM through code.


Image Exam Tip

jQuery is probably the most popular library available to date for simplifying and extending the core JavaScript capabilities. Although jQuery isn’t a Microsoft technology, it’s essentially an industry standard and fully supported by Microsoft. As such, web developers today are generally understood to have a grasp of using jQuery interchangeably with core JavaScript. The exam will expect that you can use jQuery effectively in place of the document object selector methods.


Altering the DOM

Having access to the DOM through JavaScript can be used to provide rich user experience when creating dynamic webpages. So far, all you’ve done is obtain references to the elements, which is not particularly useful by itself. The purpose of retrieving elements from the DOM is to be able to do something with them. In this section, you look at how to manipulate the DOM by using JavaScript code to add and remove items.

After you have a reference to a container element, you can add child elements to it dynamically. You can remove elements from it or simply hide elements. When you remove an element from the DOM, it is gone. So if you want to make something invisible to the user but be able to use it again later, you can simply hide it by using the appropriate CSS rather than remove it. Here’s an example:

var element = document.getElementById("innerDiv");
alert(element.innerHTML);
document.removeChild(element);
var afterRemove = document.getElementById("innerDiv");
alert(afterRemove);

The first alert properly shows the innerHTML property of the innerDiv, but the code never reaches the second alert. Instead, the getElementById method throws an error because the element id specified no longer exists in the document.

Be aware of various methods when it comes to adding elements to and removing them from the DOM.

The first method to look at is document.createElement. You use this method of the document object to create a new HTML element. The method receives a single parameter—the element name of the element you want to create. The following code creates a new <article> element to use in your page:

var element = document.createElement("article");
element.innerText = "My new <article> element";

This new <article> element isn’t visible to anyone at this point; it merely exists in the DOM for use within your page. Because you don’t have much need to create elements but then not use them, next look at the methods available to get your new <article> element into your page. The first of these methods is appendChild. You use this method to add a new HTML element to the collection of child elements belonging to the calling container. The node is added to the end of the list of children the parent node already contains. The appendChild method exists on the document object as well as on other HTML container elements. It returns a reference to the newly added node. This example appends a new <article> element to the outerDiv:

var outerDiv = document.getElementById("outerDiv");
var element = document.createElement("article");
element.innerText = "My new <article> element";
outerDiv.appendChild(element);

Like most of the other methods explained in this section, the appendChild method returns a reference to the new element appended to the child elements. This is a good way to ensure that you always have a reference to an element for future use, especially when deleting elements. It also enables you to simplify or restructure the code. The following code achieves the same result:

var element = document.getElementById("outerDiv").appendChild(document.
createElement("article"));
element.innerText = "My new <article> element";

Figure 1-18 shows the output of this code.

Image

FIGURE 1-18 A new <article> element appended to the bottom of the page

You can see that the <article> element was put in at the end of your page. The appendChild method always adds the new element to the end of the parent element’s child node list. To insert the new <article> element somewhere more precise, the insertBefore method could be more suitable. This method takes two parameters: the new element itself, and the node before which you want to append the new element. For example, to insert your new article before the innerDiv element, you could write the following code:

var element = document.getElementById("outerDiv").insertBefore(
               document.createElement("article"),
               document.getElementById("innerDiv"));
element.innerText = "My new <article> element";

This example uses the getElementById method to get a reference to the node before which you wanted to insert your <article> element in the DOM. You can use other tools to make this code simpler in some cases, depending on the document’s structure. Each element or node has the properties listed in Table 1-3 to help get references to the more common nodes when working with the DOM.

Image

TABLE 1-3 Properties available on a DOM element

For an example of these properties, you can change the preceding code to insert your <article> element as the first element in the innerDiv element:

var inner = document.getElementById("innerDiv");
var element = inner.insertBefore(document.createElement("article"),inner.firstChild);
element.innerText = "My new <article> element";

This code produces the output shown in Figure 1-19.

Image

FIGURE 1-19 The new <article> element inserted as the first child of a <div> element

Your <article> element is now positioned as the first child element of the innerDiv element. Experiment with the other properties to become familiar with how they behave. Every element that can have child elements supports all this functionality; however, if you try to insert elements into a node that doesn’t support child nodes—such as an <img>, for example—the interpreter throws a run-time error.

Just as you can add new elements to the DOM through code, you also can remove elements from the DOM using code. In this section you look at the methods available to do just this, named removeChild and removeNode.

The removeChild method removes a child node from the calling container. This method exists on the document object as well as other HTML container elements. The removeChild method returns a reference to the removed node. This is especially handy if you plan to return that node to the DOM—perhaps in response to some other user interaction with the page. Remember, however, that if you don’t keep the returned reference to the removed node, you have no way to add the element back in without completely re-creating it. The following example removes the first <p> element from your innerDiv element:

var innerDiv = document.getElementById("innerDiv");
var p = innerDiv.removeChild(document.getElementById("P1"));

This code provides the output in Figure 1-20. You can see that the first <p> element has been removed. Because you captured the removed element into the variable p, you could use it later if you wanted to put the <p> element somewhere else.

Image

FIGURE 1-20 Removal of the first <p> element by the removeChild method

Another useful method for removing nodes or elements is removeNode, which takes one Boolean parameter. Setting the parameter as true tells the method to do a deep removal, which means that all children are also removed. The following code demonstrates this:

var innerDiv = document.getElementById("innerDiv");
innerDiv.removeNode(true);

Figure 1-21 shows that when this code is run in the browser, the innerDiv element has been removed.

Image

FIGURE 1-21 Using the removeNode method to remove the <div> node

Now, suppose that you want to change the content of the page more dramatically—perhaps even by rewriting all the HTML content. This is completely possible with the techniques you have seen so far, but you haven’t tried some methods yet: replaceNode and replaceChild. These two methods operate in the same way as removeNode and removeChild in terms of the parameters they take and which elements they affect. The difference, however, is that you can replace the target element with a completely new element. The following code converts all your inner paragraphs to anchor elements and adds line breaks, because you don’t get those automatically as you do from the <p> element:

var innerDiv = document.getElementById("innerDiv");
var newDiv = document.createElement("div");
for (var i = 0; i < innerDiv.childNodes.length; i++) {
    var anchor = newDiv.appendChild(document.createElement("a"));
    anchor.setAttribute("href", "http://www.bing.ca");
    anchor.text = innerDiv.childNodes[i].textContent;
    newDiv.appendChild(document.createElement("br"));
}
innerDiv.replaceNode(newDiv);

This code produces the browser output as shown in Figure 1-22.

Image

FIGURE 1-22 Converting all the <p> elements to <a> elements

All your plain-text paragraphs now display as hyperlinks. Your original innerDiv element is gone and no longer in the DOM. Your only reference to it is within the JavaScript code. You would need to hang on to that reference if you intended to swap it back into the DOM later. Further, because the code didn’t assign the new <div> element a unique id, the only way to get a reference to it in the DOM is through your existing code reference. For this reason, a recommended practice is to always give your new elements a unique id. If the JavaScript variables go out of scope before you insert them into the document, you lose the references to your elements completely.

In this section, you saw how to access HTML elements by using JavaScript to manipulate the DOM in the browser. You now can retrieve references to the elements or nodes that make up your HTML document as well as modify, add, and remove elements in the HTML document. Next, you look at implementing media controls into your pages.

Implementing media controls

Embedding multimedia elements into webpages isn’t a new concept. This capability has been around for a long time and has presented challenges in various situations. One key challenge has often been dependence on a third-party object integrated with the browser to render the media. In this section, you look at two new elements added to the HTML5 specification that work with multimedia natively in the web browser and with JavaScript. You also examine the <video> and <audio> elements.

Using the <video> element

Embedding video into a webpage has become very popular, and many websites now include a video element in their design. HTML5 has made including video in your webpages much easier than it was previously. Here, you learn about the new <video> element provided by the HTML5 standard and look at the available attributes and events you can use to control video either declaratively, through static HTML, or dynamically, using JavaScript.

Embedding a video in the page is as simple as adding the following markup:

<video src="samplevideo.mp4" autoplay> </video>

That’s the bare minimum. However, you know that the bare minimum is rarely enough for a professionally designed website. You need to work with more properties and events. You also need to consider browser support for various video formats. First, you need to examine the key attributes available to use on the <video> element, as listed in Table 1-4.

Image

TABLE 1-4 Attributes available on the <video> element

With all this new information about the available attributes, you can provide a bit more detail in your <video> element to control how you would like it to behave:

<video src="samplevideo.mp4" controls poster="picture.jpg" height="400" width="600">
</video>

The preceding <video> element specifies that it should initially display a poster image, sets the height and width parameters, and indicates that the default controls should be available. The absence of a loop attribute means that when the video is finished, it shouldn’t repeat automatically. And the absence of an autoplay attribute tells the browser that you don’t want the video to start playing automatically; instead, it should wait until the user invokes the play operation with the controls or until you invoke the play operation with JavaScript. When you do include the default controls, the user gets a basic set. Figure 1-23 shows what the default controls look like in Internet Explorer.

Image

FIGURE 1-23 The default Internet Explorer media controls

From left to right, the default controls provide a play button that changes to a pause button while the video is playing. A timer shows the current video position and how much time remains in the video. A slider bar lets users navigate to a specific point in the video. The audio control button pops out a volume slider bar when pressed, and finally, at the far right, is a control that enables users to display the video at full-screen size.

So far, so good—for Internet Explorer users. But you also need to ensure that your video will play successfully in other browsers. The problem is that not all browsers support all video formats. Keep this in mind as you implement your <video> elements; what each browser supports can (and will) change as well. You need to ensure that you provide options to the browser so that it can choose which video format to play. If you don’t have all the appropriate supported video formats and your page happens to get a visitor with a browser that can’t play the video format you have, you also need to provide an alternative or at least the information that the user’s browser doesn’t support this video. The following code demonstrates this:

<video controls height="400" width="600" poster="picture.jpg">
   <source src="samplevideo.ogv" type="video/ogg"/>
   <source src="samplevideo.mp4" type="audio/mp4"/>
   <object>
       <p>Video is not supported by this browser.</p>
   </object>
</video>

This sample removed the src attribute from the <video> element and added child <source> elements instead. The <video> element supports multiple <source> elements, so you can include one for each video type. A browser goes through the <source> elements from top to bottom and plays the first one that it supports.

Notice that the example also has an <object> element to cover the possibility that the client browser has no support for the <video> element at all. In such cases, you could have a Flash version of the video to play; but if no other version of the video is available to play, you can just display a message that video isn’t supported, as shown in the code snippet. Browsers that don’t support the <video> element ignore the element altogether but show the <object> element that they do understand. This lets older browsers “fall back” to previous methods for displaying video, ensuring that you can reach as many users as possible.

Finally, the <p> element is a last resort to provide at least some information to users that a video is supposed to be playing here but that their browser doesn’t support it.


Image Exam Tip

If the browser supports the HTML5 video element, it doesn’t show the fallback. In this case, make sure that you have the valid <source> element specified for that browser. If you don’t, the video container shows an error in place of the control bar, saying that an invalid link or file is specified.


Sometimes having more control over things is nice, or perhaps you just don’t like the look and feel of the default controls. This is where JavaScript comes in. You can create your own control bar and substitute your own control buttons to enable users to control the video. The following example adds a few custom image elements to the page and wires up some JavaScript to control the video:

<head>
    <style>
        img:hover {
            cursor: pointer;
        }
    </style>
    <script>
        var video;
        window.onload = function () {
            video = document.getElementById("sampleVideo");
        }

        function play() {
            video.play();
        }
        function pause() {
            video.pause();
        }
        function back() {
            video.currentTime -= 10;
        }

    </script>
</head>
<body>
    <table>
        <tr>
            <td>
                <video height="400" width="600" id="sampleVideo">
                    <source src="samplevideo.mp4" type="audio/mp4"/>
                </video>
            </td>
            <td>
                <img id="backButton" src="backword.png" onclick="back();"/><br/>
                <img id="playButton" src="forward.png" onclick="play();"/><br/>
                <img id="PauseButton" src="pause.png" onclick="pause();"/><br/>
            </td>
        </tr>
    </table>
</body>

This HTML produces the media controls shown in Figure 1-24.

Image

FIGURE 1-24 A custom media control bar

As you can see, the code has created a little custom control bar and positioned it to the right of the video frame. The <video> element offers many methods. Table 1-5 outlines the more common ones.

Image

TABLE 1-5 Methods and properties on the <video> object

You’ve learned all about how to display video in your webpages. Now turn your attention to playing sounds using the <audio> element.

Using the <audio> element

The <audio> element is essentially identical to the <video> element. It has all the same attributes and the same methods. The only real difference is how it displays in the browser. Because no video is available to show, the <audio> element occupies no screen space. However, you can show the default controls—or you can again choose not to show the default controls and to create your own mechanism to control the audio, either through custom user interface elements or behind the scenes in JavaScript. Here is an example of what an <audio> declaration looks like in your webpage:

<audio controls>
    <source src="sample.mp3" type="audio/mp3"/>
    <source src="sample.ogg" type="audio/ogg"/>
    <p>Your browser does not support HTML5 audio.</p>
</audio>

This HTML provides the output in Internet Explorer shown in Figure 1-25.

Image

FIGURE 1-25 The default audio controls in Internet Explorer

Figure 1-25 shows the output of the <audio> element when you opt to use the built-in controls. From left to right, you get a pause/play button, the counter, a progress bar, the total time in the audio, and a volume slider bar. Because no other screen space is required as in the video samples, the <audio> element has no height or width properties available. If you don’t like the built-in audio control bar, you can choose not to include it in your declaration and instead create a custom control bar that suits your needs.

The <audio> and <video> elements are very similar. The key point regarding these elements is that they provide a standardized way to represent media in HTML pages to simplify reading the HTML code and know exactly what the page is supposed to be doing.

Now that you know how to use audio and video in your webpages, you can turn your attention to the use of graphics.

Implementing graphics with HTML5 <canvas> and SVG

HTML5 provides a new mechanism to work with graphics in your webpages. The HTML5 specification introduces the <canvas> webpage element, which provides a blank canvas on which you can draw dynamically. You can draw lines, text, and images on the canvas and manipulate them with JavaScript.

Adding a canvas to your page is as simple as declaring one in the HTML. The <canvas> element is similar to the <div> element. However, it’s a container for graphics as opposed to text-based elements. Here is the markup for a <canvas> element:

<canvas id="drawingSurface" width="600" height="400">
Your browser does not support HTML5.
</canvas>

The HTML is very straightforward. You simply need to define a <canvas> and specify a size. Also, if the user’s browser doesn’t support the <canvas> element, you can place fallback text inside the <canvas> element to be displayed in its place. When you run this HTML in the browser, you should notice absolutely nothing! This is because—just like with a <div> element or any other container—the <canvas> element has no default visibility; in other words, it’s visible, but it’s white with no borders, and thus it’s invisible on a blank HTML page. The next example adds a simple style to your <canvas> element so that you can see its borders:

<style>
  canvas {
        border: 1px solid black;
     }
</style>

Now you can see your canvas, which should look Figure 1-26.

Image

FIGURE 1-26 A blank <canvas> element

A blank canvas isn’t terribly exciting yet. But now that you have a basic canvas up and running, you can work through all the various methods to create graphics on the canvas. To do that, you should create an onload event for your window (as you have in previous examples) to encapsulate your code and cause the graphics to render when the page is loaded. To draw on the canvas, you need to understand the coordinate system that the canvas uses.

The canvas provides a fixed (x,y) coordinate system in which the top-left corner of the canvas is (0,0). In this case, the bottom-left corner of the canvas is (0,400), the top-right corner is (600,0), and the bottom-right corner is (600,400). You should be fairly used to this type of system because it matches the browser window coordinate system, with (0,0) in the top-left corner. However, the position of the canvas in the browser window is irrelevant to the drawing methods you use to draw on the canvas. The coordinates for drawing on the canvas are always based on the coordinates within the canvas itself, where the top-left pixel is (0,0).

As with any HTML element, to work with it through code you need to get a reference to it in your JavaScript. Begin by writing the following code in your page:

window.onload = function () {
            var drawingSurface = document.getElementById("drawingSurface");
            var ctxt = drawingSurface.getContext("2d");
        }

In the preceding code, you get a reference to your canvas element followed by a reference to a “2d” context. The context is an object that provides the API methods you use to draw on the canvas. Now, <canvas> supports only a 2d context, but you can expect to see a 3d context in the future.

Having acquired a reference to the context, you can now start to look at the various methods for drawing on your canvas.

Drawing lines

At the most basic level, you can draw lines on the canvas with the 2d context object you are referencing. The context object provides the following methods for drawing lines, as listed in Table 1-6.

Image

TABLE 1-6 Methods for drawing lines

With that information, in its simplest form, you can draw a line across your canvas like this:

ctxt.beginPath();
ctxt.moveTo(10, 10);
ctxt.lineTo(225, 350);
ctxt.stroke();

This code produces the line on the canvas shown in Figure 1-27.

Image

FIGURE 1-27 A line drawn on the canvas

At the point where the line ends, you can continue drawing more lines by adding more lineTo methods, as in the following example:

ctxt.beginPath();
ctxt.moveTo(10, 10);
ctxt.lineTo(225, 350);
ctxt.lineTo(300, 10);
ctxt.lineTo(400, 350);
ctxt.stroke();

Run this code and look at the output. You get a graphic that resembles Figure 1-28. You might use straight lines in this way when plotting connected points on a line graph, for example.

Image

FIGURE 1-28 A polyline drawn on the canvas

Exploring the stroke method in more depth is worth the effort. If you were creating a chart or a graph, you might want to change the color of your lines so that they stand out from the axis. You might want to change the thickness. You do this by changing some properties on the context object before calling the stroke method:

ctxt.lineWidth = 5;
ctxt.strokeStyle = '#0f0';

The lineWidth property accepts a value that determines the line width. The strokeStyle property lets you change the line color. This property accepts all the common style formats for specifying colors in HTML, including hexadecimal values or named colors. These changes produce a new, more attractive output, as shown in Figure 1-29.

Image

FIGURE 1-29 The polyline rendered with a different color

You also can experiment with the lineCap property, which accepts a few values that control how the end of the line will render. For example, you can set the lineCap property to round to give the line a rounded cap. Applying a cap affects the length of the line. The cap is added to the end of line, and its length matches what you have set for the line’s width. In this example, the line has a width of 5. With a round cap set on the line, the total line length would be extended by 5.

You’ve seen all you need to know about working with straight lines. Now turn your attention to curves.

Drawing curves

Drawing curves is a little more involved because you have more parameters to consider. Table 1-7 lists the methods used when working with curves on the HTML5 canvas.

Image

TABLE 1-7 Methods for drawing curves

Each drawing method can have styles applied to it, just like the line examples. You can control the lineWidth, strokeStyle, and lineCap properties to change how your curves display. Start off by creating some basic arcs on your canvas. The arc method takes the parameters listed in Table 1-8.

Image

TABLE 1-8 Parameters required to draw an arc

Add the following code to your page:

ctxt.beginPath();
ctxt.arc(150,100,75,0,2 * Math.PI, false);
ctxt.lineWidth = 25;
ctxt.strokeStyle = '#0f0';
ctxt.stroke();

ctxt.beginPath();
ctxt.arc(450, 100, 75, 1.5 * Math.PI, 2 * Math.PI, false);
ctxt.lineWidth = 25;
ctxt.strokeStyle = 'blue';
ctxt.stroke();

ctxt.beginPath();
ctxt.arc(150, 300, 75, 1 * Math.PI, 1.5 * Math.PI, false);
ctxt.lineWidth = 25;
ctxt.strokeStyle = '#0ff';
ctxt.stroke();

ctxt.beginPath();
ctxt.arc(450, 300, 75, .5 * Math.PI, 1 * Math.PI, false);
ctxt.lineWidth = 25;
ctxt.strokeStyle = '#f00';
ctxt.stroke();

This code sample draws four arcs: a full circle followed by three quarter circles, each with a different style. Notice that some math formulas are specified in the parameters to the arc. This math is necessary to get the value in radians because the parameters for startAngle and endAngle are specified in radians, not in degrees. The code produces the drawing shown in Figure 1-30.

Image

FIGURE 1-30 Drawing arcs on the canvas in different colors

The previous example demonstrated a simple arc. Now look at the next arc method, the quadraticArc. The curve of a quadratic arc is evenly distributed from one end to the other in terms of its distance from the center point. The quadraticCurveTo method allows you to specify some additional parameters to alter the “steepness” of the curve—in other words, to change the distance from the center point along the curve. Drawing a quadratic curve is somewhat like drawing a straight line but then pinching it in the middle and pulling it away to create a curve where the starting and ending points of the line stay fixed. The farther away you pull the center point, the steeper the curve becomes. Here’s an example:

ctxt.beginPath();
ctxt.moveTo(10,380);
ctxt.quadraticCurveTo(300,-250,580,380);
ctxt.lineWidth = 25;
ctxt.strokeStyle = '#f00';
ctxt.stroke();

You first need use the moveTo method to tell the context where you want your curve to start. Then, you pass the four parameters described in Table 1-9 to the quadraticCurveTo method.

Image

TABLE 1-9 Parameters required for the quadraticCurveTo method

The code sample produces the image in Figure 1-31.

Image

FIGURE 1-31 A quadratic curve output onto a canvas

As the control point moves farther away from the line formed by the start and end points, you get a steeper curve. This example used a negative number to indicate that the control point should be above the top of your canvas to stretch the curve to where you want it.

The final curve to look at is the Bezier curve. A Bezier curve is similar to the quadratic curve except that it has two control points instead of just one. Having two points allows the Bezier curve to create more complex curves. In both examples you have seen so far, the curve was created around the context of a single point. The Bezier curve changes that. It’s easiest to see in an example, and then I’ll explain the parameters. Create the following code:

ctxt.beginPath();
ctxt.moveTo(125, 20);
ctxt.bezierCurveTo(0, 200, 300, 300, 50, 400);
ctxt.lineWidth = 5;
ctxt.strokeStyle = '#f00';
ctxt.stroke();

The bezierCurveTo method follows a moveTo method call in the same way that the quadraticCurveTo method did. You need to pass three sets of coordinates to the bezierCurveTo method, as listed in Table 1-10.

Image

TABLE 1-10 Parameters required for the bezierCurveTo method

The code sample produces the output shown in Figure 1-32. You can see that this curve is skewed because of the two control points.

Image

FIGURE 1-32 A Bezier curve drawn on a canvas

In the next section, you learn about using path methods to combine everything you’ve looked at so far.

Using path methods

When using the context object to draw, you always need a starting point and an ending point. The ending point for one stroke also can become the starting point for the next stroke. You do this by calling the beginPath method on the context object and then drawing all your lines before calling either the closePath method (which ends the line) or the beginPath method (which starts a new line) again. Recall that the first arc example called the beginPath method before drawing each arc. Had the code not done that, the line would have continued across the canvas from one arc to the next. But by calling the beginPath method again, you reset the path’s starting point. So essentially, you can string together all the calls to the various drawing methods to create a complex stroke. The stroke—no matter how simple or complex—is called a path. Run the following code and see what kind of image you end up with:

ctxt.beginPath();
ctxt.arc(300, 200, 75, 1.75 * Math.PI, 1.25 * Math.PI, false);
ctxt.lineTo(150, 125);
ctxt.quadraticCurveTo(300, 0, 450, 125);
ctxt.lineTo(353, 144);
ctxt.strokeStyle = "blue";
ctxt.lineCap = "round";
ctxt.lineWidth = 10;
ctxt.stroke();

This code produces the output shown in Figure 1-33.

Image

FIGURE 1-33 A custom path drawn on the canvas

Although this is still a simple example, you can get creative and put together images quite nicely. Depending on your math skills, you can create some very complex graphics using these methods.

Next, look at the other methods that exist for drawing shapes.

Using the rect method

Earlier, you saw how to draw circles using the arc method. And as you saw in the previous section, you can draw custom shapes of any sort and size by using the beginPath method and stringing together a series of drawing methods. But you don’t always need to do that; some shapes are built in. In this section, you look at the built-in functionality to build rectangles. Then you look at the functionality to fill your drawn shapes with colors and patterns. The context object to which you have a reference has a method called rect. The rect method takes the parameters listed in Table 1-11.

Image

TABLE 1-11 Parameters required for drawing rectangles

A simple call to the rect method, as in the following code, draws a rectangle:

ctxt.beginPath();
ctxt.rect(300, 200, 150, 75);
ctxt.stroke();

This code draws a rectangle as shown in Figure 1-34.

Image

FIGURE 1-34 A rectangle drawn on the canvas using the rect method

Notice that although the parameters passed in for the top-left corner were (300,200), which is the center of your canvas, the rectangle is off center. To center your rectangle, you would need to do a bit of math to calculate the center based on the size of your canvas as well as the size of your desired rectangle. The following code should center your rectangle:

ctxt.beginPath();
var x, y;
x = 150;
y = 75;
ctxt.rect(300—(x/2), 200—(y/2), x, y);
ctxt.stroke();

Now that you can draw shapes and rectangles, you can look at how you would go about filling your shapes with colors or patterns.

Using the fill method

In this section you examine how you can fill your shapes. You have drawn various types of shapes, but so far they have been empty. Here you’ll see how to fill them with colors, gradients, and patterns.

Filling a shape with a color is as simple as setting the fillStyle property to a color and calling the fill method. Inserting the following code before calling the stroke method fills your shape with a blue color:

ctxt.fillStyle = "blue";
ctxt.fill();

With respect to the rect method, you get a special fill method specifically for rect called fillRect. With this method, you can create and fill your rectangle in one call:

ctxt.fillStyle = "blue";
ctxt.fillRect(300—(x / 2), 200—(y / 2), x, y);

Using the fillRect method reduces the amount of code required. And it’s just as simple to fill nonrectangular shapes, such as the complex Path graphic that you created earlier, with a single call to the fill method:

ctxt.beginPath();
ctxt.arc(300, 200, 75, 1.75 * Math.PI, 1.25 * Math.PI, false);
ctxt.lineTo(150, 125);
ctxt.quadraticCurveTo(300, 0, 450, 125);
ctxt.lineTo(353, 144);
ctxt.strokeStyle = "blue";
ctxt.lineCap = "round";
ctxt.lineWidth = 10;
ctxt.fillStyle = "Green";
ctxt.fill();
ctxt.stroke();

You can see in Figure 1-35 that the logic of coloring in this complex shape is completely handled by the browser.

Image

FIGURE 1-35 Using the fill method to color in a complex object

That’s all it takes to fill a shape with a solid color. Filling shapes with a gradient requires a few extra steps.

Creating a gradient involves using a new CanvasGradient object. You first call the createLinearGradient method available on the context object to get a CanvasGradient object. On that CanvasGradient object, you define the color stops that you want to blend to create the gradient effect. Then you assign your CanvasGradient object to the fillStyle property of the context. The following code creates and fills a rectangle with a linear gradient:

var ctxt = drawingSurface.getContext("2d");
ctxt.lineWidth = 3;
ctxt.rect(150, 150, 200, 125);
var gradient = ctxt.createLinearGradient(150, 150, 200, 125);
gradient.addColorStop(0, "Black");
gradient.addColorStop(0.5, "Gray");
gradient.addColorStop(1,"White");
ctxt.fillStyle = gradient;
ctxt.fill();
ctxt.stroke();

This code creates the CanvasGradient object by passing in the start and end points of a gradient line. You then add three color stops. The addColorStop method takes two parameters. The first is a value from 0 to 1, where 0 is the starting point of the gradient line and 1 is the ending point. The second parameter is the color to start filling with at that stop. This example has three stops, so the gradient transitions through three colors. The gradient output is displayed in Figure 1-36.

Image

FIGURE 1-36 The <canvas> element colored with a linear gradient

You can also create a radial gradient using the createRadialGradient method. This method takes six parameters, which specify the center point and radius of two circles and the color transitions through the stops along the cone formed by the two circles. The following code produces a radial gradient in which the cone is pointed toward the viewer:

var ctxt = drawingSurface.getContext("2d");
ctxt.lineWidth = 3;
ctxt.rect(150, 150, 250, 175);
var gradient = ctxt.createRadialGradient(200, 200,5, 250, 250,100);
gradient.addColorStop(0, "Red");
gradient.addColorStop(.5, "Orange");
gradient.addColorStop(1, "Blue");
ctxt.fillStyle = gradient;
ctxt.fill();
ctxt.stroke();

Figure 1-37 shows the output of this gradient:

Image

FIGURE 1-37 A radial gradient colored on a canvas

The last fill option to look at involves using a fill pattern. You need an external image, which is applied as a pattern throughout the shape. For example, you can use a texture that you created as a background to your canvas by using the following code:

var ctxt = drawingSurface.getContext("2d");
ctxt.lineWidth = 3;
ctxt.rect(150, 150, 200, 125);
var img = new Image();
img.src = "texture.png";
img.onload = function () {
    var pat = ctxt.createPattern(img, "repeat");
    ctxt.fillStyle = pat;
    ctxt.fill();
    ctxt.stroke();
}

Figure 1-38 shows the output of this code.

Image

FIGURE 1-38 The canvas filled with a pattern drawn on it

The preceding code calls the createPattern method and passes it a reference to an Image object and a repeat pattern. The repeat pattern can be no-repeat, repeat-x, or repeat-y, but it defaults to repeat if you don’t specify anything. You need to assign an event handler to the onload event of the Image object to ensure that you draw the pattern only after the image loads. Otherwise, the code could run before the picture is rendered, and the pattern won’t display.

This section has covered a lot about how to work with shapes and fill them. All your graphics have been created by using code to manually draw shapes. Next, you see how to draw existing graphics from external files on your canvas, and then you look at drawing text.

Drawing images

Drawing images on a canvas is just as straightforward as the other drawing methods you’ve seen. To draw an image on a canvas, you use the drawImage method of the context object. This method takes an Image object and some (x,y) coordinates to define where the image should be drawn. Just like with the rectangle, the image’s top-left corner is drawn at the specified (x,y). The default size of the image is the actual image size, but as you will see right after, you can also resize the image as you draw it. To simply draw the image, create the following code:

var drawingSurface = document.getElementById("drawingSurface");
var ctxt = drawingSurface.getContext("2d");
var img = new Image();
img.src = "orange.jpg";
img.onload = function () {
    ctxt.drawImage(img, 0, 0);
    ctxt.stroke();
}

This code produces a <canvas> element with the image drawn on it, as shown in Figure 1-39.

Image

FIGURE 1-39 An image drawn on a canvas

If you want to resize the image, you can replace the drawImage method call with the following line:

ctxt.drawImage(img, 0,0,img.width * .5, img.height * .5);

This reduces the image size by 50 percent.

Now look at how you can draw text on your canvas.

Drawing text

Drawing text on the canvas involves adding a few additional tools to your chest from the context object, using the strokeText method and the font property. You see how to apply color to your text and, finally, how to manage its alignment.

In its simplest form, drawing text requires only the following code:

ctxt.strokeText("1. Text with default font", 100, 100);

Remember that you need to make sure the window has finished loading and you need to get a context object. Here’s the full code for this example:

window.onload = function () {
    var drawingSurface = document.getElementById("drawingSurface");
    var ctxt = drawingSurface.getContext("2d");
    ctxt.strokeText("1. Text with default font", 100, 100);
}

That’s it. The strokeText call draws the specified text into the specified coordinates on the canvas. The parameters specify what text to draw, and the (x,y) coordinates specify where drawing should begin. The strokeText method draws in the default font style. You can easily change the font property of the context object to enhance the appearance of your text. For example, running the following code changes the font size to 24 and the font family to Arial:

ctxt.font = "24px arial";
ctxt.strokeText("2. Text with altered font", 100, 125);

To color your text, you could add this code:

ctxt.font = "24px arial";
ctxt.strokeStyle = "Red";
ctxt.strokeText("3. Text with altered colored font", 100, 160);

When you run the preceding code, notice that your text is outlined. This is the default behavior when you increase the font size; it’s drawn as outlined. To draw solid-colored text, add the following code, which sets the fillStyle property and calls the fillText method instead of the strokeStyle and StrokeText methods:

ctxt.font = "24px arial";
ctxt.fillStyle = "Red";
ctxt.fillText("4. Text with altered colored font", 100, 185);

You can also set the alignment of your text within the canvas. For example, to ensure your text is centered, add this code:

ctxt.font = "24px arial";
ctxt.textAlign = "center";
ctxt.fillStyle = "Red";
ctxt.fillText("5. Text with altered colored font Centered.", drawingSurface.width / 2,
drawingSurface.height / 2);

By setting the textAlign property to the value center, you are telling the context to consider the specified (x,y) coordinate as the center point of the string instead of the beginning point of the string. So, you divide the canvas width and height by two to get the center point of the canvas, and you get a string centered horizontally and vertically.

Figure 1-40 shows the progression of your text:

Image

FIGURE 1-40 Progression of text with changing styles

The canvas is a strong utility for presenting graphics dynamically in the browser. However, it’s not the only graphical tool available. In the next section, you look at using Scalable Vector Graphics.

Scalable Vector Graphics (SVG)

Scalable Vector Graphics (SVG) is an XML-based language for creating two-dimensional graphics. It’s implemented by using tags defined by the SVG XML namespace and embedded in HTML5 documents within opening and closing <svg> elements.

SVG objects don’t lose any quality as users zoom in or out. You can access SVG objects via the DOM, and—similar to HTML elements—SVG elements support attributes, styles, and event handlers. The <svg> element provides a container in which to render graphics; SVG renders inline with the page’s layout. Here’s an example of an SVG graphic with event handlers:

<!DOCTYPE html>
<html>
   <head>
       <title>Test Web Page</title>
       <script language="javascript">
           function Red(evt) {
               var circle = evt.target;
               circle.setAttribute("style", "fill: red");
           }

           function Green(evt) {
               var circle = evt.target;
               circle.setAttribute("style", "fill: green");
           }
       </script>
   </head>
   <body>
       <svg>
          <circle id="Circle" cx="50" cy="50" r="50" fill="green" onmouseover="Red(evt)"
             onmouseout="Green(evt)"/>
       </svg>
   </body>
</html>

This code produces the output shown in Figure 1-41. The JavaScript event handlers turn the circle red when the mouse hovers over it and back to green when the mouse is moved out of the circle.

Image

FIGURE 1-41 A circle drawn using SVG

All the shape-drawing and line-drawing functionality you saw in the <canvas> element discussion exists for SVG as well, although the syntax is different, of course. The following code produces a slightly more elaborate graphic.

<svg>
    <rect id="lightStandard"  x="100" y="100" width="60" height="200" fill="black"/>
    <circle id="redLight" cx="129" cy="145" r="25"  fill="red"/>
    <circle id="amberLight" cx="129" cy="205" r="25" fill="yellow"/>
    <circle id="greenLight" cx="129" cy="265" r="25" fill="green"/>
</svg>

The image in Figure 1-42 shows the output of this code:

Image

FIGURE 1-42 Multiple shapes drawn using SVG

In this example, the <rect> element was used to create the background rectangle, and a series of <circle> elements were used to create the lights. Each SVG shape requires the same types of parameters as their canvas counterpart, and the same rules apply. The <rect> element needs an (x,y) coordinate to establish where it should be drawn, along with a width and height to establish the size. The same is true for each circle, except that you specify the radius for the size. The fill attribute sets the color to be used to fill the shape.

SVG also supports the same basic shape-drawing functions as the canvas context. The following code segment shows the use of the polyline, polygon, line, and ellipse and produces the output shown in Figure 1-43:

<svg>
    <polygon points="10,15 30,35 10,85 100,85, 70,35,100,15" fill="purple"/>
    <polyline points="10,150 30,170 50,132 62,196 78,165 96,170"

              style="stroke:orange; fill:none; stroke-width:5;"/>
    <line x1="150" y1="100" x2="150" y2="150" style="stroke:blue;stroke-width:3"/>
    <ellipse cx="250" cy="150" rx="30" ry="55" fill="green"/>
    <text x="10" y="10" style="stroke: black;stroke-width:1;">

              Examples of SVG Shapes and Text</text>
</svg>

Image

FIGURE 1-43 Text, a line, a polygon, an ellipse, and a polyline drawn in different colors


Image Exam Tip

In some cases, using SVG graphics is simpler than using the <canvas> element. As the examples have shown, you can create SVG images declaratively directly within the HTML itself. However, as you increase the number of objects in an SVG rendering, performance can become a concern. In cases where performance is a consideration, using the <canvas> element is a preferable approach.


SVG also supports rendering existing graphics in the form of external image files, as shown here:

<svg id="mySVG">
    <image href="orange.jpg" width="250" height="100"/>
</svg>

Objective summary

Image JavaScript is a powerful tool that enables developers to manipulate the DOM programmatically in the browser.

Image HTML5 supports rich media controls to incorporate video by using the <video> element and audio by using the <audio> element.

Image The <video> element supports multiple media formats by using the <source> element.

Image The HTML5 <canvas> and <svg> elements support a rich API to create both simple and complex graphics in the browser.

Image Both the <canvas> and <svg> graphics engines can draw text, lines, shapes, fonts, fills, and gradients.

Image The <canvas> element is drawn on via JavaScript by getting a reference to the context.

Image The <svg> element renders graphics by using a declarative syntax.

Objective review

Answer the following questions to test your knowledge of the information in this objective. You can find the answers to these questions and explanations of why each answer choice is correct or incorrect in the “Answers” section at the end of this chapter.

1. Which of the following JavaScript methods can’t be used to select an element in the DOM?

A. getElementById

B. querySelector

C. getElementByClassName

D. queryAll

2. Which line of JavaScript successfully retrieves only the image element with the ID myDog from the following HTML? Choose all that apply.

<form>
    <div id="main" class="mainStyle">
        <p id="dogs">
             This is a web page about dogs. Here is my dog picture:
             <img src="dog.jpg" id="myDog" class="thumb"/>
             Here is a picture of my friend's dog:
             <img src="dog.jpg" id="myfriendsDog" class="thumb"/>
        </p>
    </div>
</form>

A. document.getElementbyId(“myDog”);

B. <p>.getChildNode(“img”);

C. document.getElementbyId(“dogs).querySelector (“thumb”);

D. document.querySelectorAll(“thumb”);

3. To hide an element in the DOM and still be able to add it back later, what should you do?

A. Nothing, because the DOM is always available in a static form.

B. Keep a reference to the removed node to be able to add it back.

C. Call the document.restoreNodes method.

D. You can’t add an element back after it’s removed.

4. When implementing the HTML5 video element, how do you ensure that the rendering of the element can function in different browsers?

A. You need to do nothing, because HTML5 is now a standard specification.

B. Specify all the source video types in the src attribute of the video element.

C. Include the <source> element for each video type so that each browser can play the version that it supports.

D. Include the <object> element for each video type so that the browser can play the version that it supports.

5. When drawing on the HTML5 <canvas> element, what method is used on the context to begin drawing at a new point?

A. moveTo

B. lineAt

C. beginPath

D. stroke

6. When performance is critical for an HTML5 graphics application, what should you use?

A. <canvas> using a declarative syntax to create the graphics

B. <svg> using a declarative syntax to create the graphics

C. <canvas> using JavaScript to create the graphics

D. <svg> and <canvas> combination to leverage the best performance of both

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.185.169