SlideShare a Scribd company logo
www.GetPedia.com
*More than 150,000 articles in the
        search database
 *Learn how almost everything
            works
How To Do Everything With JavaScript
JavaScript
This page intentionally left blank
JavaScript
         Scott Duffy




           McGraw-Hill/Osborne
         New York Chicago San Francisco Lisbon
    London Madrid Mexico City Milan New Delhi
       San Juan Seoul Singapore Sydney Toronto
McGraw-Hill/Osborne
2600 Tenth Street
Berkeley, California 94710
U.S.A.
To arrange bulk purchase discounts for sales promotions, premiums, or fund-raisers, please
contact McGraw-Hill/Osborne at the above address. For information on translations or book
distributors outside the U.S.A., please see the International Contact Information page immediately
following the index of this book.

                                         How to Do Everything with JavaScript

Copyright © 2003 by The McGraw-Hill Companies. All rights reserved. Printed in the United
States of America. Except as permitted under the Copyright Act of 1976, no part of this publication
may be reproduced or distributed in any form or by any means, or stored in a database or retrieval
system, without the prior written permission of publisher, with the exception that the program
listings may be entered, stored, and executed in a computer system, but they may not be reproduced
for publication.
1234567890 FGR FGR 019876543
ISBN 0-07-222887-3

Publisher:                            Brandon A. Nordin
Vice President
& Associate Publisher:                Scott Rogers
Acquisitions Editor:                  Megg Morin
Project Editors:                      Leslie Tilley, Madhu Prasher
Acquisitions Coordinator:             Tana Allen
Technical Editor:                     Warren Raquel
Copy Editor:                          Leslie Tilley
Proofreader:                          Paul Tyler
Indexer:                              Valerie Robbins
Computer Designers:                   Carie Abrew, Lucie Ericksen
Illustrators:                         Melinda Lytle, Michael Mueller, Lyssa Wald
Series Design:                        Mickey Galicia
Cover Series Design:                  Dodie Shoemaker
Cover Illustration:                   Eliot Bergman

This book was composed with Corel VENTURA™ Publisher.


Information has been obtained by McGraw-Hill/Osborne from sources believed to be reliable. However, because of the possibility of
human or mechanical error by our sources, McGraw-Hill/Osborne, or others, McGraw-Hill/Osborne does not guarantee the accuracy,
adequacy, or completeness of any information and is not responsible for any errors or omissions or the results obtained from the use of
such information.
This book is dedicated to:

     My wife, Liez’l. Words cannot adequately express
            how important you are to my life.

  My mother, who taught me the true meaning of strength
              and perseverance. God bless.

My father, who at this very moment is surely telling the angel
       next to him, “That’s my son.” I miss you, Dad.
About the Author
Scott Duffy has been providing IT consulting services to medium- and large-sized businesses
and government organizations for more than six years. Before embarking on a career as a
consultant, Scott worked at two of the largest corporations in Canada as a software developer.
    His 12 years of professional experience cover a wide range of platforms and technologies,
including programming in mainframe, client-server, and web-based application environments.
He is actively involved in every stage of the software development process, including team
management.
    When he’s not designing software applications for clients, Scott keeps himself busy with his
writing projects. He is currently working on his next book for McGraw-Hill/Osborne, a study
guide for the Microsoft MCSD 70-300 exam.
    To contact Scott to discuss your organization’s business needs, or about any other matter,
please e-mail him at scott.duffy@mydemos.com or visit his web site at http://www.mydemos.com.
Contents at a Glance
Part I          Learn JavaScript Basics
           1    Prepare to Program in JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .             3
           2    Learn JavaScript Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .             25
           3    Use Built-in JavaScript Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .           63
           4    Organize Data into Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         95
           5    Create Your Own JavaScript Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . .               117

Part II         Build JavaScript-Enabled Web Sites
            6   Embed JavaScript in a Web Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .             141
            7   Create Scripts That Work in Every Browser . . . . . . . . . . . . . . . . . . . . . . . .                  161
            8   Manipulate Web Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       179
            9   Handle Browser Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      207
           10   Communicate Between Browser Frames . . . . . . . . . . . . . . . . . . . . . . . . . .                     223
           11   Interact with the Web Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .          243
           12   Perform Simple Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         259

Part III        Take JavaScript to the Next Level
           13   Debug JavaScript Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .          281
           14   Make Your Program Errorproof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .             295
           15   Use JavaScript to Manage Browser Plug-Ins . . . . . . . . . . . . . . . . . . . . . . .                    313

           A    HTML 4.01 Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   327
           B    JavaScript Quick Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         331

                Index       .....................................................                                          335



                                                                                                                                 vii
This page intentionally left blank
Contents
            Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .           xv
            Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   xvii

PART I      Learn JavaScript Basics
CHAPTER 1   Prepare to Program in JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . .                         3
            Learn the History of JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .              4
                   The Origin of JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .              5
                   JavaScript Makes Its Way into Internet Explorer . . . . . . . . . . . . .                             5
                   JavaScript Becomes an Official Standard . . . . . . . . . . . . . . . . . . .                         5
                   Where JavaScript Is Today . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                 6
            Choose a Development Environment . . . . . . . . . . . . . . . . . . . . . . . . . . .                       7
                   Develop JavaScript-Enabled Web Pages . . . . . . . . . . . . . . . . . . .                            7
                   Create Server-Based Web Applications . . . . . . . . . . . . . . . . . . . .                          8
                   Use JavaScript in a DOS or Windows Environment . . . . . . . . . .                                    9
                   JavaScript Development Tools . . . . . . . . . . . . . . . . . . . . . . . . . . .                    9
            Learn What JavaScript Can and Cannot Do . . . . . . . . . . . . . . . . . . . . . .                         13
                   Use JavaScript as a Client-Side Language . . . . . . . . . . . . . . . . . .                         14
                   Use JavaScript as a Server-Side Language . . . . . . . . . . . . . . . . . .                         14
            Decide Which Version of JavaScript to Use . . . . . . . . . . . . . . . . . . . . . .                       15
            Test JavaScript Programs Using HTML . . . . . . . . . . . . . . . . . . . . . . . . .                       16
                   Create a JavaScript Template . . . . . . . . . . . . . . . . . . . . . . . . . . . .                 16
                   Understand the JavaScript Template . . . . . . . . . . . . . . . . . . . . . .                       18
            Communicate with the User . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .               19
                   Display an Alert Message . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .               20
                   Write Text to the Browser Window . . . . . . . . . . . . . . . . . . . . . . .                       21
            Learn More about Topics Discussed in this Chapter . . . . . . . . . . . . . . . .                           22

CHAPTER 2   Learn JavaScript Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . .                         25
            Understand Basic Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                26




                                                                                                                              ix
x     How to Do Everything with JavaScript


                  Store Data in Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   26
                        Define Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    27
                        Define Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    28
                  Understand Program Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       29
                  Control Program Flow with Statements . . . . . . . . . . . . . . . . . . . . . . . . .                30
                        Execute Code Conditionally . . . . . . . . . . . . . . . . . . . . . . . . . . . . .            30
                        Repeat Statements Using Loops . . . . . . . . . . . . . . . . . . . . . . . . . .               34
                        Comment Your Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .           43
                        Set a Default Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      44
                        Handle Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   46
                  Understand the Basics of Expressions . . . . . . . . . . . . . . . . . . . . . . . . . .              49
                  Use Operators to Create Complex Expressions . . . . . . . . . . . . . . . . . . .                     50
                  Organize Your Code into Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . .             51
                        Define Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    52
                        Accept Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       54
                        Understand Variable Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .           56
                        Return Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   58
                  Use the Improvements in JavaScript 2.0 to Create More
                    Powerful Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    59
                        Use Named Optional Parameters . . . . . . . . . . . . . . . . . . . . . . . . .                 60
                        Accept Any Number of Parameters . . . . . . . . . . . . . . . . . . . . . . .                   61

    CHAPTER 3     Use Built-in JavaScript Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . .               63
                  Learn about Objects in JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         64
                        Write Unstructured Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . .             65
                        Organize Code into Procedures . . . . . . . . . . . . . . . . . . . . . . . . . .               65
                        Separate a Program into Modules . . . . . . . . . . . . . . . . . . . . . . . . .               66
                        Use the Object-Oriented Approach . . . . . . . . . . . . . . . . . . . . . . .                  66
                        Turn Properties and Functions into a Class . . . . . . . . . . . . . . . . .                    68
                  JavaScript’s Built-in Classes and Data Types . . . . . . . . . . . . . . . . . . . .                  69
                        Instantiate an Object with the new Operator . . . . . . . . . . . . . . . .                     72
                        Access an Object with the . Operator . . . . . . . . . . . . . . . . . . . . . .                73
                        Access an Object with the [] Operator . . . . . . . . . . . . . . . . . . . . .                 73
                  Create a String Object in JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . .          73
                        Create a String Object Using a String Literal . . . . . . . . . . . . . . . .                   74
                        Create a String Object Using the String Data Type . . . . . . . . . . .                         76
                        Use the String Object’s Built-in Functionality . . . . . . . . . . . . . . .                    76
                  Perform Mathematical Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .            78
                  Apply JavaScript’s Date-Handling Functions . . . . . . . . . . . . . . . . . . . . .                  79
                  Convert Strings into Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        82
                        Use the parseInt and parseFloat Functions . . . . . . . . . . . . . . . . . .                   82
                  Prepare Text Before Sending to Web Server . . . . . . . . . . . . . . . . . . . . . .                 84
                        Use the escape and unescape Functions . . . . . . . . . . . . . . . . . . . .                   85
Contents        xi

            Decide When to Use Regular Expressions . . . . . . . . . . . . . . . . . . . . . . .                  86
                  Understand the Basics of Regular Expressions . . . . . . . . . . . . . .                        87
                  Create Patterns with a RegExp Object . . . . . . . . . . . . . . . . . . . . .                  89
            Understand JavaScript 2.0’s Powerful New Data Types . . . . . . . . . . . . .                         91
                  Use the Boolean, Integer, and Number Data Types . . . . . . . . . . .                           91
                  Use the char Data Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        91
                  Use the Object Data Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .          92
                  Understand Special Data Types . . . . . . . . . . . . . . . . . . . . . . . . . .               92

CHAPTER 4   Organize Data into Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .               95
            Create an Array Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    97
                  Create an Empty Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         97
                  Specify an Initial Array Length . . . . . . . . . . . . . . . . . . . . . . . . . .             99
                  Create and Initialize an Array in One Line of Code . . . . . . . . . . .                       100
                  Use Array Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     100
                  Call the Properties and Methods of the Array Object . . . . . . . . .                          101
            Set and Retrieve Values in an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . .          104
            Use Multidimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        107
                  Use JavaScript 2.0’s Enhanced Arrays . . . . . . . . . . . . . . . . . . . . .                 111
                  The StaticArray Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      112
                  The DynamicArray Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .           114
                  The ConstArray Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       114

CHAPTER 5   Create Your Own JavaScript Classes . . . . . . . . . . . . . . . . . . . . . . . .                   117
            Learn about Classes in JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        118
            Create Objects in JavaScript 1.x . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       118
                  Call a Constructor Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . .          119
                  Use an Object Literal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      122
                  Extend an Existing Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         123
                  Extend an Existing Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .          125
            Create Objects in JavaScript 2.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       126
                  Define Your Own Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .          127
                  Organize Classes Using Inheritance . . . . . . . . . . . . . . . . . . . . . . .               130
                  Choose Between Static and Instance Members . . . . . . . . . . . . . .                         135
                  Make Class Members Public or Private . . . . . . . . . . . . . . . . . . . .                   136

PART II     Build JavaScript-Enabled Web Sites
CHAPTER 6   Embed JavaScript in a Web Page . . . . . . . . . . . . . . . . . . . . . . . . . .                   141
            Understand Basic HTML Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . .            142
                  Build an HTML Document . . . . . . . . . . . . . . . . . . . . . . . . . . . . .               145
                  Indicate the Document Type with <!DOCTYPE> . . . . . . . . . . . .                             146
xii     How to Do Everything with JavaScript


                           Add a Title and Define Document Keywords . . . . . . . . . . . . . . . .                      147
                           Format Text with HTML Elements . . . . . . . . . . . . . . . . . . . . . . .                  148
                           Format Text with Style Sheets . . . . . . . . . . . . . . . . . . . . . . . . . . .           150
                    Use <script> to Add JavaScript to a Web Page . . . . . . . . . . . . . . . . . . . .                 153
                    Use <noscript> for Browsers That Don’t Support Scripting . . . . . . . . . .                         154
                    Load an External JavaScript File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       157
                    Call JavaScript Using Hyperlinks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         158
                    Learn More about the Topics in this Chapter . . . . . . . . . . . . . . . . . . . . .                159

      CHAPTER 7     Create Scripts That Work in Every Browser . . . . . . . . . . . . . . . . . .                        161
                    Understand Browser Differences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .           162
                           What Kind of Errors Can Occur? . . . . . . . . . . . . . . . . . . . . . . . . .              163
                           Detect What Type of Browser the User Is Running . . . . . . . . . . .                         164
                           Query the Document Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . .            169
                    Stick to Web Standards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   170
                    Write Cross-Browser Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       171

      CHAPTER 8     Manipulate Web Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .               179
                    Understand HTML Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        180
                           Request User Input Using an HTML Form . . . . . . . . . . . . . . . . .                       181
                           Process Form Input with Client-Side JavaScript . . . . . . . . . . . . .                      182
                           Process Form Input on a Web Server . . . . . . . . . . . . . . . . . . . . . .                183
                           Insert an HTML Form into a Web Page . . . . . . . . . . . . . . . . . . . .                   184
                    Retrieve and Set Form Control Values in JavaScript . . . . . . . . . . . . . . . .                   200
                           Access Form Values Using the forms Array . . . . . . . . . . . . . . . .                      200
                           Access Form Values Using the elements Array . . . . . . . . . . . . . .                       202
                           Access Form Values Using getElementById() . . . . . . . . . . . . . . .                       204
                           Access Form Values Using getElementsByName() . . . . . . . . . . .                            204
                           Access Form Values Using getElementsByTagName() . . . . . . . .                               205

      CHAPTER 9     Handle Browser Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .              207
                    Write JavaScript Event Handlers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        208
                          Handle User Interface Events . . . . . . . . . . . . . . . . . . . . . . . . . . . .           209
                          Handle Mouse Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        211
                          Handle Key Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      212
                          Handle HTML Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .           215
                    Handle Events Using the Event Property . . . . . . . . . . . . . . . . . . . . . . . .               218
                    Trigger Events in JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     219
                          Call the Method Associated with an Event . . . . . . . . . . . . . . . . .                     219
                          Use the fireEvent Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         220
                    Overcome Browser Incompatibility . . . . . . . . . . . . . . . . . . . . . . . . . . . .             220
Contents        xiii

CHAPTER 10   Communicate Between Browser Frames . . . . . . . . . . . . . . . . . . . . .                         223
             Learn the Basics of HTML Frames . . . . . . . . . . . . . . . . . . . . . . . . . . . . .            224
                    Create a Frameset in HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . .           225
                    Define and Name Frames in a Frameset . . . . . . . . . . . . . . . . . . . .                  233
             Call JavaScript Functions from Other Frames . . . . . . . . . . . . . . . . . . . .                  235
                    Access Another Frame Using JavaScript . . . . . . . . . . . . . . . . . . .                   236
                    Call a JavaScript Function Located in Another Frame . . . . . . . . .                         237
             Handle Synchronization Between Frames . . . . . . . . . . . . . . . . . . . . . . .                  239

CHAPTER 11   Interact with the Web Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . .                243
             Learn the Basics of the Document Object Model . . . . . . . . . . . . . . . . . .                    245
             Manipulate the Contents of a Web Page . . . . . . . . . . . . . . . . . . . . . . . . .              248
                    Dynamically Modify the Contents of a Web Page . . . . . . . . . . . .                         249
                    Change the Items in a Drop-Down List Box . . . . . . . . . . . . . . . .                      251
             Examine the Entire Browser Window . . . . . . . . . . . . . . . . . . . . . . . . . . .              252
             Retrieve Properties of the Web Browser Software . . . . . . . . . . . . . . . . .                    254
             Examine the Operating System’s Display Settings . . . . . . . . . . . . . . . . .                    256
             Access the Web Browser History List . . . . . . . . . . . . . . . . . . . . . . . . . . .            257
             Send the Browser to a New Location . . . . . . . . . . . . . . . . . . . . . . . . . . .             258

CHAPTER 12   Perform Simple Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .               259
             Learn the Basics of Cascading Style Sheets . . . . . . . . . . . . . . . . . . . . . .               260
                   Assign Style to Web Pages Using HTML Elements . . . . . . . . . .                              261
                   Assign Style to Web Pages Using Style Sheets . . . . . . . . . . . . . .                       264
                   Use Basic Style Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         268
                   Position Elements on a Web Page . . . . . . . . . . . . . . . . . . . . . . . .                268
                   Modify Styles Using JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . .             270
                   Understand Cross-Platform Issues . . . . . . . . . . . . . . . . . . . . . . . .               272
             Perform Basic Animation Using JavaScript . . . . . . . . . . . . . . . . . . . . . .                 274
                   Dynamically Load Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .            274
                   Make Content Move Around the Screen . . . . . . . . . . . . . . . . . . .                      276

PART III     Take JavaScript to the Next Level
CHAPTER 13   Debug JavaScript Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                281
             Understand the Possible Causes of Errors . . . . . . . . . . . . . . . . . . . . . . . .             282
                    Find the Source of an Error Message . . . . . . . . . . . . . . . . . . . . . .               284
                    Interpret Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        285
             Use a JavaScript Validator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   287
             Add Debugging Code to Your Programs . . . . . . . . . . . . . . . . . . . . . . . . .                287
             Use the JavaScript Console . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     290
             Use a JavaScript Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      291
xiv     How to Do Everything with JavaScript


      CHAPTER 14    Make Your Program Errorproof . . . . . . . . . . . . . . . . . . . . . . . . . . .                 295
                    Learn the Basics of Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     296
                    Catch Exceptions Using the try and catch Statements . . . . . . . . . . . . . .                    297
                          Understand Exception Bubbling . . . . . . . . . . . . . . . . . . . . . . . . . .            299
                          Use the IE Error Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      301
                          Use Netscape-Only catch Clauses . . . . . . . . . . . . . . . . . . . . . . . .              302
                          Use Nonstandard finally Clauses . . . . . . . . . . . . . . . . . . . . . . . . .            302
                    Create Exceptions Using the throw Statement . . . . . . . . . . . . . . . . . . . .                304
                    Design Programs That Are Easy to Debug from the Start . . . . . . . . . . .                        306
                          Avoid Unstructured Programming . . . . . . . . . . . . . . . . . . . . . . . .               307
                          Break Code into Manageable Chunks . . . . . . . . . . . . . . . . . . . . .                  307
                          Reuse Code Using Classes and Objects . . . . . . . . . . . . . . . . . . . .                 308
                    Test Your JavaScript Code Thoroughly . . . . . . . . . . . . . . . . . . . . . . . . . .           309
                          Create a Testing Harness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       309
                          Force Errors to Test Error-Handling Code . . . . . . . . . . . . . . . . . .                 311
                          Try Your Program in Many Different Environments . . . . . . . . . .                          312

      CHAPTER 15    Use JavaScript to Manage Browser Plug-Ins . . . . . . . . . . . . . . . . . .                      313
                    Insert Scriptable Objects into HTML Web Pages . . . . . . . . . . . . . . . . . .                  315
                    Include Sun Java Applets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   315
                           Connect to Java Applets Using JavaScript . . . . . . . . . . . . . . . . . .                319
                    Embed Movies and Music in Web Pages . . . . . . . . . . . . . . . . . . . . . . . .                321
                           Connect to Music and Media Objects Using JavaScript . . . . . . .                           322
                    Use the Microsoft Calendar Control in Your Web Pages . . . . . . . . . . . .                       324

      APPENDIX A    HTML 4.01 Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       327
      APPENDIX B    JavaScript Quick Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .             331

                    Index      ...................................................                                     335
Acknowledgments
   Programming today is a race between software engineers striving to build bigger and better
   idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the
   Universe is winning.
                                                                                 —Rich Cook

I very much appreciate the efforts of everyone who was involved in getting this book published. I
certainly don’t want to imagine what would have been created had I been left to my own devices.
I am extremely happy with how this book turned out, and I owe a great debt of gratitude to many
people for that:

   Megg Morin, my acquisitions editor at Osborne. Thank you for all your help in developing
   the concept and for giving the book the strong push in the right direction that it needed at
   the beginning.

   Leslie Tilley, my copy editor and project editor. Thank you, thank you, thank you. I really
   appreciate your hard work and attention to detail. You’re the primary reason this book turned
   out so well.

   Tana Allen, my acquisitions coordinator. Thanks for keeping the project on track.

   Madhu Prasher. Thanks for doing what you do so well. It’s always good to meet someone
   who loves her job.

   Warren Raquel, my technical editor. Thanks for your diligent efforts.

   Jawahara Saidullah, my agent at Waterside Productions. Thanks for getting me this gig and
   hopefully many more to come.

   And last but not least, my wife Liez’l. With you beside me, I can climb mountains and
   slay dragons.




                                                                                                    xv
This page intentionally left blank
Introduction
Netscape introduced JavaScript with great fanfare in December 1995 as an “open, cross-platform
object scripting language.” It was billed as the perfect complement to the much-anticipated
Java programming language, since the two languages can communicate with each other inside
a browser window.
    Today, almost 10 years later, JavaScript is ubiquitous across the Internet landscape. It is
estimated that 25 percent of web pages on the Internet today contain JavaScript code. Some
of them use that code to perform some very basic scripting effects, such as controlling mouse
rollovers and setting the browser status bar. Many of them contain complex dynamic menus
and automated forms. No other scripting language comes close to JavaScript’s domination of
the web browser environment.
    The key to JavaScript’s success has been its ease of use. For instance, a single JavaScript
statement can create an interesting browser effect, and a small handful of statements is all that’s
required for a completely interactive browser environment.
    You don’t even need any special tools to create these effects. A simple text editor, such as
Windows Notepad, is all that is required. If you can create HTML web pages, you have all the
tools you’ll need to get started.
    With the impending release of version 2.0, JavaScript will finally be usable side by side with
programming languages such as C++ and Visual Basic. For instance, Microsoft has included a
version of JavaScript 2.0, called JScript .NET, in its popular .NET programming environment.
JScript .NET can access almost all the .NET Framework classes and can be used to create Windows
Forms applications that run on your desktop. In fact, the next new word processor you use may
be coded entirely in JavaScript.

Who Should Read This Book
This book is designed to help anyone interested in adding elements of interactivity to their personal
web pages. Some experience with a PC is required, as we will not cover how to access the Internet
or how to use a web browser. You don’t have to be an HTML expert, although it will help if you
have some experience with that language. When encountering new HTML for the first time,
I will briefly explain what’s going on, but always in the context of JavaScript.




                                                                                                        xvii
xviii      How to Do Everything with JavaScript


        How This Book Is Organized
        How to Do Everything with JavaScript is organized into three main sections. Each section
        focuses on a different set of JavaScript skills:

            Part I Chapters 1–5 take you through the basics of JavaScript. This part covers the
            fundamental aspects of the programming languages, including statements, objects, and
            data types.

            Part II Chapters 6–12 show you how to integrate JavaScript into a web site. This part
            looks at using JavaScript with the Document Object Model, browser events, frames, and
            web forms.

            Part III Chapters 13–15 cover advanced JavaScript topics. This part deals with debugging
            a JavaScript program, errorproofing code, and communicating with other objects embedded
            in a web page.

            Often, the best way to learn a programming language like JavaScript is to play around with it.
        Don’t be afraid to try some of the JavaScript examples in the book yourself. Type them in and
        change them to something of your own design—you will gain a better understanding of how
        things work. Ask yourself, “What will happen if I do this instead?” Then go ahead and try it—
        nothing can go seriously wrong. The worst that can happen is that something you try doesn’t
        work. And that’s OK. Simply shrug your shoulders and try again.
Learn
Part I   JavaScript
         Basics
This page intentionally left blank
Prepare to
Chapter 1   Program in
            JavaScript
4      How to Do Everything with JavaScript


    How to...
        ■   Choose a development environment
        ■   Learn what JavaScript can and cannot do
        ■   Decide which version of JavaScript to use
        ■   Test JavaScript programs using HTML
        ■   Use the HTML <script> tag
        ■   Create a JavaScript template with Microsoft Notepad
        ■   Communicate with the user

    Behind every successful movie, there is a person behind the scenes who governs the interaction
    of actors, camera operators, writers, and other crew members. This is the director, and although
    you don’t usually see this person on screen, the quality of the movie rests on the success of his or
    her efforts.
        Well, JavaScript is the behind-the-scenes “director” of many Internet web sites. Its job is to
    govern the interaction of objects and events so that the two interact seamlessly with one another.
    Generally, the more complex the web site, the more it relies on JavaScript to direct. Lights!
    Camera! Browser! Action!
        Perhaps the first question that needs to be asked about JavaScript is, what is it? The simplest
    answer is that JavaScript is a simple programming language, used mainly to bring interactivity to
    web sites. It is often called a scripting language, hence the name, but it also has a nonscripting form.
        A script, in programming terminology, is a program that does not need to be compiled in
    order to run. Scripts tend to perform a specific task and then exit, and do not generally have a
    graphical user interface (GUI) to speak of. JavaScript, Perl, and VBScript are the most common
    scripting languages used by Internet web sites.


Learn the History of JavaScript
    JavaScript was born out of the need to coordinate HTML (Hypertext Markup Language) web
    pages with embedded content such as Java applets. But JavaScript is used for much more than
    that. It is often used to help users fill out online forms, provide web site navigation through
    dynamic menus, and power e-commerce shopping carts. In fact, it is said that 25 percent of all
    web sites today use JavaScript in one way or another.
             Although most (99.5 percent or more) of the web browser software in use today has
             built-in support for JavaScript, users can choose to turn off that support. When designing
             web sites for everybody to see on the Internet, it’s important to remember that some
             people won’t “see” JavaScript.

       Considering how rapidly other web-related technologies have been changing to incorporate
    new features, JavaScript has been fairly stable. It has taken JavaScript eight years to progress
CHAPTER 1: Prepare to Program in JavaScript                 5

from its initial 1.0 release to the next major version, 2.0. Some feel that this slow pace has been
both a blessing and a curse to the language.                                                                  1
      The blessing is that JavaScript support is fairly consistent across multiple browser makers
and version numbers. Web developers can implement one JavaScript program and not have to
worry too much about compatibility issues (other than avoiding certain incompatible coding
techniques). JavaScript has gained such widespread adoption mainly because developers can
trust that it will work.
      The curse is that while JavaScript has been standing still, other languages have emerged to
fill the technical void. It is far more common to see web sites that use Visual Basic Script (VBScript)
or Java Server Pages (JSP) as a server-side web scripting language instead of JavaScript. In fact,
a recent release of a popular web server software (iPlanet Web Server) has dropped JavaScript
support altogether. This could change, however, as JavaScript 2.0 catches developers’ attention.

The Origin of JavaScript
JavaScript made its first appearance in Netscape 2.0 in 1995. JavaScript was originally designed
to help integrate HTML pages with Java applets—Java applications embedded in web pages.
Developers quickly realized its true potential, though, and soon JavaScript was being used to add
interactivity to web sites—most of the time without the help of Java.
    Figure 1-1 shows Navigator 2.0, the first JavaScript-enabled web browser.

JavaScript Makes Its Way into Internet Explorer
Soon after Netscape Communications first introduced JavaScript in its Navigator 2.0 browser,
Microsoft realized the importance of incorporating this language into its Internet Explorer browser.
Since Netscape was not exactly going to mail Microsoft the source code, and even the language
specification was a well-guarded secret, Microsoft was forced to reverse engineer JavaScript to
create its own version. Microsoft named its version JScript, since Netscape owned the trademark
on the word JavaScript.
    Early versions of JScript did not perform certain functions in exactly the same way JavaScript
did, and so JavaScript incompatibility between the browsers was something developers often had to
take into account when scripting their web pages.

JavaScript Becomes an Official Standard
In the early days of the Web, cross-browser compatibility was a big issue—a lot bigger than it
is today. The two main browser companies were making changes to the HTML and JavaScript
languages to try to gain a competitive advantage over each other, causing massive headaches for
web developers trying to create web sites that supported both browsers. Luckily for us, both
companies relented.
     Netscape wisely turned JavaScript standardization over to the European Computer Manufacturers
Association (ECMA) in 1996. The ECMA concentrated on standardizing the core language, but
left other things (such as the JavaScript Document Object Model, or DOM) to the browser makers.
The result was that incompatibilities continued to exist between the browsers.
6      How to Do Everything with JavaScript




     FIGURE 1-1     What the Web looked like in 1995, through the eyes of Navigator 2.0


        The ECMA released their standardized scripting language known as ECMAScript in 1997.
    They updated the standard twice in the two years that followed, calling the updates Edition 2 and
    Edition 3. JavaScript 1.5 conforms to Edition 3 of the standard.

    Where JavaScript Is Today
    The ECMAScript Edition 4 standard will be the first update to be released in over four years.
    JavaScript 2.0 conforms to Edition 4 of the ECMAScript standard, and the difference between
    the two is extremely minor.
             The specification for JavaScript 2.0 can be found on the Mozilla.org web site:
             http://www.mozilla.org/js/language/js20/index.html.

        Today, Netscape’s JavaScript and Microsoft’s JScript conform to the ECMAScript standard,
    although each language still supports features that are not part of the standard.
CHAPTER 1: Prepare to Program in JavaScript                  7

    JavaScript
    Version       Date Released        Browsers                            Standards Compliance
                                                                                                                   1
    1.0           December 1995        Navigator 2, Internet Explorer 3    No
    1.1           April 1996           Navigator 3                         Partially, with ECMAScript 1
    1.2           December 1996        Navigator 4, Internet Explorer 4    Partially, with ECMAScript 1
    1.3           August 1998          Navigator 4.06, Internet            ECMAScript 1, ISO-16262
                                       Explorer 5
    1.4           October 1998         Version 1.4 did not appear in       ECMAScript 1, ISO-16262
                                       any web browser
    1.5           April 2000           Navigator 6 and 7, Internet         ECMAScript 3
                                       Explorer 5.5 and 6, Mozilla 1
    2.0           2003                                                     ECMAScript 4

    TABLE 1-1      Chronology of JavaScript Releases



      Table 1-1 contains a chronological list of JavaScript versions, including a short list of popular
   browsers that supported each one.
            The exact release date of JavaScript 2.0 and version numbers of the browsers that will
            support it were not yet determined at the time this was written.

Choose a Development Environment
   One of JavaScript’s biggest strengths is its support on many different platforms, often for different
   purposes. The most common type of JavaScript application today is one that runs inside a web
   browser, as a client-side script. JavaScript has long been supported as a web server-side language
   as well, in popular environments such as IIS and LiveWire. Recently, developers have had even
   more choices for using JavaScript in different environments.
       In this section, we will take a look at how JavaScript is used in each of these environments.
   None of them supports JavaScript 2.0 yet, but it is still important to look at the potential environments
   that will, since support will probably be introduced in the near future.
       Also in this section, we will discuss development environments for JavaScript developers. In
   the first few years of JavaScript’s existence, developers had to create their JavaScript programs
   using only a text editor, without the aid of integrated development environments (IDEs)—and
   many still do. But as HTML development tools evolved, many added development support for
   the world’s most popular scripting language. And today this support exists in all the big tools, as
   we will see later on in this section.

   Develop JavaScript-Enabled Web Pages
   Applications that are designed to run inside a browser are by far the most popular use for JavaScript.
   JavaScript was given very strong integration into the web browser environment through the DOM.
   Netscape introduced the original DOM in JavaScript 1.0.
8      How to Do Everything with JavaScript



                           The Client-Server Analogy

      In web-development terminology, the web browser and the computer it runs on are often
      called the client. Similarly, the web server software and the computer it runs on are called the
      server. Thus, the term client-side JavaScript refers to JavaScript programs that are embedded
      inside a web page and run on the client machine. JavaScript that runs on the server machine
      is referred to as server-side JavaScript.



       Fairly soon thereafter, control of the DOM was handed over to the World Wide Web
    Consortium (W3C), a standards organization. The DOM standard has evolved from dealing with
    how JavaScript interacts with a browser to dealing with standard ways to create, read, and
    modify HTML and XML documents.
             The W3C (http://www.w3.org) specializes in web standards, including HTML, XML,
             DOM, and Cascading Style Sheets (CSS). The various documents related to the DOM
             standards can be viewed at http://www.w3.org/DOM/DOMTR. It’s important to note
             that the original DOM (sometimes called Level 0) is not an official standard.

        JavaScript applications that are designed to run inside a browser are subject to a number of
    security restrictions. These applications generally do not have access to the user’s hard drive or
    any installed applications on the user’s computer. For users, this means a JavaScript application
    generally poses no security risk, as it cannot contain a virus or other malicious code.
        Netscape Navigator 4.0 (also known as Communicator) introduced the concept of signed
    scripts. A script that has been signed using a secure digital key can request additional privileges
    within the browser environment, such as the ability to send e-mail or read a file from the hard
    disk. Often the browser would prompt the user to ask if they will allow the script such privilege.
        The Mozilla web browser, and its cousin Navigator 6, changed the way signed scripts are
    handled in a way that is no longer compatible with Navigator 4. Microsoft Internet Explorer (IE)
    handles security completely differently (using trusted zones, for instance). As a result of these
    heterogeneous security solutions, there still is no standard way to write JavaScript applications
    that have expanded privileges. In practice, signed JavaScript is rarely used.
        Client-side application development is still very much one of JavaScript’s core strengths.
    Developers actually risk incompatibility with many operating systems and web browsers by
    choosing any language other than JavaScript for their client-side development!

    Create Server-Based Web Applications
    Although JavaScript dominates all other languages when it comes to web-client programming,
    that is not the case with server-side programming. JavaScript was one of the first server-side
CHAPTER 1: Prepare to Program in JavaScript                9

languages supported (back in 1996, when Netscape released its web server platform), but it was
unable to use that head start to its advantage. Perl quickly became a popular server-side scripting        1
tool, and several other languages have emerged (including VBScript in the ASP environment,
PHP, and JSP) as popular alternatives.
    One of the reasons server-side languages vary so much is that the server environment can be
controlled to a certain extent by web developers. In most cases, developers have very little control
over the browsers people use. So while the choice of client-side programming language is really
a “lowest common denominator” decision (which language is supported by the most browsers),
the choice on the server is whatever the developer wants to use.
    For some developers, getting to choose the programming language is like being a kid in a
candy store. There are many server-side programming languages to choose from, and no real
reason to choose one over another except personal preference.

Use JavaScript in a DOS or Windows Environment
For a long time now, Microsoft has been providing the Windows Script Host (WSH) tools as a
free add-on to Windows as a download from its web site. WSH includes the latest versions of
Microsoft’s two scripting languages—VBScript and JScript.
    With WSH, you can create a small program in JScript that could be run from the DOS
prompt. In fact, many virus writers took advantage of this ability (particularly with VBScript), so
these macros and small scripts are less frequently used these days. In fact, many mail systems
ban them altogether when sent as an attachment to e-mail, due to the potential for viruses.
         Windows Script, including the JScript and VBScript engines, can be downloaded free
         from http://msdn.microsoft.com/scripting.


    Developers can still create small programs using JScript for use in a Windows environment,
although it is rarely done. These JScript programs rely on the presence and enablement of the
Windows scripting environment, and in these security-conscious times, that is something which
you cannot rely on too heavily.

JavaScript Development Tools
One of JavaScript’s strengths is that expensive development tools are not usually required. With a
simple text editor such as Notepad, which is built into Windows, you can create relatively complex
JavaScript code with little trouble. Since it is an interpreted language inside the context of a web
browser, you don’t even need to buy a compiler.
         A compiler is a program that turns programming code into machine-ready form, often
         called a binary or an executable.
10      How to Do Everything with JavaScript


         But just because JavaScript can be edited in a simple text editor doesn’t mean that it should be.
     Development environments offer several key resources that often make development faster and
     easier, such as:

         ■   Predefined scripts that can be easily added to a web page
         ■   Integrated help, to quickly look up the syntax of a function
         ■   Automatic FTP uploads to a web server
         ■   Integrated debugging tools

         In this section, we will examine the top four HTML editors. Each of these editors has
     significant support for JavaScript development, including ready-to-use scripts, JavaScript
     editing tools, and embedded help.

     Microsoft FrontPage
     Microsoft has developed a popular HTML editor called FrontPage. FrontPage provides web
     developers with a number of JavaScript tools to assist in the creation of an interactive web site.
     FrontPage was once the undisputed leader in HTML and JavaScript development tools. Now a
     couple of other competitors in the field have taken a significant slice of the Microsoft market
     share—Macromedia and NetObjects.
          FrontPage still contains many useful features, including capabilities such as designing a web
     site’s hierarchy before creating any of the pages, configuring web site security, setting sitewide
     styles, and creating custom banner images. Figure 1-2 shows how FrontPage Explorer can be
     used to organize a web site by graphically linking pages together. Microsoft FrontPage also has
     a server-side component called FrontPage Server Extensions, which enables it to integrate well
     into Microsoft’s IIS web server.
          FrontPage can be purchased for $90 to $170, which makes it a very affordable tool for
     nonprofessional web site developers.
              Microsoft offers a free 30-day trial version of FrontPage 2002 for those who are
              interested in trying out the software. The trial CD can be ordered from
              http://www.microsoft.com/frontpage.

     Macromedia Dreamweaver MX
     Macromedia Dreamweaver MX is a very popular HTML and JavaScript editor in the professional
     web development crowd. It is packed with features, including the ability to edit most of the
     popular web server programming languages (like ASP, JSP, and PHP), provides several handy
     prebuilt JavaScript components, integrates well with databases, and conforms to new standards
     such as XHTML and XML. In short, it includes lots of goodies that professionals will find useful
     but that many home users might not require.
CHAPTER 1: Prepare to Program in JavaScript             11

                                                                                                       1




 FIGURE 1-2     Using FrontPage Explorer to organize a web site


    The power of the Dreamweaver MX environment is shown in Figure 1-3.
    Macromedia Dreamweaver MX retails for between $200 and $400, which makes it an ideal
tool for professional developers.
        You can download a free trial of Macromedia Dreamweaver MX for either Windows or
        Mac at http://www.macromedia.com/software/dreamweaver.

Macromedia HomeSite 5
Macromedia purchased Allaire Corporation and took over ownership of Allaire’s flagship product,
HomeSite. The most recent version is HomeSite 5, and Macromedia includes a free copy of it
with each copy of Dreamweaver it sells. HomeSite appeals to the home user because of its price,
although it lacks most of the sophisticated features of its sibling.
12      How to Do Everything with JavaScript




      FIGURE 1-3      Dreamweaver MX is an extraordinary working environment for the professional
                      web developer.

         For $29 to $99 users receive a well-liked HTML and JavaScript editor, which will manage
     their personal web site just fine. Users with large sites to manage or more than one developer
     might want to consider investing the extra money to get Dreamweaver instead.
              Macromedia offers a free trial version of HomeSite 5 for Windows at
              http://www.macromedia.com/software/homesite.

     Adobe GoLive
     Adobe is best known to most surfers on the Internet for its Acrobat software, which writes and
     reads documents in their popular Portable Document Format (PDF). However, Adobe is also a
     leader in graphics, digital video, and desktop publishing software with its Photoshop, Premiere,
     and PageMaker products.
         In fact, it is likely that all the other industry-leading tools and software packages the company
     produces overshadow their web publishing tool business. However, even though Adobe GoLive
CHAPTER 1: Prepare to Program in JavaScript             13

   might be trailing the pack in many respects, for developers who regularly work with Adobe’s
   graphics- and video-editing tools, GoLive may be an easy choice.                                         1
            As with other web authoring tools, you can download a trial copy of GoLive 6.0.
            GoLive is available for both Windows and Mac, and can be downloaded from Adobe’s
            web site at http://www.adobe.com/products/golive.

   NetObjects Fusion
   FrontPage, Dreamweaver, GoLive, and NetObjects Fusion make up the top four most popular
   web site development tools in use today. NetObjects, unfortunately, did not have sufficient cash
   or resources to stay in the race against such tough competitors. The company has been sold and
   the new owner, Website Pros, has been continuing development of the Fusion tool under the
   existing brand name.
       Fusion is priced competitively in the $70 to $150 range. It includes many interesting new
   features, such as integration with popular online payment services, JavaScript pop-up menus, and
   improved support for embedded multimedia. It was once a popular tool with developers, and may
   become so again under new guidance.
            A free trial of NetObjects Fusion 7 for Windows can be downloaded from the company’s
            web site at http://www.netobjects.com. The full version of the software can also be
            purchased and downloaded online.


Learn What JavaScript Can and Cannot Do
   Historically, JavaScript has differentiated itself from other languages in the following ways:

       ■   It is easy to develop for.
       ■   It interfaces well with other languages and environments.
       ■   No special tools or compilers are required.
       ■   It’s flexible.

       These properties made it particularly well suited for web development. Web pages can be
   made dynamic with as little as one line of JavaScript code, and often only a handful of lines are
   required to accomplish common tasks. DOM provides JavaScript access to the browser, the web
   page, and all the objects (Java, multimedia, etc.) embedded within it.
       Despite the significant improvements, JavaScript 2.0 was not designed as an all-purpose
   language. Specifically, it does not intend to challenge C, C++, or Java in areas where those
   languages currently dominate. Rather, JavaScript 2.0 tries to improve upon the strengths of the
   existing language, while also adding features that developers often like to use when developing
   large or complex code, namely:

       ■ The ability to write modular and object-oriented applications
       ■ Improved ability to interface with other programming languages
14      How to Do Everything with JavaScript


         ■ The ability to write scripts that can be compiled for faster performance
         ■ The ability to restrict the way functions and code are used
     The ECMA has actually designed JavaScript 2.0 with these goals in mind.

     Use JavaScript as a Client-Side Language
     One of the unique qualities of the core JavaScript specification is that it does not attempt to define
     how JavaScript interacts with its environment. There are no JavaScript methods or functions in
     this specification that define how to draw the user interface or how to write text to the screen.
     Likewise, there are no file input/output routines that allow the language access to the hard drive.
          That feature can be considered both a strength and a weakness. The flexibility given by this
     lack of a standard I/O interface has resulted in JavaScript’s use in many different environments
     (browsers, servers, stand-alone applications, mobile devices, etc.). This has allowed devices with
     different ways of storing data and different ways of displaying output to run JavaScript applications.
          The downside to this flexibility is that the same JavaScript application cannot be run in each
     environment without some alteration. While most web browsers have standardized on a document
     object model, some differences remain between the DOMs of various browser makers. For example, a
     JavaScript application designed to run in a web browser cannot be run on a web server without
     taking the server’s own object model into consideration.
          Today, JavaScript is practically the only scripting language used inside web pages. Even
     though a couple of alternatives exist (most notably VBScript), JavaScript was (and still is) the
     only scripting language supported by all the major browser manufacturers. It is the only scripting
     language worth learning for client-side development.

     Use JavaScript as a Server-Side Language
     JavaScript also gained some popularity as a web server programming language. Both Netscape
     Enterprise Server and Microsoft IIS (popular web servers of the mid-1990s) supported server-
     side JavaScript development. Netscape supported this through the LiveWire server-side language.
     Microsoft allowed JScript as one of the potential languages for ASP development.
          Unfortunately, Netscape Enterprise Server (now called iPlanet Web Server) no longer supports
     JavaScript on the server, starting with version 6. This might have something to do with the fact that
     iPlanet is part of Sun Microsystems, and Sun Microsystems prefers programmers to use Java.
          And although Microsoft’s ASP environment has been hugely successful, developers prefer to
     use VBScript when developing for that platform. With the introduction of Microsoft’s ASP .NET
     platform, VB .NET and C# have become the two languages developers use most.
          Microsoft did the JavaScript community a small favor when it included JScript .NET support
     in the Visual Studio .NET development environment. JScript .NET has access to all the classes
     of the .NET Framework, and was the first (albeit, extremely early) implementation supporting
     features of the ECMAScript Edition 4 proposal.
CHAPTER 1: Prepare to Program in JavaScript               15

       Although the ECMA has given JavaScript the ability to function as a full programming
   language, JavaScript is not necessarily suitable for every environment. You would probably not             1
   want to use JavaScript as a programming language for the following types of tasks:

       ■ Very large applications
       ■ Performance-critical applications
       ■ Device drivers and other low-level programs
   After all, we wouldn’t want to see all those C++ programmers out of a job, would we?


Decide Which Version of JavaScript to Use
   One decision that JavaScript developers must make early on in the development process is which
   version of the language they wish to support. Several factors go into this decision, such as:

       ■ The size and scope of the programming task at hand
       ■ The possibility of future enhancements to the program
       ■ The need for the program to easily interoperate with other programs written in different
           programming languages
       ■ The need to take advantage of new features only offered in JavaScript 2.0 (new built-in
           objects, for instance)
       ■ The version of JavaScript supported by your favorite development tool
       ■ The version of JavaScript supported by the vast majority of your intended audience
       By far the most important consideration would be the last one. There is no point placing
   JavaScript 2.0 inside web pages if a significant amount of your intended audience still uses
   browsers that don’t support it. Of course, if your program will reside only on the server (a
   server-side program), all that matters is the version supported by the server.
       It is also important to remember one of the fundamental rules of computer programming:
   never write more code than is absolutely necessary for a task. So if your JavaScript program is a
   three-line script that converts degrees Celsius to degrees Fahrenheit, there is no need to create
   packages and classes in JavaScript 2.0 syntax (as discussed in Chapter 5). You may want to do it
   for other reasons, including future extensibility of your program. But this is also a case of if it
   ain’t broke…
       So as a general rule, be very cautious about developing in client-side JavaScript 2.0 code if
   your intended audience is likely to be running a wide variety of web browsers. Otherwise, if you
   know for certain what the minimum browser version will be or are developing in a server or
   embedded environment, feel free to use the new features and improvements in JavaScript 2.0 to
   your heart’s content!
16      How to Do Everything with JavaScript


Test JavaScript Programs Using HTML
     Before jumping into the fundamentals of JavaScript, we need to set up a way to test our code.
     The easiest way to test a JavaScript program is by putting it inside an HTML page and loading
     it in a JavaScript-enabled browser.
          To run any of the code samples in this book using this HTML method, you will need a web
     browser. I recommend using IE 5 or Navigator 4 or later, as some examples won’t work with
     earlier versions.
          If you would like to upgrade the browser on your computer to a more recent version, you can
     visit Microsoft’s IE web site at http://www.microsoft.com/windows/ie, or Netscape Browser
     Central at http://channels.netscape.com/ns/browsers.

     Create a JavaScript Template
     The <script> tag is the HTML element used to signify JavaScript code. It’s a good idea to create
     this file as a template using Notepad (or your favorite web development tool) and save it on your
     hard drive. That way it will be much easier to start creating JavaScript-powered web pages using
     this HTML code as a base.
          Here’s how to create the template in Notepad:

         1. In Windows, click the Start menu button.
        2. Select Run from the pop-up menu.
        3. Type in notepad as shown here, and press ENTER.




        4. In Notepad, enter the following HTML code:
             <html>
                 <head>
                     <title>JavaScript sample code</title>
                 </head>
                 <body>
                     <h1>My Sample Code</h1>
                     <script language="JavaScript" type="text/javascript">
CHAPTER 1: Prepare to Program in JavaScript            17

               <!-- // Begin
                   // NOTE:: Replace this line with JavaScript code                                  1
               // End -->
               </script>
           </body>
       </html>

   5. Select the File menu, and choose Save As.
   6. Navigate to the desired location on your hard drive. The My Documents folder is
      commonly used, but you can also choose to save it to any directory of your choice.
        We will use this HTML file to run the JavaScript code samples throughout the book, so
        put it someplace handy.

    7. Give the HTML file a name ending in .htm such as JSTemplate.htm.




   8. Close Notepad.
   9. From your Windows desktop, choose My Computer. This will bring up Windows Explorer,
      which allows you to navigate to the directory where you saved your HTML file.
  10. Double-click the HTML file. A web browser (usually Microsoft Internet Explorer) will
      open your HTML document.
  11. You should see the words “My Sample Code” in large letters.
  12. Close the browser window when you are finished with it.

   Figure 1-4 shows how the HTML template looks in the browser. This is the most basic
example of a <script> tag in an HTML page.
18     How to Do Everything with JavaScript




      FIGURE 1-4     A simple HTML document containing a <script> tag that does nothing



     Understand the JavaScript Template
     Remember that HTML documents are divided into two distinct pieces: the header section and the
     body. HTML documents always start with the <html> tag and end with the </html> closing tag.
     Similarly, the HTML header section is delimited with the <head> and </head> tags, as so:
          <head>
              <title>JavaScript sample code</title>
          </head>

         Generally, the HTML markup inside the header section is used to describe the main content
     that appears in the body section. Most commonly, the header section contains:

        ■ A mandatory title for the document (<title>)
        ■ Style sheet definitions (<style> and <link>)
CHAPTER 1: Prepare to Program in JavaScript              19

       ■ Meta data, such as search keywords (<meta>)
       ■ JavaScript functions (<script>)
                                                                                                             1
       The bulk of the HTML document is inside the body section, delimited by <body> and
   </body> tags. In this section you would find text, images, forms, and embedded content.
   JavaScript can also be used in this section to output dynamic text to the screen. Our template’s
   body section looked like this:
        <body>
            <h1>My Sample Code</h1>
            <script language="JavaScript" type="text/javascript">
            <!-- // Begin
                // NOTE:: Replace this line with JavaScript code
            // End -->
            </script>
        </body>

        Our body section starts and ends with the mandatory <body> and </body> tags. The <h1>
   and </h1> tags indicate header text. <h1> is the predefined header with the largest font. The
   <h2>, <h3>, <h4>, <h5>, and <h6> tags indicate headers with decreasing font sizes.
        I have included a <script> element inside the body section for later use. I’ve included two
   attributes with this tag, language and type. The language attribute was the original way to
   indicate what scripting language was used inside the tags. Although recent versions of HTML
   (and XHTML, its successor) have phased out the use of this attribute, it is still quite common to
   use it. The type attribute is what is now recommended to indicate the scripting language in use.
        The template contains three lines inside the <script> section:
              <!-- // Begin
                  // NOTE:: Replace this line with JavaScript code
              // End -->

        All three of these lines are comments. In web programming, a comment is one or more
   lines of text that is ignored by the browser when interpreting the code. Programmers often use
   comments to make a program easier for humans to read, but in the preceding code, the first and
   last lines are used to stop browsers that don’t support JavaScript from displaying the code. As
   time goes on, this technique becomes less and less important. But it is still quite prevalent, and
   there is really no reason not to include it. The <!-- and --> are markers for the start and end of
   HTML comments. JavaScript comments are marked with double slashes (//), which is why the
   browser will ignore the second line as well.


Communicate with the User
   Many JavaScript programs perform their tasks quietly. A web page may use JavaScript to verify
   that all the fields on a form have been completed in the proper manner. When they are complete,
20      How to Do Everything with JavaScript


     the JavaScript program allows the form to be submitted to the web server for further processing.
     But if one of the form fields has not been filled out properly, JavaScript should, ideally, inform
     the user so that they can correct the problem and submit the form again.
         There are generally two ways to bring an error like this to the user’s attention. The first is to
     take advantage of a JavaScript alert box, which requires the user to click an OK button in order
     for processing to continue. This is considered a slightly intrusive technique that ensures the user
     reads and acknowledges the error message.
         The other way is to write an informative message inside the web page directly. This is obviously a
     less intrusive technique, although you must be sure that the user does not accidentally overlook
     the message.
         In this section, we will examine how to communicate with the user using both methods, as
     each will be important before we move on to the next chapter.

     Display an Alert Message
     JavaScript provides three types of pop-up dialog boxes for use in your applications:

         ■ An alert box
         ■ A confirm box
         ■ A user-input prompt box
         Basic alert messages are displayed using the built-in alert function:
     alert ("This message will be displayed to the browser");

         You can place any text string or expression inside the parentheses. The dialog box displayed
     looks like this in Internet Explorer.




         Netscape Navigator displays a similar message box.
CHAPTER 1: Prepare to Program in JavaScript                21

    A confirm box acts in much the same way as an alert box, except it displays both OK and
Cancel buttons to the user. The confirm box tells the program which button the user chose,                   1
allowing two different outcomes.
result = confirm ("Would you like a piece of chocolate cake?");

    The result variable will contain true if the user selects the OK button, or false otherwise. This
is how the confirm box appears in Internet Explorer.




    Finally, the user-input prompt box allows the program to ask for a typed response to a
message. This is rarely used on Internet web pages, as HTML web forms are a more commonly
accepted way to retrieve user input.
firstname = prompt ("What is your first name?",
    "Enter name here");

    The result of this JavaScript code is shown here.




Write Text to the Browser Window
Many of the examples in this book will use the document.write() function to print text into the
web browser window. This can be used for more than just error reporting. In fact, it is quite
common to see web sites using document.write() to support dynamic functions such as
navigation, user help, banner ad rotation, and more.
document.write ("<b>This text goes right into the browser</b>")
22      How to Do Everything with JavaScript


        Notice how you can include HTML tags inside the document.write() function and the
     browser will process those tags. By adding a few document.write() statements into our HTML
     template, we can create a web page with a bit more content.
     <html>
         <head>
             <title>JavaScript sample code</title>
         </head>
         <body>
             <h1>Hamlet, by Bill Shakespeare</h1>
             <script language="JavaScript" type="text/javascript">
             <!-- // Begin
                 // NOTE:: Replace this line with JavaScript code
                 document.write
                     ("To be, or not to be: that is the question:<br>");
                 document.write
                     ("Whether 'tis nobler in the mind to suffer<br>");
                 document.write
                     ("The slings and arrows of outrageous fortune,<br>");
                 document.write
                     ("Or to take arms against a sea of troubles,<br>");
                 document.write
                     ("And by opposing end them.<br>");
             // End -->
             </script>
         </body>
     </html>

          As you can see in Figure 1-5, our document.write() statements were output to the screen just
     as if we had entered them directly in HTML. This technique becomes more useful when we get
     into the next chapter, when we learn about variables, functions, and statements.
          Now that we have covered the boring stuff—the history of the language, and what it is used
     for—we are ready to jump into a bit of real programming. The next chapter starts off by covering
     the basics of JavaScript, to get you ready to start coding on your own.


Learn More about Topics Discussed in this Chapter
     There are several good books available to learn more about HTML and Java, namely:

        ■    How to Do Everything with HTML, by James Pence (McGraw-Hill/Osborne, 2001)
        ■    HTML: A Beginner’s Guide, 2nd edition, by Wendy Willard (Osborne, 2002)
        ■    Java 2: A Beginner’s Guide, by Herbert Schildt (Osborne, 2000)
        ■    Learn to Program with Java, by John Smiley (Osborne, 2001)
CHAPTER 1: Prepare to Program in JavaScript   23

                                                                                           1




FIGURE 1-5    Hamlet’s famous soliloquy, as delivered by JavaScript


  In addition, you may want to check out some of the following web sites:

  ■   DevGuru: http://www.devguru.com
  ■   W3 Schools: http://www.w3schools.com/html
  ■   Sun Microsystems’ Java home page: http://java.sun.com
  ■   JavaRanch: http://www.javaranch.com
This page intentionally left blank
Learn JavaScript
Chapter 2   Fundamentals
26      How to Do Everything with JavaScript


     How to...
         ■   Define variables
         ■   Define constants
         ■   Understand program flow
         ■   Execute code conditionally
         ■   Repeat statements using loops
         ■   Comment your code
         ■   Set a default object
         ■   Handle errors
         ■   Understand the basics of expressions
         ■   Organize your code into functions
         ■   Use the improvements in JavaScript 2.0 to create more powerful functions

     JavaScript is extremely dependent on other technologies for help. In fact, if you tried to write a
     program in JavaScript that didn’t rely on anything outside of the official JavaScript specification,
     your program would not be able to do very much. JavaScript relies on external components for
     communication with the outside world, such as writing to a screen, retrieving data from a web
     form, and receiving notification of browser events.
         In this chapter, we will examine JavaScript’s fundamentals. We will learn the basics of writing
     a program by learning about statements, variables, and functions—the three basic building blocks
     of any program.


Understand Basic Terminology
     Like practitioners of other specialties, computer programmers have developed their own lingo
     over the years. Ordinary English words such as variable, function, and string have been given
     computer-related meanings. Table 2-1 lists some of the programming terms you will encounter
     in this chapter and throughout the book.


Store Data in Variables
     When it gets right down to it, there are only three places to store information in modern computing:
     the hard disk, a database, or memory. Sure, there are other data-storage media, such as floppy
     disks, CDs, Zip disks, and backup tapes upon which information can be saved, but the devices
     these media require are much slower than a hard drive—sometimes taking 100 times as long
     (or more) to record the same data. So application programmers cannot—and should not—generally
     rely on any of these media when storing information.
CHAPTER 2: Learn JavaScript Fundamentals                      27

 The programming term...   Refers to...
 statement                 One line of programming code; statements are often separated by
                           semicolons (;) in JavaScript.
 variable                  A named location for storing values that can be changed during program
                                                                                                                   2
                           execution.
 constant                  A named location for storing values that cannot be changed during program
                           execution.
 function                  A named set of statements that perform some operation and can optionally
                           return a single value.
 keyword                   A word that has a predefined meaning in JavaScript, and cannot be used for
                           any other purpose.
 operator                  Typically a symbol (such as +, -, *, or / ) that takes one or more values
                           (called operands) and returns a result.
 expression                A combination of keywords, operators, variables, and/or functions from
                           which a result can be calculated.
 string                    A sequence of 0 or more letters, numbers, or other text characters; strings
                           are typically enclosed in quotation marks, as in “this is a string”.
 Boolean                   A value or expression that evaluates to either true or false.
 literal                   A Boolean, number, or string that is written directly in the code; for instance,
                           the expression ((3+2)/total) contains two numeric literals, 3 and 2.
 value                     A number, Boolean, string, or object.
 TABLE 2-1     Common JavaScript Programming Terminology



    On the hard disk, information is stored in the form of files. In a database, information is
stored as records. But in memory, program data is stored and retrieved using variables. Variables
are named sections of memory.

Define Variables
In JavaScript 1.5, variables are declared using the var keyword:
var counter;

    This code tells JavaScript that we intend to store information in a variable we’ll refer to as
“counter.” Variables defined in such a way can contain any type of information: numbers, strings,
Booleans (true and false), or objects. For convenience, you could assign the variable an initial
value like so:
var counter = 5;

We have assigned the variable named counter an initial value of 5.
28      How to Do Everything with JavaScript


          JavaScript 2.0 has introduced the concept of data types into JavaScript programming. Before
     this release of the language, programmers could not predefine the types of data that a variable
     could contain—all JavaScript variables could be assigned any type of data.
          But with this important new release of the language, we can now restrict variables to certain
     types of data: integers, for example, or strings. Attempting to assign data that does not belong to
     the variable’s predefined data type would result in an error. Data types are defined as follows:
     var counter : Integer;

         The counter variable defined here belongs to the Integer data type. Thus, that variable can
     never contain anything other than whole numbers. (We examine all the data types available in
     JavaScript 2.0 in Chapter 3.)

     Define Constants
     Variables are called variables for a reason: a program is free to change the value stored inside
     the variable at any time. Constants are similar to variables, but once a value has been assigned,
     constants cannot be changed.
              Constants are only currently supported by Netscape 6 and later, or the Mozilla web
              browser. Microsoft IE has not yet incorporated support, so the use of constants should
              be limited to uses when you are absolutely sure they are safe.

         Constants were introduced into JavaScript starting with version 1.5, so early versions of the
     language do not support them. But other programming languages (most notably C) use constants
     very effectively, and they can be useful in your JavaScript programming as well.
         Constants are defined using the const keyword:
     const ERR_INVALID_USERID;

         In the preceding code, I created a constant named ERR_INVALID_USERID. Notice how I
     capitalized the name. It is not mandatory, but it is a programming convention often used in C, so
     you will sometimes see constants capitalized in JavaScript as well.




                            JavaScript Can Store Some
                            Mighty Big Numbers
       Integers in JavaScript 2.0 are double-precision floating-point numbers, which allows them to
       contain values in the range of approximately +/–100 unodecillion—1 with 38 zeros after it.
CHAPTER 2: Learn JavaScript Fundamentals                  29

       Once a value has been set, a constant cannot be altered.
   const ERR_INVALID_USERID = 300;
   ERR_INVALID_USERID = 50;     // This will cause an error!
                                                                                                                   2
       Constants are often used to give human-readable names to error codes and other numbers
   that “mean something.” It is much easier for humans to read the following code than if it just
   used the error numbers directly:
   switch (returncode) {
       case ERR_INVALID_USERID:
           // do something
       case ERR_INVALID_PASSWORD:
           // do something else
       case ERR_INVALID_DOMAIN_NAME:
           // etc.
   }

   Like variables, constants can be assigned a data type in JavaScript 2.0.




Understand Program Flow
   The bulk of this chapter is devoted to learning the fundamentals of the JavaScript programming
   language, statements, and functions. But before we get into that, it is important to spend a few
   moments examining program flow.
       When I talk about program flow, I am talking about the order in which JavaScript executes a
   program’s code. Assuming you have a program that is five lines long, JavaScript will always start
   by executing the first line of code. In theory, the second line is executed next, then the third, and
   so on until it reaches the last line (line 5 in our example). Figure 2-1 illustrates this.
       In reality, that is an extreme oversimplification of what goes on. The next line to be executed
   depends on the task that the current line asked JavaScript to perform. If the current line calls a
   function, all the code inside the function will be executed first, before JavaScript continues with
   the next line. If the current line contains a loop, the same group of lines will be executed repeatedly.
   And if the current line declares a new function to be defined, JavaScript will read the function
   into memory without executing any of it (until it is called elsewhere in the program).




    FIGURE 2-1       JavaScript executes a program from start to finish in order.
30      How to Do Everything with JavaScript




      FIGURE 2-2      JavaScript will stop executing a program in order to execute the contents of
                      a function.

          But, for the most part, it is still fair to characterize a program as being executed in order from
     start to finish. Figure 2-2 shows how the program flow jumps around depending on the code itself.
     We can see that all the code inside a function is executed before the program continues where it
     left off.


Control Program Flow with Statements
     The HTML template we defined in Chapter 1 (see “Create a JavaScript Template”) didn’t really
     do anything useful, other than displaying some header text. The only way we can get our JavaScript
     program to do anything is to add some statements.
         A statement is the basic action item in any program code. In effect, each statement is telling
     the computer to do something. Statements can be divided up into five categories:

         ■   Conditional
         ■   Loops
         ■   Object manipulation
         ■   Comments
         ■   Expressions

          The typical JavaScript program uses statements that fall into each of those categories. Often,
     statements inside a program are organized into functions and classes as well, to make the program
     easier to manage and more efficient to develop. We will examine functions in more detail later in
     this chapter, and classes in Chapter 5.

     Execute Code Conditionally
     Computer programs almost always contain conditional statements. There are two conditional
     statements in JavaScript: if and switch. The if statement allows the program to choose one of
     two alternatives, based on some predefined factor. In real life, you might decide that, if it were
     not raining, you would like to go to the baseball game. Of course, if it were raining, you would
     then decide to stay home. You can make that same decision in a JavaScript program with the
     following code:
CHAPTER 2: Learn JavaScript Fundamentals           31

function stay_or_go (raining) {
     if (raining == false) {
          return "Go to baseball game!";
     } else {                                                                                                2
          return "Got to stay home today.";
     }
}

    So you see, conditional statements give programs a choice between two or more alternatives
in much the same way we make those choices in real life.

The if Statement
Depending on how you use it, the if statement can be very simple or very complex. The if
statement can be used in the following ways.

 Syntax                                        Use
 if (expression) {statements;}                 If expression evaluates to true, execute statements.
 if (expression) {statements1;}                If expression evaluates to true, execute statements1.
 else {statements2;}                           Otherwise, execute statements2.
 if (expression1) {statements1;}               If expression1 evaluates to true, execute statements1.
 else if (expression2) {statements2;}          Otherwise, if expression2 evaluates to true, execute
 else {statements3;}                           statements2. Otherwise, execute statements3.


     The if statement evaluates an expression to determine which set of statements to execute,
if any. Since the if statement expects a Boolean expression (one that evaluates to either true
or false), it will try to convert expressions of other data types to either true or false.
             JavaScript makes certain assumptions when converting from other data types to Boolean.
             The strings “true” and “false” evaluate to the Booleans true and false. The integers 1
             and 0 are also converted to the Booleans true and false, respectively.

    In computer programming terminology, an expression is a piece of code that, when
evaluated, returns a value. In JavaScript, the following can be used as expressions.

 Expression                                     Example
 A variable                                     if ( x ) {statements;}
 A function that returns a value                if ( myfunc(x) ) {statements;}
 A literal                                      if ( true ) {statements;}
 Variables, functions, and literals combined    if ( a > 5 ) {statements;}
 using operators
32      How to Do Everything with JavaScript


         Even the same if statement can be written in at least four different ways, all of which are valid:

         ■ if (expression) statement;
         ■ if (expression)
                     statement;
         ■ if (expression) {statements;}
         ■ if (expression) {
                     statements;
             }

         The various preceding forms of the if statement are technically equivalent. The first two can
     include only one statement. Notice that the third and fourth forms use curly brackets, { and }, to
     enclose the statements. Statements enclosed in curly brackets are generally treated as a group,
     called a statement block.
         The if statement can include an optional else clause, to decide between one of two alternatives.
     This form of the statement is sometimes called the if-else statement:
     if (expression) {statements1;}
     else {statements2;}

          The else clause allows you to specify a statement or group of statements that will be executed
     if the expression does not evaluate to true. Only one else clause is allowed in any if statement.
     Again, the statement can be used with or without the curly brackets.
          Finally, the if statement can be used to choose between one of three or more alternatives.
     With the introduction of the else-if clause, the if statement can include multiple expressions that
     will each be evaluated until either one of them evaluates to true or the else clause is encountered.
     Multiple else-if clauses can be included, but keep in mind that the else-if clause must always
     precede any else clause.
     if (expression) {
          statements;
     } else if (expression) {
          statements;
     } else {
          statements;
     }

              If you find yourself using more than two or three else-if clauses in a single if statement,
              you may want to consider using a switch statement instead, as described in the
              following section.
CHAPTER 2: Learn JavaScript Fundamentals               33

The switch Statement
The switch statement has a very similar role to the if statement in JavaScript. The switch
statement evaluates an expression and compares the value to one or more case clauses. If you
need to compare a variable against more than two or three values, the switch statement is the             2
most efficient way.
    The following code shows how the switch statement is typically used in JavaScript programming.
In this example, our program will try to determine the name of a country based on its official
three-letter ISO (International Organization for Standardization) country code.
// ISO official country codes
switch (countrycode) {
    case "ALB":
        countrystring="Albania";
        break;
    case "DZA":
        countrystring="Algeria";
        break;
    case "ASM":
        countrystring="American Samoa";
        break;
    case "AND":
        countrystring="Andorra";
        break;
    case "AGO":
        countrystring="Angola";
        break;

     // etc.

     case "", "?":
     default:
         countrystring="Unknown code";
}

    The same code could be written using if-else-if statements, but that would be both inefficient
and harder to read. Let’s take a look at the preceding code, to see what is going on.
    The first line of the statement uses the switch keyword, followed by the expression that needs
to be evaluated.
switch (countrycode) {
34      How to Do Everything with JavaScript


     In this example, countrycode is a variable that happens to contain a string.
         The next three lines in the switch statement contain the first case clause.
          case "ALB":
              countrystring="Albania";
              break;

         The case clause indicates that we would like to compare the value of countrycode
     (the expression the switch statement is acting on) with the string "ALB". If there is an exact
     match, JavaScript will execute the next two lines:

         ■ Set the countrystring variable to "Albania".
         ■ Exit the switch statement at the break statement.
         Of course, if the value of countrycode does not match the string "ALB", the countrystring
     variable is not set and the switch statement continues.
         The next case clause compares the expression against a new value:
          case "DZA":
              countrystring="Algeria";
              break;

         The switch statement evaluates each of the case statements in order, until it finds one that
     matches. It then executes the code that immediately follows the case clause until the first break
     statement is encountered.
              Once a match is found, JavaScript will execute all the code that follows, even inside
              other case clauses, until the break statement is encountered.

         In JavaScript, the switch statement has a special kind of case clause known as the default
     clause. The default clause executes only if JavaScript was unable to match the expression with
     any of the previous clauses. The default clause must always be the last clause in a switch statement.
          case "", "?":
          default:
              countrystring="Unknown code";

         Our example includes an empty case clause, trying to match against the empty string ("") or
     a question mark (?). You can provide multiple values to match against the expression in a single
     case clause, as long as they are separated with commas. If the expression matches our empty case,
     the code inside the default clause will be executed, since there is no break statement to stop it.

     Repeat Statements Using Loops
     Loops are convenient statements for two purposes:

         ■ When you want to repeat a set of statements a specific number of times
         ■ When you want to repeat a set of statements an unknown number of times
CHAPTER 2: Learn JavaScript Fundamentals                35

    There are four loop statements in JavaScript: while, do-while, for, and for-in. JavaScript also
provides the break and continue statements to give programmers more control over how loops
execute. In this section, we will examine each of the statements related to looping and see how
they can be applied in our programs.                                                                         2
The while Loop
The while loop evaluates an expression before executing a group of statements. It will execute
the statements repeatedly, until the expression no longer evaluates to true.
while (expression) {
    statements;
}

    JavaScript processes the while loop in the following manner. The expression is first evaluated,
and its value is interpreted as a Boolean (true or false) value. If the expression evaluates to true,
the statements contained inside the curly brackets are executed once. The expression is then
evaluated again, and if it still evaluates to true, the statements are executed a second time. This
continues indefinitely until the expression evaluates to false.
    A common programming trap is the infinite loop. An infinite loop is a loop statement that
never ends, and this is most like to happen with the while statement. Most browsers will inform
the user when a script takes too long to execute, which allows them to force an infinite loop to end.




    To avoid infinite loops, it is common programming practice to make sure the expression
always has a chance to evaluate to false. The following while statement is guaranteed not to
cause an infinite loop:
var counter = 1;

while (counter < 101) {
    document.write ("This is line number " + counter + "<br>n");
    counter++;
}

    This code will execute exactly 100 times. We know this because the counter variable starts
off at 1, and after every successive while loop iteration, it is incremented by one. (We will learn
about operators, such as the ++ operator, later in this chapter. In this code, the ++ operator takes
36      How to Do Everything with JavaScript


     the counter variable and increments it by 1.) When it reaches 101, the loop will exit, since
     “counter < 101” would evaluate to false.
         If we paste this while loop into our HTML template from Chapter 1, we get the following
     HTML code:
     <html>
         <head>
             <title>JavaScript sample code</title>
         </head>
         <body>
             <h1>My Sample Code</h1>
             <script language="JavaScript" type="text/javascript">
             <!-- // Begin
             var counter = 1;

             while (counter < 101) {
                 document.write ("This is line number " + counter + "<br>n");
                 counter++;
             }
             // End -->
             </script>
         </body>
     </html>

         Loading this HTML code into a web browser gives you something similar to Figure 2-3. The
     browser window has been scrolled all the way to the bottom to demonstrate exactly how many
     lines were printed.




      FIGURE 2-3     The while loop prints exactly 100 lines.
CHAPTER 2: Learn JavaScript Fundamentals                37

The do-while Loop
The do-while loop acts exactly like the while loop, with one exception. The expression is
evaluated after the end of each iteration in a do-while loop. That means the loop is guaranteed
to execute at least one time. A while loop evaluates its expression prior to each iteration, which           2
means that it’s possible that the contents of the loop will never be executed.
do {
    statements;
} while (expression);

      Even though the expression is evaluated after each iteration of the loop, the following loop
still executes exactly 100 times. So the only iteration that is affected by choosing do-while instead
of a while loop is the first run through the loop.
var counter = 1;

do {
    document.write ("This is line number " + counter + "<br>n");
    counter++;
} while (counter < 101);

    You can look at the while and do-while loops as two versions of the same statement.
Everything you can do with do-while, you can do with while. As a result, do-while loops
are less commonly seen “in the wild” than while loops.

The for Loop
In discussing while loops just now, we used the following example:
var counter = 1;

while (counter < 101) {
    document.write ("This is line number " + counter + "<br>n");
    counter++;
}

    That while loop can be rewritten using a for loop. In fact, this type of loop (one that employs
a counter variable) is better suited to a for loop.
for (var counter = 1; counter < 101; counter++) {
    document.write ("This is line number " + counter + "<br>n");
}
38      How to Do Everything with JavaScript


          As you can see, the for loop version is a more efficient way of looping a predefined number
     of times. The for loop syntax has four components:
     for (initializer; expression; incrementor) {
         statements;
     }

         The initializer section is traditionally used to define variables and give them an initial value.
     In our example, we defined a new variable named counter and set it to the value 1. The JavaScript
     code contained in the initializer section gets executed only once—before the loop begins.
         The expression is evaluated before every loop. Whether or not the statements are executed
     depends on the Boolean results of this expression.
         The incrementor section contains code that gets executed following each run through the
     loop. Traditionally, this is where any counters are incremented or decremented. In our example,
     we add 1 to the counter variable using this section.
         Each of these sections is optional. If the variables being used are already defined and have a
     value set, the initializer can be empty. But don’t forget that the semicolon in between is mandatory.
     In fact, the following code is an infinite loop using a for statement:
     for (;;) {
         // do nothing
     };

              Although this is another example of an infinite loop (which is generally a bad idea
              in programming) this loop is a valid technique if you have code inside the loop that
              executes a break statement when a certain condition is met.

     The for-in Loop
     I only want to talk about the for-in loop here for the sake of context. You will see a proper
     discussion of it in Chapter 5, when we talk about classes and objects.
          For now, think of an object as a tool chest that contains a bunch of tools. The for-in loop will
     extract each tool individually from that tool chest, and allow you to examine and manipulate it on
     its own.
          In the following code, we create a simple object (compatible with JavaScript 1.5) and retrieve
     each of its properties using the for-in loop.
     <html>
         <head>
             <title>JavaScript Test</title>
CHAPTER 2: Learn JavaScript Fundamentals              39

     </head>
     <body>
         <h1>for-in Loop</h1>
         <script language="JavaScript" type="text/javascript">                                            2
         <!-- // Begin
             // We define the tool chest object
             var toolchest = {tool1:"Wrench",
                 tool2:"Hammer",
                 tool3:"Cordless drill",
                 tool4:"Needlenose pliers"};

                // for-in iterates over its properties
                for (var tool in toolchest) {
                    document.write(toolchest[tool] + "<BR>");
                }

        // End -->
        </script>
    </body>
</html>

    This program creates an object named toolchest. The object is created using an object literal,
as discussed in Chapter 5.
// We define the tool chest object
var toolchest = {tool1:"Wrench",
                 tool2:"Hammer",
                 tool3:"Cordless drill",
                 tool4:"Needlenose pliers"};

    The code that we’re interested in is the for-in loop:
// for-in iterates over its properties
for (var tool in toolchest) {
    document.write(toolchest[tool] + "<BR>");
}
40       How to Do Everything with JavaScript


         This code picks loops through the contents of the toolchest object—tool1, tool2, tool3, and
     tool4. When executed, the program outputs the value of each property, like so.




     The break and continue Statements
     We already saw the break statement in action when we looked at the switch statement. When
     JavaScript encounters a break statement inside a switch, it stops executing code inside the
     switch and continues execution at the first statement that follows it.
         The break statement works in a similar fashion with loops. When JavaScript encounters a
     break statement, it stops executing the code inside the loop and starts again at the first statement
     outside the loop. The break statement is not valid outside a loop or a switch statement.
         The continue statement causes JavaScript to stop executing code inside the loop as well, but
     execution continues at the next iteration of the loop instead. In effect, the break statement says,
     “Exit the loop,” while the continue statement says, “Skip this iteration and move on to the next.”
     The continue statement is also not valid outside of a loop.
     var Fahrenheit, Celsius;
     for (Celsius = -70; Celsius <= 70; Celsius += 10) {
         Fahrenheit = (Celsius * 9/5) + 32;
         document.write ("Celsius = " + Celsius);
         document.write (", Fahrenheit = " + Fahrenheit + "<br>");

          if (Fahrenheit > 100) {
              // It's getting hot in here
              break;
          }
     }
CHAPTER 2: Learn JavaScript Fundamentals                  41

    The for loop in this code is designed to run through all of the degrees Celsius starting at –70,
incrementing by 10 degrees per iteration, until Celsius reaches +70 degrees (–70, –60, –50, –40, etc.).
    But if you examine the code inside the loop, it tells JavaScript to break out of the loop when
the temperature exceeds 100º Fahrenheit. Since 100º Fahrenheit is approximately 37º Celsius, the               2
loop will actually exit when Celsius hits 40, and not 70. The break statement causes the loop to
exit prematurely.




     The continue statement is very useful when you want to loop through a range of values,
ignoring some that don’t meet certain criteria. But when you find some that do, you have a lot
of code to execute inside the loop. Instead of surrounding dozens of lines of code with a giant
if statement, the continue statement can be used to skip on to the next iteration.
// Which numbers are evenly divisible by 23?
var iNumber;
for (iNumber = 1; iNumber <= 1000; iNumber++) {
    if (iNumber % 23 > 0) {
        // Not divisible by 23
        continue;
    }
    document.write("<b>" + iNumber + "</b>");
    document.write(" is evenly divisible by 23!<br>");
}
42      How to Do Everything with JavaScript


          In this code, the loop is designed to execute 1,000 times, running through the numbers from
     1 to 1,000. The if statement inside the loop checks to see whether the number is evenly divisible
     by 23, using the modulus (%) operator. If it is not evenly divisible by 23, the continue statement
     is executed—the rest of the current loop is skipped and the next iteration of the loop starts.
          Every 23 numbers (it’s odd how it works out like that), we will run into a number that is
     evenly divisible by 23. The continue statement is not executed, and the rest of the loop has a
     chance to run. In our example, we output the happy news that we finally found a number that
     matches, using the document.write() function.




     Using Labels
     A label is a named line of code. Since their only purpose is related to loops—nested loops in
     particular—labels are rarely used in real life, although it is important to know they exist.
              In programming terminology, you have created a nested loop when you place one loop
              completely inside another—for instance, if you have a for loop inside a while loop. In
              this situation, the for loop is known as the inner loop, and the while loop is called the
              outer loop. Loops can be nested many levels deep.
CHAPTER 2: Learn JavaScript Fundamentals              43

   Labels are fairly easy to create.

    1. Open your JavaScript program using a text editor, such as Notepad.
   2. Pick the line of code that you would like to name. Labels must appear at the beginning of         2
      a valid statement.
   3. Type a label name, using only letters or numbers. No spaces or other special characters
      are allowed in the name.
   4. End the label with a colon (:).

   For instance, in the following code, we have a set of nested loops, which are also labeled.
var x, y, z;
outer: for (x = 1; x < 20; x++) {
    middle: for (y = 1; y <= x; y++) {
        inner: for (z = 1; z <= y; z++) {
             document.write
                 ("x = " + x + "; y = " + y + "z = " + z + "<br>");
        }
    }
}

     In this code, we have three loops. The innermost loop, acting on the variable z, is labeled
“inner.” The middle loop, which encloses the loop named “inner,” is called “middle.” And the
outermost loop is named “outer” and encloses both the middle and inner loops.
     The only reason to label a loop is because the break and continue statements are designed
to work with labels. By adding the following code immediately after the document.write function
call inside the innermost loop, you could cause all three loops to exit prematurely:
break outer;

    This is convenient when you have a condition inside an inner loop (it doesn’t have to be the
innermost one, however) that would make you want to stop processing all the loops—or even just
stop processing the two innermost and continue with the outer loop. For instance, the following
code placed inside the innermost loop in the preceding code would cause the variables y and z
to never get past the value of 1, while x is allowed to increment to 20:
break middle;


Comment Your Code
We discussed comments briefly in Chapter 1. Comments are not really a type of statement,
although they are often lumped in with the other JavaScript statements for the sake of
convenience. There are two ways to add comments inside a JavaScript program.
44      How to Do Everything with JavaScript


         You can add a single line of comments by starting your comments with two slashes.
     // Everything after the slashes will be ignored by JavaScript

         It is also possible to include comments on the same line with valid code.
     var Students = 3;               // There will be three students in the class

         Another way to comment code is with block comments. Block comments start with a slash
     and an asterisk (/*).
     /* This is the start of block comments

        Block comments continue until an asterisk and slash (*/) are encountered, even if the
     comments extend over several lines.
     /* This is the start of block comments
        Even this will be ignored
        document.write ("This will not be executed either!");
        Because it is still considered a comment */

         When you are developing small JavaScript programs for yourself, you may not wish to spend
     much time commenting your code. That is fine—it’s called programmer’s prerogative. You may
     find, however, that comments are useful for the following reasons:

         ■ You can include a copyright notice with your program.
         ■ You can describe what a program or function does in “plain English.”
         ■ In the development stage, or when debugging, sometimes you would like code
             not to execute, but you don’t want to delete it.
         ■ Comments can also be placeholders for code you want to add some time in the future.
         If you create programs professionally, you may be required to include a copious amount
     of comments to make it easier for others to understand your code.

     Set a Default Object
     We have not yet spent any time looking at the concept of programmable objects in this book and
     I’m going to defer most of that discussion to Chapters 3 and 5, when we get to built-in objects
     and user-defined classes. But in order to understand the with statement and its ability to specify
     a default object for a set of statements, let’s spend a moment looking at what objects, methods,
     and properties are.
          To understand the concept of objects in programming, it is helpful to draw an analogy to the
     real world. Almost anything in real life can be thought of as programmable object—a car, a television,
     a coffee cup, or even a person. In programming, objects can have both methods and properties.
     An object’s methods are actions it can take, while an object’s properties describe the object.
          For instance, let’s assume we have created a Person object in JavaScript. In real life, a person
     typically has certain unique features, such as a name, hair color, eye color, and height. These
     features would be defined as properties of the Person object. In real life, a person can take actions
CHAPTER 2: Learn JavaScript Fundamentals                45

such as eating, sleeping, talking, and listening. These actions would translate into methods of the
Person object.

The with Statement                                                                                          2
The with statement allows you to access the methods and properties of an object without having
to specify the name of the object on every line. Without the with statement, you will always need to
specify the name of the object you are working on next to every property or method you wish
to access:
person.fullname = "Bob Jones";
person.haircolor = "Black";
person.eat();
person.sleep();

    But when statements are surrounded by the with statement, the object name is implied,
as in:
with (person) {
    fullname = "Bob Jones";
    haircolor = "Black";
    eat();
    sleep();
}

     When JavaScript first encounters the reference to fullname inside the with statement, it will
first check to see if a variable called fullname exists. If not, it will check to see if the person
object has a property called fullname. As you can see, when you need to access the same object
repeatedly over many lines, it may make sense to surround your code in a with statement.
     The with statement can be a convenient statement for the programmer to use—anything that
saves typing is convenient. But some developers feel using the with statement also makes your
program a bit harder to read. With the technique of copy-and-paste in most text editors, there
may not be many reasons you would need to use this statement in your programs.
with (document) {
    write("99 bottles of          beer on the wall<br>");
    write("99 bottles of          beer<br>");
    write("If one of the          bottles happens to fall<br>");
    write("98 bottles of          beer on the wall<br><br>");

     write("98     bottles of     beer on the wall<br>");
     write("98     bottles of     beer<br>");
     write("If     one of the     bottles happens to fall<br>");
     write("97     bottles of     beer on the wall<br><br>");
}
46      How to Do Everything with JavaScript


         In the preceding code, we start off by declaring that we would like document to be the
     default object. Notice how we can then start using the write() method without referring to
     document at all.
              The default object set using the with statement applies only to code within the
              curly brackets. Outside the curly brackets, the object will need to be explicitly
              used once again.

     Handle Errors
     Perhaps the most difficult programming challenge most developers face on a regular basis is
     intelligently handling errors. In JavaScript programming, an error is a problem that the browser
     encounters when it is trying to run a program. Errors can be triggered by something the browser saw
     and didn’t like, called a system error. Or it can be triggered by something your program saw and
     didn’t like, called an application error.
          A JavaScript program could easily be doubled in size with the addition of a reasonable amount
     of error-handling code. Error-handling code is typically additional code a programmer has to write
     to check for the existence of errors and do something with them. In JavaScript, if the program
     contains no error-handling code, the default action is often for the browser to present the problem
     to the user.
          The problem with error-handling is that it often takes as much work (or more) to create good
     error-handling code as it took to create the rest of the program. So frequently, for a variety of
     reasons, programmers skip that step.
          It is all too easy to write a program (in any language) without any error-handling code. You
     can tell the computer to go to the database, read in some values, ask the user for some input, add
     the user’s input into the existing data, and put it back into the database. That can be done in a
     programming language such as Visual Basic in about 30 lines of code. But that assumes nothing
     could ever go wrong. If you think about it, lots of things can go wrong:

         ■   The database is not available.
         ■   The database is available but you are unable to log in.
         ■   You can log in to the database, but the data is not available.
         ■   The data you retrieve from the database contains invalid values.
         ■   The user enters invalid values.
         ■   Adding the user’s data into the database data causes an error.
         ■   You are unable to save the data back to the database.

         So by the time you add code to your program to handle all those errors, you are suddenly
     looking at a 120-line program, instead of a 30-line program. So you see, it is certainly easier
     to avoid worrying about this type of stuff.
         But when you are writing programs professionally, you must worry about how errors are
     handled. Should the program crash when the user types in a wrong value? Or should you simply
CHAPTER 2: Learn JavaScript Fundamentals                  47

continue on, writing the bad data to the database, causing errors the next time the program is
run? Or is the best solution to inform the user of their mistake and ask them to try again? This
is why errors such as these need to be caught and properly handled.
                                                                                                               2
The try-catch Statement
Web browsers are designed to handle errors differently depending on the browser type and
version, and to some degree on the user’s browser settings. In some cases, if you include some
bad JavaScript code inside a web page the browser would simply not run it, with no error message
or other indication that something went wrong. In other cases, the browser pops up a message box
with details of the error it encountered, asking the user what to do next. The JavaScript error message
usually looks something like this.




    For JavaScript developers, neither of the default error-handling methods is ideal. Ignoring an
error completely stops the program from executing. And displaying an ugly error message to the
user can be embarrassing for the programmer—not to mention frustrating to the user.
         There are some minor differences between the ways Netscape and Microsoft use this
         statement and what the official ECMA specification defines. In this section, I am using
         the statement as supported by most web browsers.

    The try-catch statement is used to allow programs to handle the error themselves, instead
of allowing the browser to do it. It is often used to wrap a statement or set of statements that are
likely to fail. The statement has the following syntax:
try {
    statements;
}
catch (variable) {
    // error handling code
    statements;
}

         The try-catch statement was only added in JavaScript 1.4, so only recent browsers
         (such as IE 5.5 and Netscape 6) support it.
48      How to Do Everything with JavaScript


        For example, you can surround a function call using the try-catch statement, and report
     a more friendly error message to the user if it fails.
     try {
         open_database();
     }
     catch (err) {
         // error handling code
         alert("An error occurred connecting to the database." +
             " Please try again in a few minutes.");
     }

         So instead of receiving the ugly-looking JavaScript error message (or none at all, depending
     on the browser settings), your user will receive a friendlier message asking them to try again in
     a few minutes:




          The official system error message that occurred is still passed to the statement as a parameter
     of the catch clause. In our example, the err variable contains the description of the error that occurred.
     So if you needed to determine what happened inside the catch clause, you can. You can even
     display the original error message text to the user.
          The try-catch statement is not only used for catching system errors; you can also use this
     construct to catch errors generated by your own program.
          It is a good idea to use a try-catch statement when your program is attempting to do something
     that could cause an error, for instance, if your program is attempting to connect to an embedded
     Java applet. It is possible for an applet to encounter a problem and be unable to load, or for
     a browser’s security settings not to permit certain Java applets to run. If you surrounded such
     code in a try-catch statement, you could detect this problem and redirect the user to a non-Java
     version of the application.
          There are also plenty of errors that your application could detect programmatically, including:

         ■ Invalid user input in a form
         ■ Unsupported browser maker or version
         ■ Missing or invalid browser cookies

     The throw Statement
     The throw statement allows a JavaScript program to declare an error in the exact same manner as
     it would use for system errors. That means these errors can be caught using a try-catch statement.
CHAPTER 2: Learn JavaScript Fundamentals               49

   It also means that user-declared errors that are not caught are displayed to the user in a JavaScript
   pop-up dialog box.
             Like the try-catch statement, the throw statement was only added in JavaScript 1.4, so
             only recent browsers (such as IE 5.5 and Netscape 6) support it.
                                                                                                                2
       The following is an example of a program that throws its own errors.
   try {
       var errors = 0;
       // Do something
       errors++;
       if (errors > 0) {
           throw "Could not find the file.";
       }
   }
   catch (errorstring) {
       alert("The following error occurred:nn" +
           errorstring);
   }



Understand the Basics of Expressions
   Many of the programming statements that we have been examining in this chapter use an expression
   to make some sort of decision. An expression is anything that returns a value. Table 2-2 lists the
   common types of expressions, along with an example of their use.

    Expression                        Example
    Numeric literal                   47
    String literal                    "Hello"
    Boolean literal                   true
    Object literal                    {make : "Toyota"}
    Program-defined variable          x
    Program-defined function          get_toast()
    Null                              null
    Assignment expression             x=5
    Mathematical operations           x+y
    Boolean operations                x == y
    Conditional operator              x == 5 ? "yes" : "no"
    Combination                       x = "You have " + messagecounter + " new messages"
    TABLE 2-2         Common Types of Expressions
50      How to Do Everything with JavaScript


          Some statements, such as the if statement or while statement, specifically require expressions
     that return a Boolean value (true or false). JavaScript does its best to automatically convert strings
     and integers to the appropriate Boolean value. Expressions are also often used as parameters to
     functions, and can also be used as statements themselves.
     x = 5;

     This code is an expression, but it is also a statement. It assigns the value 5 to the variable x.


Use Operators to Create Complex Expressions
     JavaScript provides a number of operators to perform mathematical and other functions within
     your code. Some operators modify the variables they operate on, although most do not. All operators
     return a value, and thus can be used to create complex expressions.
          There are 12 types of operators in JavaScript, and several dozen individual operators. Most
     operators are represented by symbols (like +), while some operators are represented by words
     (like new). Most operators require two operands, while some operators only require one (particularly
     the unary operators).
          Table 2-3 lists the operators available in JavaScript 1.5.



      Operator Type              Operators
      Member                     dot (.)
                                 square bracket ([])
      Unary                      new
                                 delete
                                 typeof
                                 instanceof
                                 void
                                 ++
                                 --
                                 negation (-)
                                 logical not (!)
                                 bitwise not (~)
      Multiplicative             multiply (*)
                                 divide (/)
                                 modulus (%)
      Additive                   add (+)
                                 subtract (-)
      Bitwise Shift              shift left (<<), unsigned shift right (>>>), signed shift right (>>)
      TABLE 2-3        Operators Available in JavaScript
CHAPTER 2: Learn JavaScript Fundamentals               51

    Operator Type               Operators
    Relational                  less-than (<)
                                greater-than (>)
                                less-than-or-equal (<=)                                                            2
                                greater-than-or-equal (>=)
                                in
    Equality                    equal (==)
                                not equal (!=)
                                strictly equal (===)
                                strictly not equal (!==)
    Bitwise Logical             bitwise and (&)
                                bitwise or (|)
                                bitwise exclusive or (^)
    Logical                     logical and (&&)
                                logical or (||)
                                logical exclusive or (^^)
    Conditional                 conditional (?:)
    Assignment                  equals assignment (=)
                                shortcut assignment (*=, /=, +=, -=, %=, <<=, >>=, >>>=, &&=, ||=, ^^=, &=,
                                |=, and ^=)
    Special                     comma (,)
                                function
                                this
    TABLE 2-3         Operators Available in JavaScript (continued)



       JavaScript 2.0 adds two new operators to the language, and they are both considered relational:

       ■ is
       ■ as
       We have already seen a few of these operators in action so far in this chapter, such as equals
   (==), greater-than (>), increment (++), in, and equals assignment (=). Most of these operators have
   their origin in mathematics. Additional operators exist to deal with logical Booleans (such as
   logical and and logical or), plus binary operators to deal with the ones and zeros of binary math.


Organize Your Code into Functions
   There may be the occasional instance when you can sit down and write an entire JavaScript
   program without functions, but believe it or not, that type of JavaScript program is rare. Most
   JavaScript programs contain at least one function.
52      How to Do Everything with JavaScript


         Functions allow you to predefine a group of JavaScript statements before you actually need
     to call that code. Since functions can be called repeatedly, with varying parameters, they are also
     convenient time-savers.

     Define Functions
     Functions are defined using the function keyword. Functions must be assigned a name and can
     optionally take one or more parameters. Parameters are contained in brackets, and separated by
     commas.
     function name(parameter1, parameter2, …, parameterN) {
         statements;
     }

         This is the JavaScript 1.5 format for defining functions. JavaScript 2.0 introduces some powerful
     extensions to this basic format, by allowing parameters to have a data type, the function itself to
     have a data type, parameters to be optional, named parameters, and more. We will examine the
     JavaScript 2.0 functions later in this chapter.
         The parameters specified inside the function definition are treated as variables inside the
     function. Parameter names must be unique, in that two parameters of the same function cannot
     have the same name.
         From the basic function syntax, we can define a basic function:
     function add_two(x, y) {
         if (x > 7) {
             x = x - 7;
         } else {
             x = x + 7;
         }
         if (y > 18) {
             y = y - 18;
         } else {
             y = y + 18;
         }
         return x + y;
     }

         The preceding code creates a function called add_two(). This function accepts two parameters,
     named x and y. The function’s name and the parameters it accepts are defined in the first line
     of code:
     function add_two(x, y) {

         The function’s code defines a somewhat complicated way to add two numbers together. First,
     the contents of both x and y are examined, and depending on their values something is added or
     subtracted from each.
CHAPTER 2: Learn JavaScript Fundamentals                 53

     if (x > 7) {
         x = x - 7;
     } else {
         x = x + 7;                                                                                          2
     }
     if (y > 18) {
         y = y - 18;
     } else {
         y = y + 18;
     }

    Then the two numbers are added together and the result is returned. With the addition of a
return statement that returns a result, this function can act as an expression, by returning a value.
     return x + y;

    Now the code just defines a function. If you were to add this into our HTML template and try
to execute it in a web browser, it would actually do nothing. Functions need to be called in order
to run. And if a function defines one or more parameters, values must be given for those as well.
    In order to call a function, you must do the following:

    1. Type its function name followed by an open parenthesis:
        add_two(

   2. Provide a list of parameters, if required, separated by commas:
        add_two(12, 2

   3. Followed by a close parenthesis and a semicolon:
        add_two(12, 2);

   4. Of course, in the case of our function, we need to assign its return value to a variable, or
      use it in a context that expects a value:
        var result = add_two(12, 2);

    We can combine the function definition, our HTML template, and a bit of code that calls our
function with various parameters as follows:
<html>
    <head>
        <title>JavaScript sample code</title>
    </head>
    <body>
        <h1>Defining JavaScript Functions</h1>
        <script language="JavaScript" type="text/javascript">
54      How to Do Everything with JavaScript

                <!-- // Begin
                function add_two(x, y) {
                    if (x > 7) {
                        x = x - 7;
                    } else {
                        x = x + 7;
                    }
                    if (y > 18) {
                        y = y - 18;
                    } else {
                        y = y + 18;
                    }
                    return x + y;
                }

             document.write("add_two(2, 17) = " +
                 add_two(2, 17) + "<BR>");
             document.write("add_two(14, 9) = " +
                 add_two(14, 9) + "<BR>");
             document.write("add_two(100, 200) = " +
                 add_two(100, 200) + "<BR>");
             // End -->
             </script>
         </body>
     </html>

         In this code, we have inserted our add_two() function definition into the <script> section of
     our HTML template. For the code inside that function to be executed, we need to call that function.
     In our code, we call the function three times, with three different sets of parameters.
         When we load this code into a browser, we see something similar to Figure 2-4. Since we
     are calling the functions inside the document.write() function call, the output of the function is
     written to the screen. This is also a good example of how functions can themselves be passed
     as parameters to other functions—the value of add_two has to be executed to come up with the
     value that gets passed to document.write.

     Accept Parameters
     Of course, a function can be defined without any parameters.
     function print_header() {

         The parentheses are still required when defining and calling such a function.
     print_header();
CHAPTER 2: Learn JavaScript Fundamentals              55



                                                                                                         2




 FIGURE 2-4      Defining a function and calling it repeatedly


    Another important consideration when using functions is how variables and even parameters
are treated. Consider the following bit of JavaScript code:
var counter;
counter = 5;
function add2(input) {
    input = input + 2;
    document.write("input = " + input + "<br>");
    return;
}
add2(counter);
document.write("counter = " + counter + "<br>");

    What value will be written to the screen at the end of that program? We start off by defining
a variable named counter, and assigning it a value of 5. We then define a function named add2()
56      How to Do Everything with JavaScript


     which appears to add the value 2 to the parameter that is passed to it. We then call this function
     with our counter variable and print its value to the screen.
         The answer is that counter will still have a value of 5 at the end of the program.




         Why? Well, that has to do with how parameters are handled inside functions. JavaScript does
     not pass the actual counter variable into the add2() function. It actually makes a copy of counter,
     and passes the copy into add2(). Therefore, any changes add2() makes to the parameter are lost
     when the function exits.
              JavaScript passes parameters by value, which means the value of any parameters
              cannot be permanently altered inside a function.

     Understand Variable Scope
     Another important rule concerning functions is one of variable scope. In programming, when and
     where a variable can be used is determined by where you define it. If you declare a variable inside
CHAPTER 2: Learn JavaScript Fundamentals              57

a function, it can only be used inside that function. When you exit the function, the variable is
no longer defined and its value is lost.
// get_factors() returns all the numbers that divide into
//     the parameter evenly
                                                                                                          2
function get_factors(inputValue) {
    var counter;
    var factorString = "";
    for (counter = 1; counter <= inputValue; counter++) {
        if ((inputValue % counter) == 0) {
            factorString = factorString + counter + " ";
        }
    }
}
get_factors(6777214);
document.write (factorString);

     For instance, in this code, a function named get_factors() is defined. We then call it using
the value 6,777,214 as its parameter. We would like to print out the string that results using
document.write(), but by that time it is too late. The factorString variable is only valid inside
the function, because that is its scope. When we attempt to run this program, an error message
attributed to the final line of our program is displayed. The variable factorString cannot be used
outside the function in which it is defined.
58      How to Do Everything with JavaScript


         If we were to move the document.write() statement inside the function call, we would see
     a better result.




     Return Values
     Inside a function, the return statement serves two purposes:

         ■ It causes the function to exit.
         ■ It optionally passes a value back to the line of code that called it.
         Much as the break statement causes a loop to exit, the return statement causes a function to
     exit as well. Since functions can act as expressions by returning a value to the code that called it,
     the return statement can accept the value returned as an optional parameter.

         ■   return;
         ■   return "Hello";
         ■   return 32;
         ■   return true;
CHAPTER 2: Learn JavaScript Fundamentals                 59

   All four of these are valid uses of the return statement inside a function.


Use the Improvements in JavaScript 2.0                                                                           2
to Create More Powerful Functions
   JavaScript 2.0 brings a number of improvements to the language. The European Computer
   Manufacturers Association (ECMA) has added a number of features that increase the power
   and flexibility:

       ■   Classes
       ■   Packages
       ■   Namespaces
       ■   Data types
       ■   More powerful and flexible data arrays
       ■   Access controls, such as public and private

        With this added functionality, JavaScript can now be used for tasks that used to require
   a more complex language like C++ or Java, while still retaining the simplicity that has made
   JavaScript so popular with web developers for all these years.
        If you’ve worked with JavaScript before, one of the first changes you will notice is the addition
   of data types to the language. Data types allow you to restrict the range of values a variable can
   contain or a function can return. We can modify the add_two() function we defined earlier in
   this chapter with JavaScript 2.0 syntax to use data types for all its variables, parameters, and the
   function itself:
   function add_two(x : Number, y : Number) : Number {
       if (x > 7) {
           x = x - 7;
       } else {
           x = x + 7;
       }
       if (y > 18) {
           y = y - 18;
       } else {
           y = y + 18;
       }
       return x + y;
   }
60       How to Do Everything with JavaScript


         Now that we have added the Number data type to our x and y parameters, JavaScript will
     report an error if something other than a number is passed. It is also clearer to other developers
     what data types we expect for each of the parameters.

     Use Named Optional Parameters
     Another change to the way parameters are used in JavaScript 2.0 is the ability to define named
     optional parameters. The named keyword allows us to identify some parameters as optional
     when defining the parameter list of a function.
         For instance, let’s say we have a function that expects a person’s name to be passed to it in
     three parts:
     function sayHello
         (first : String,
          initial : String,
          last : String) : String {

           var fullname;
           if (initial <> "") {
               initial = initial + ". ";
           }
           fullname = first + " " + initial + last;
           return fullname;

     }

         If we define it using the preceding syntax, we have no choice but to call it in the following way:
     sayHello ("Scott", "", "Duffy");

         But by using the named modifier on the middle initial parameter, we can allow the function
     to be called without the middle initial.
     function sayHello
         (first : String,
          last : String,
          named initial : String = "") : String {
         var fullname : String;
         if (initial <> "") {
             initial = initial + ". ";
         }
         fullname = first + " " + initial + last;
         return fullname;
     }
     document.write (sayHello ("Scott", "Duffy") + "<br>");
     document.write (sayHello ("Bobby", "Jones", initial:"H") + "<br>");
CHAPTER 2: Learn JavaScript Fundamentals                 61

    By defining the middle initial parameter as named, we can then call the sayHello() function
with only the first and last name specified. Named parameters must always specify an initializer
in case a value is not specified for that parameter, so one can be assigned. If you want to provide
a value for a named parameter, you have to refer to that parameter by name.                                  2
Accept Any Number of Parameters
Functions in JavaScript 2.0 can be defined so that they can accept an unlimited number of
parameters. You would want to do this when your function needs to accept a large number
of identical parameters but you do not want to create lots of named optional parameters.
     The rest parameter must always appear at the end of any unnamed parameters that are defined,
using three periods (...). Named parameters, those defined using the named keyword, can still be
listed after the rest parameter. Of course, there can only ever be one rest parameter for a single
function.
     The following code defines a function that can accept an unlimited number of parameters.
The first four arguments passed will be assigned to the first four parameters defined: name, address,
phoneNum, and spouseName. Any arguments passed beyond those four will be assigned to an
array called childName. We can use a for-in loop to get the list of names out of that variable.
(We will look at arrays in depth in Chapter 4.)
function printform (name : String,
    address : String,
    phoneNum : String,
    spouseName : String,
    ... childName : Array) {

     // An unlimited number of children can be provided
     with (document) {
         write ("Name: " + name + "<br>");
         write ("Spouse: " + spouseName + "<br>");
         write ("Address: " + address + "<br>");
         write ("Phone: " + phoneNum + "<br>");
         for (child in childName) {
             write ("Child " + childName[child] + "<br>");
         }
     }
     return;

}

    In the next chapter, we will focus on some of JavaScript’s most powerful features—its
built-in objects and functions.
This page intentionally left blank
Use Built-in
Chapter 3   JavaScript Classes
64      How to Do Everything with JavaScript


     How to...
         ■   Master objects in JavaScript
         ■   Understand JavaScript’s built-in classes and data types
         ■   Create a String object in JavaScript
         ■   Perform mathematical functions
         ■   Apply JavaScript’s date-handling functions
         ■   Convert strings into numbers
         ■   Prepare text before sending to web server
         ■   Decide when to use regular expressions
         ■   Use JavaScript 2.0’s powerful new data types
         ■   Decide when to use JavaScript 2.0’s special data types

     JavaScript has always contained a number of built-in classes that programmers could employ
     when developing programs. These classes—self-contained data and code—provide useful
     functionality for handling dates, mathematical functions, and arrays. For instance, if you wanted to
     retrieve the current date and time in JavaScript, you would create an instance of the Date class, as so:
     var today = new Date();

          The today variable in this code is actually an object. Not only does the today object contain a
     value (today’s date in fact), but it also contains a number of built-in functions for retrieving and
     setting individual parts of the date and converting it into a number of different formats (a string,
     for instance). The Date class, and all of its functionality, is explored in the section “Apply
     JavaScript’s Date-Handling Functions,” later in the chapter.
          JavaScript 1.5 contains nine such classes, but only three are used in common practice (Array,
     Date, and Math). JavaScript 2.0 has expanded the list to more than 18 classes, and almost all of
     them are useful. In this chapter, we will examine most of these classes and learn to apply them in
     our JavaScript programs.


Learn about Objects in JavaScript
     We are approaching the 50th anniversary of the development of Fortran, the first high-level
     programming language, which was developed in 1956. Since that time, computer scientists have
     developed several programming methodologies. Table 3-1 lists the most common methods of
     designing programs.
         It’s important to remember that no methodology is perfect for every situation. In JavaScript
     programming, you are likely to use any of the four methodologies listed in Table 3-1, depending
     on the task at hand.
CHAPTER 3: Use Built-in JavaScript Classes   65

 Methodology           Description
 Unstructured          Sequence of statements acting on global data
 Procedural            Main program that calls functions to perform certain tasks
 Modular               Main program that uses modules to group related functionality
 Object-oriented       Main program that uses objects to group related data and functionality         3
 TABLE 3-1         Common Programming Methodologies



Write Unstructured Programs
Unstructured programming is usually best used for short, simple scripts, since they would not
benefit from many functions and objects. An unstructured program is simply a set of JavaScript
statements that does not use user-defined functions or objects.
    The following is an example of an unstructured program, in the context of an HTML web
page. Notice that there are only three lines of JavaScript code in the program.
<html>
    <head>
        <title>JavaScript sample code</title>
    </head>
    <body>
        <h1>Unstructured Program</h1>
        <script language="JavaScript" type="text/javascript">
        <!-- // Begin
        for (var counter = 1; counter < 101; counter++) {
            document.write ("This is line number " + counter + "<br>n");
        }
        // End -->
        </script>
    </body>
</html>


Organize Code into Procedures
Procedural code is also quite common in JavaScript programming. We could easily rewrite the
unstructured code in the preceding program using the procedural approach.
function printline(value) {
    document.write ("This is line number " + value + "<br>n");
}

for (var counter = 1; counter < 101; counter++) {
    printline(counter);
}
66      How to Do Everything with JavaScript


         This program creates a function named printline(), whose sole job is to write text to the
     screen that includes the value passed to it as a parameter. Later on in the program, we can
     repeatedly call that function.
         The benefits of this type of programming practice are twofold:

         ■ The same function can be called from multiple locations in a program, thereby removing
             the code duplication of an unstructured approach.
         ■ Dividing a program into functions makes it easier to test, which generally results in
             fewer bugs.

     Separate a Program into Modules
     If a program gets sufficiently big (in size and scope), it gets increasingly difficult to manage and
     maintain. Programmers require an additional technique (besides using procedures and functions)
     to separate their programs into smaller, more manageable pieces. The next logical step up from
     the procedural approach is the modular approach.
          Modular programming generally involves separating one large program into two or more
     separate files. These files, or modules, as they are called, are not necessarily self-contained, but
     they do group related code and functions together. Typically, a modular program consists of
     a main program plus one or more modules, such as:

         ■   Main program
         ■   Database module
         ■   User interface module
         ■   Error-handling module

          We can infer from the preceding modular configuration that the main program does most of
     the work, but it calls functions that exist in the database module whenever it needs to talk to the
     database. Similarly, it uses the user interface and error-handling modules to do their own tasks,
     as needed. This type of program is much easier for a programmer to manage when broken up
     into modules, as opposed to one large single module.
          To create a modular program using JavaScript, you need to create one or more JavaScript
     files. When you import those external code files into an HTML page using a property of the <script>
     tag, your main program has access to all the functions defined in those external modules. We will
     learn more about creating and importing JavaScript files in Chapter 6.

     Use the Object-Oriented Approach
     The next progression from modular programming is to object-oriented programming. The concept
     of objects can be a little bit intimidating at first, but that should not stop anyone from attempting to
     at least understand how using objects can make the job of a programmer much easier.
CHAPTER 3: Use Built-in JavaScript Classes            67

     In programming, an object is simply a “thing” that has its own attributes (known as properties)
and related functions (known as methods). You can think of objects in programming just as you
would think of objects in real life. Let me give you an example.
     My car is an object that has certain attributes and can perform certain actions. The unique
attributes of my car distinguish it from most others on the road. Even if I encounter another
vehicle that is the same make and model as my own, they are still separate vehicles. The                    3
following is a list of some common properties of my car:

 Property                              Value
 Year                                  2001
 Make                                  Toyota
 Model                                 4Runner SR5
 Tires                                 4
 Doors                                 4
 Color                                 Thundercloud
 Speedometer (mph)                     Ranges from 0 to 70
 Gas gauge (volume, in gallons)        Ranges from 0.0 to 16.0
 Etc.


     What I have just listed are, in fact, the programming variables that will go into my Car
object. In fact, the first five properties (Year, Make, Model, Tires, and Doors) are permanent—
in programming parlance they’re constants. The rest of the properties can be changed, thus they
are variable. Remember, we examined constants and variables in Chapter 2. If I were to turn the
list of properties related to my car into JavaScript 2.0 code, it would look something like this.
const Year : Integer;
const Make : String;
const Model: String;
const Tires : Integer;
const Doors : Integer;
var Color : String;
var CurrentSpeed : Number;
var CurrentGas : Number;

    Besides having several properties, my car also has several actions it can perform:

 If I do this…                          The car does this…
 Step on the gas pedal                  Increases its speed; increases fuel consumption
 Step on the brake pedal                Decreases its speed; decreases fuel consumption
68      How to Do Everything with JavaScript


      If I do this…                            The car does this…
      Turn the steering wheel right or left    Turns its front wheels right or left
      Press the center of the steering wheel   Honks its horn
      Add gasoline into the gas tank           Increases its gas volume


         Again, from a programmer’s perspective these are functions of the car. Many of the functions
     are related to the car’s properties. For instance, both the gas pedal and the brake pedal affect the
     car’s speed and gasoline usage.
         If my car were a programmable object, it would have the following JavaScript 2.0 function
     definitions.
     function     depressGasPedal (howMuch : Integer) {}
     function     depressBrakePedal (howMuch : Integer) {}
     function     turnSteeringWheel (degrees : Integer) {}
     function     beepHorn () {}
     function     addGas (volume : Number) {}


     Turn Properties and Functions into a Class
     Simply defining the collected constants, variables, and functions of a car does not make it an
     object. Before a collection of code can become an object, it must first become a class.
         A class is a self-contained grouping of variables and functions. The variables and functions
     of a class, also called its members, cannot be used to store data or perform actions. Classes are
     merely the blueprints from which objects are created. There will only ever be one Car class in
     our computer program, but there could potentially be several Car objects. There could also be
     no Car objects, if we do not choose to create any.
               There is one exception to the rule that classes cannot store data or perform actions.
               If a class member is defined as static, it can be used without the existence of an object.
               Static class members are discussed in more detail in Chapter 5.

         We will examine user-defined classes in Chapter 5. There is a different syntax for creating
     this class definition in JavaScript 1 and JavaScript 2, and it is important to understand the
     difference. Without getting into more detail, this is how our Car class would look in JavaScript
     2.0 syntax.
     class Car        {
         const        Year : Integer;
         const        Make : String;
         const        Model: String;
         const        Tires : Integer;
         const        Doors : Integer;
CHAPTER 3: Use Built-in JavaScript Classes           69

        var Color : String;
        var CurrentSpeed : Number;
        var CurrentGas : Number;

        function depressGasPedal (howMuch : Integer) {
            // Gas pedal JavaScript code
        }
                                                                                                              3
        function depressBrakePedal (howMuch : Integer) {
            // Brake pedal JavaScript code
        }
        function turnSteeringWheel (degrees : Integer) {
            // Steering wheel JavaScript code
        }
        function beepHorn () {
            // Horn JavaScript code
        }
        function addGas (volume : Number) {
            // Gas tank JavaScript code
        }
   }

       We can create a Car object by calling the new operator with the name of the Car class. We
   will examine the new operator in more detail in the section “Instantiate an Object with the new
   Operator,” later in this chapter.
   var myAuto = new Car();
   myAuto.Year = 2001;
   myAuto.Make = "Toyota";
   // etc.

       Finally, classes in JavaScript 2.0 are also automatically defined as data types, so variables
   can be defined that can only contain the specified object.
   var Ferrari : Car = new Car();



JavaScript’s Built-in Classes and Data Types
   Despite the lack of true data types in previous versions of the language, JavaScript has always
   had the concept of classes. Developers could use a number of built-in classes, which provided
   useful methods and functions for manipulating certain types of data.
       Table 3-2 lists the classes that exist in JavaScript 1.5, along with a brief description of the
   functionality each class provides.
       The most significant improvement in JavaScript 2.0 is that the language has evolved to
   become more object-oriented than it ever was before. JavaScript 1.5 was object-based, but did
70      How to Do Everything with JavaScript


      Class Name              Description
      Array                   Allows lists of data to be stored in a single variable
      Boolean                 A wrapper for Boolean values
      Date                    Lets you work with dates and times
      Function                Allows you to define a function programmatically
      Math                    Contains convenient mathematical constants and functions
      Number                  A wrapper for primitive numeric values
      Object                  All objects derive from this data type
      RegExp                  Provides support for regular expressions in JavaScript
      String                  A wrapper for string values
      TABLE 3-2     Predefined Core JavaScript 1.5 Classes



     not meet several of the key attributes of object-oriented programming languages. JavaScript 2.0
     meets most of the key attributes.
         Table 3-3 lists the classes supported by JavaScript 2.0. The list is obviously much longer than
     that in Table 3-2.


      Class Name              Description
      Array                   Allows lists of data of type Object to be stored in a single variable; is
                              equivalent to the Array[Object] data type
      Array[type]             Allows lists of data of type type to be stored in a single variable
      Boolean                 Supports variables that can only store true and false
      char                    Supports variables that can only store a single character
      ConstArray              Allows lists of data of type Object to be stored in a single constant; is
                              equivalent to the ConstArray[Object] data type
      ConstArray[type]        Allows lists of data of type type to be stored in a single constant
      DynamicArray[type]      Allows resizable lists of data of type type to be stored in a single variable
      Function                The “data type” of functions
      Integer                 Supports variables that can only store integers
      Never                   Supports variables that cannot contain any value
      Null                    Supports variables that can only store “null”
      Number                  Supports variables that can only store numbers
      Object                  Supports variables that can contain any value
      Prototype               Supports variables that contain prototype-based objects (JavaScript 1.5’s way
                              of handling objects)
      TABLE 3-3     Predefined Data Types in JavaScript 2.0
CHAPTER 3: Use Built-in JavaScript Classes            71

 Class Name              Description
 StaticArray[type]       Allows writable lists of data of type type to be stored in a single variable
 String                  Supports variables that can only store strings
 Type                    The “data type” of data types
 Void                    Supports variables that can only store “undefined”                                  3
 TABLE 3-3      Predefined Data Types in JavaScript 2.0 (continued)



          All classes in JavaScript 2.0, even ones you create yourself, can be used as data types.
          Consequently, the list of classes in Table 3-3 is also a partial list of data types.

    In addition to the list of predefined classes that can be used as data types in Table 3-3, there
are a number of machine types in JavaScript 2.0. These machine types (listed in Table 3-4) are
low-level data types that can be used in JavaScript, although not all JavaScript environments will
support them. They are provided for compatibility with other languages—for instance, when your
JavaScript program needs to exchange data with an external C-language application.
          NaN (Not a Number) is a defined constant in JavaScript that is, effectively, a number
          representing that an error occurred when processing that variable.

    Machine types can be used just like data types derived from classes, although they are not
classes themselves. For instance, in the following JavaScript 2.0 code listing, we create a handful
of variables defined as machine types.
var   counter : short = 14;
var   account_balance : int = 1701330222;
var   bigNumber : long = 74440000000000;
var   anotherBigNumber = 312L;

          The machine type suffixes listed in Table 3-4 are convenient shorthand notation for
          assigning a machine type to a value. The three suffixes—L, UL, and F—indicate to
          JavaScript that you wish to treat a number as either a long, unsigned long (ulong),
          or float number respectively. So the expression “0L” tells JavaScript to treat the
          value 0 as a long, due to the L machine-type suffix.

    In the preceding code, the variable anotherBigNumber will be treated as a long integer, since
we are assigning the value 312L to it. The L suffix forces the value 312 to be treated as a long
integer. This works only when assigning numeric literals to a variable, and will not work with
other types of expressions such as variables.
72      How to Do Everything with JavaScript


      Type        Suffix    Range of Values
      sbyte                 Integers between –128 and +127
      byte                  Integers between 0 and +255
      short                 Integers between –32768 and +32767
      ushort                Integers between 0 and +65535
      int                   Integers between approximately –2.1 billion and +2.1 billion
      uint                  Integers between approximately 0 and +4.3 billion
      long        L         Integers between approximately –9 quintillion and +9 quintillion (9 followed by
                            18 zeros)
      ulong       UL        Integers between approximately 0 and +18 quintillion (18 followed by 18 zeros)
      float       F         Single-precision floating point numbers, including positive and negative zeros,
                            infinities, and NaN
      TABLE 3-4        Machine Types Defined in JavaScript 2.0



     Instantiate an Object with the new Operator
     The procedure to create an object from either a user-defined or system-defined class is basically
     the same. JavaScript provides a special operator called new for this purpose, also called object
     instantiation.
     var myAuto = new Car();

          When the new operator is called with the name of an existing class (in this example, Car), it
     calls the class’s constructor and returns an instance of the object. By assigning that object instance
     to the variable myAuto, we are keeping a reference to that object so we can use it in our program.
          A constructor is a special function defined in some classes that makes the object ready for use.
     The initialization code is placed in the constructor. Classes can have more than one constructor or
     none at all. We examine creating your own classes, and constructors for those classes, in Chapter 5.
          Any parameters included in our new operator are passed to the constructor as parameters as
     well. If we had defined a constructor to our Car class, we would probably want to allow the user
     to pass in most of the relevant properties (Make, Model, Year, etc.) as parameters, so that the
     constructor can make the object completely ready for use. Otherwise, we would have a Car object
     with no predefined properties and our program would have to manually set each relevant one.
     var myAuto = new Car (2001, "Toyota", "4Runner SR5", "Thundercloud");

         This technique of object initialization using the constructor is a recommended programming
     technique.
CHAPTER 3: Use Built-in JavaScript Classes              73

   Access an Object with the . Operator
   Once an object has been created using the new operator, we can access all its public properties
   and methods using the dot operator (.). The dot operator is placed between the object name (not
   the class name) and the name of the property or method you wish to access.
   document.write ("Your car was created in " + myAuto.Year);                                                    3
      In this code example, we actually use the dot operator twice. We use it to access the write()
   method of the built-in document object and also to access the Year property of our user-defined
   myAuto object, which is an instance of the Car class.
            You can define properties and methods as private, which restricts the ability
            to access them using the dot operator. We will examine private properties and
            methods in Chapter 5.

   Access an Object with the [] Operator
   JavaScript also allows access to an object’s properties using the square brackets operator ([]).
   The one advantage this operator has over the dot operator is that you do not need to know the
   name of the property you wish to look up. For instance, let’s look at the following for-in loop.
   for (var tool in toolchest) {
       document.write(toolchest[tool] + "<BR>");
   }

       In this code example, we are passing a variable named tool to the square brackets operator,
   which is then able to extract the value of the property from the toolchest object. The public
   properties of any class defined in JavaScript 2.0 can be accessed using the square brackets
   operator. This even works for JavaScript’s built-in DOM objects for version 1.5.
   for (var prop in document) {
       document.write
         ("document." + prop + " = " + document[prop] + "<BR>");
   }

       This code results in the entire contents of the DOM document object being written to the
   web browser window, as you can see in Figure 3-1. Since the DOM is slightly different between
   different browser makers and even versions of the same browser, your own test will probably
   reveal different properties and values.


Create a String Object in JavaScript
   A string is simply a sequence of zero or more Unicode characters. The following are all valid strings:

       ■ "" (an empty string)
       ■ "How was work today, Sofia?"
74      How to Do Everything with JavaScript


         ■ "32" (numeric characters)
         ■ "Êtes-vous prêt pour l’examen?" (non-English characters)
         There are two ways to create strings in JavaScript:

         ■ A string literal
         ■ Using the String object
         The vast majority of strings are created using the string literal, since it is by far the quickest
     and easiest technique.

     Create a String Object Using a String Literal
     A string literal in JavaScript is simply a sequence of zero or more characters surrounded by
     either single or double quotation marks, like so:
     var myString = "This is a string literal";
     var myOtherString = 'So is this, using single quotation marks.';




      FIGURE 3-1       The contents of the document object in Internet Explorer 6.0
CHAPTER 3: Use Built-in JavaScript Classes            75

         The string literal can be used with any version of JavaScript.


    In JavaScript 2.0, you can even go so far as to assign the variable a String data type, while
using a string literal to create the object.
var title : String = "How To Do Everything with Paper Clips";                                               3
    It’s important to remember that creating a String object using a string literal still allows you
to use all the properties and methods provided by the object.
var myString = "This is a string literal";
var myOtherString = 'So is this, using single quotation marks.';
document.write (""" + myString + "" = " +
    myString.length + " characters<br>");
document.write ("'" + myOtherString + "' = " +
    myOtherString.length + " characters<br>");

    Length is a property of the String object. Accessing the length property results in the actual
length of the string, as we can see in the following browser output.
76      How to Do Everything with JavaScript


     Create a String Object Using the String Data Type
     JavaScript 1.1 introduced the ability to create strings using the String class constructor.
     var hometown = new String("Chicago");

         By passing the text of the string to be created into the constructor, we end up with the
     hometown variable being a String. There are almost no advantages to creating strings like this,
     and you will very rarely see it done.

     Use the String Object’s Built-in Functionality
     String objects are given a number of predefined functions, which allow you to perform all sorts
     of manipulations on them. Table 3-5 lists the most common String methods.
               Four of the methods listed in Table 3-5 work with regular expression patterns. We
               examine regular expressions in the section “Understand the Basics of Regular
               Expressions,” later in this chapter.



      Method                            Purpose
      charAt (index)                    Returns one character from the string
      charCodeAt (index)                Returns the ASCII code of one character from the string
      concat (string)                   Joins two strings together
      indexOf (string, index)           Finds the first occurrence of one string inside another
      lastIndexOf (string, index)       Finds the last occurrence of one string inside another
      match (regexp)                    Searches the string for the regular expression pattern, and returns
                                        any matches
      replace (regexp, newString)       Searches the string for the regular expression pattern, and replaces
                                        any matches with the string provided
      search (regexp)                   Searches the string for the regular expression pattern, and returns the
                                        index of the first match
      split (separator, limit)          Splits a single string into an array of substrings, based on a separator
                                        character or regular expression
      substring (start, end)            Returns a part of a string
      toLowerCase ()                    Returns the string as lowercase characters
      toString ()                       Same as valueOf (); returns the string
      toUpperCase ()                    Returns the string as uppercase characters
      valueOf ()                        Returns the string
      TABLE 3-5         Common String Object Methods
CHAPTER 3: Use Built-in JavaScript Classes           77

    Each of the methods listed in Table 3-5 can be accessed from any String object using the
dot operator.
var msg = "ERROR: Invalid User ID or Password<br>";
document.write ( "<b>Original message:</b> " +
    msg.valueOf() );
document.write ( "<b>Upper case:</b> " +                                                                3
    msg.toUpperCase() );
document.write ( "<b>Lower case:</b> " +
    msg.toLowerCase() );
document.write ( "<b>Partial string:</b> " +
    msg.substring(20, 22) + "<br>" );
document.write ( "<b>Single character:</b> " +
    msg.charAt(17) + "<br>" );
document.write ( "<b>Search from beginning:</b> " +
    msg.toLowerCase().indexOf("sword") + "<br>" );
document.write ( "<b>Search from end:</b> " +
    msg.lastIndexOf("User ID") + "<br>" );

   As you can see from the following screenshot, all the String properties can be applied to the
msg object, since msg is of type String.
78      How to Do Everything with JavaScript

              More than one dot operator can appear in a single expression. Take the expression
              “msg.toLowerCase()”—this expression will return the msg string as all lowercase
              characters. You can apply another String method to that expression, such as
              “msg.toLowerCase().indexOf(“sword”)”. Since the indexOf() method returns
              an integer, you could add a third dot operator to perform one of the Integer
              object methods.


Perform Mathematical Functions
     JavaScript provides one built-in class that cannot actually be used to create an object—Math. The
     purpose of the Math class is to provide all sorts of mathematical functions and constants. Since all
     the members of the Math class are defined as static, you can call them directly using the Math object.
          Attempting to create an object based on the Math class results in an error in JavaScript. You
     call Math’s static members using the dot operator, just as you would with the instance members of
     any other class. Table 3-6 lists the names of all the predefined constants provided by the Math class.
          The Math class also provides a number of methods that are useful for performing complex
     mathematical calculations, as shown in Table 3-7.
          For example, if we wanted to create some JavaScript code that took advantage of the
     mathematical constants and functions provided by the Math object, we could do the following:
     // area of a 12-inch circle, (PI * r^2)
     var area = Math.PI * Math.pow (12/2, 2);

     // length of the long side of a right angle triangle
     //     assume, 5 inch base and 7 inches high, (a^2 + b^2 = c^2)
     var longside = Math.sqrt( Math.pow(5,2) + Math.pow(7,2) );




                             Instance Members Versus
                             Static Members
       By default, properties and methods of a class will be defined as instance members. This
       means that they can only be accessed within the instance of an object based on that class.
       These objects are created using the new keyword, and a new copy of the class’s instance
       members will be created for each new object created. If you create 100 objects based on a
       class, you have 100 separate copies of each method and variable. Changing the value of one
       of the copies does not affect the others.
           Properties and methods of a class can optionally be defined as static members. Static
       members can only be accessed directly from the class and are not part of instances created
       based on that class. In essence, static class members are global, since only one version of
       that member ever exists, regardless of how many objects have been created from it.
CHAPTER 3: Use Built-in JavaScript Classes            79

    Constant                      Purpose
    E                             Euler’s constant, 2.7183
    LOG2E                         The base 2 logarithm of E
    LOG10E                        The base 10 logarithm of E
    LN2                           The natural logarithm of 2                                                        3
    LN10                          The natural logarithm of 10
    PI                            Pi, 3.1416
    SQRT2                         The square root of 2
    SQRT1_2                       The square root of one-half (0.5)
    TABLE 3-6         A List of the Static Constants Provided by the Math Class



Apply JavaScript’s Date-Handling Functions
   We already took a quick look at the Date class at the beginning of this chapter, but it is worth
   looking at it again in more detail. The Date class allows you to create Date objects containing
   any date you specify, or today’s date if you specify none. With a Date object, you can:

         ■     Retrieve specific parts of the date (the month, for instance)
         ■     Change or modify parts of the date
         ■     Convert the date between different string formats
         ■     Convert the date between different time zones


    Method                        Purpose
    abs (x)                       The absolute value of x
    acos (x), asin (x), atan      Trigonometry functions
    (x), atan2 (y, x), cos (x),
    sin (x), tan (x)
    ceil (x)                      Returns the next largest integer larger than x (or x, if it is an integer)
    exp (x)                       Returns the constant E to the power of x
    floor (x)                     Returns the next lower integer less than x (or x, if it is an integer)
    log (x)                       Returns the natural logarithm of x
    max (x, y)                    Returns x or y, whichever is highest
    min (x, y)                    Returns x or y, whichever is lowest
    pow (x, y)                    Returns x to the power of y
    TABLE 3-7         Static Methods of the Math Object
80      How to Do Everything with JavaScript


      Method                       Purpose
      random ()                    Returns a pseudorandom number between 0 and 1
      round (x)                    Rounds x to the nearest integer
      sqrt (x)                     Returns the square root of x
      TABLE 3-7        Static Methods of the Math Object (continued)



                 Early versions of JavaScript restricted the Date object so that it could not handle dates
                 before January 1, 1970. This was corrected in version 1.3 of the language. Dates can
                 now range between –100 million and +100 million days of January 1, 1970, which is
                 approximately 270,000 years into the past and future.

          There are no such things as date literals in JavaScript, so a Date object can only be created out
     of the Date class. The constructor for the Date class accepts a number of different input parameters.
     var   holiday = new Date ("July 4, 2010");
     var   newyears = new Date (2010, 12, 31);
     var   today = new Date ();
     var   midnight = new Date (2010, 12, 31, 23, 59, 59, 999);

          As we can see in the code, the Date constructor can attempt to interpret a date written as a
     string literal. You can also pass in the year, month, and day as integers. You can even specify the
     date and time down to the millisecond. If no parameters are provided, the object is set to today’s
     date by default.
          Table 3-8 lists all the methods supported by the Date object. Using these methods, you can
     extract specific parts of a date, change the date, or convert it to different formats.

      Method                       Purpose
      getDate ()                   Returns the day of the month (1–31) according to local time
      getDay ()                    Returns the day of the week (1–7) according to local time
      getFullYear ()               Returns the four-digit year according to local time
      getHours ()                  Returns the hour component of the time according to local time
      getMilliseconds ()           Returns the milliseconds component of the time according to
                                   local time
      getMinutes ()                Returns the minutes component of the time according to local time
      getMonth ()                  Returns the month (0–11) according to local time; 0 is January, 1 is
                                   February, and so on
      getSeconds ()                Returns the seconds component of the time according to local time
      TABLE 3-8        Methods of the Date Object
CHAPTER 3: Use Built-in JavaScript Classes               81

Method                      Purpose
getTime ()                  Returns the numeric value corresponding to the time
getTimezoneOffset ()        Returns the number of hours the current time is offset from
                            Universal time (Greenwich mean time)
getUTCDate ()               Returns the day of the month (1–31) according to Universal time
                                                                                                                3
getUTCDay ()                Returns the day of the week (1–7) according to Universal time
getUTCFullYear ()           Returns the four-digit year according to Universal time
getUTCHours ()              Returns the hour component of the time according to Universal time
getUTCMilliseconds ()       Returns the milliseconds component of the time according to Universal time
getUTCMinutes ()            Returns the minutes component of the time according to Universal time
getUTCMonth ()              Returns the month (0–11) according to Universal time; 0 is January,
                            1 is February, and so on
getUTCSeconds ()            Returns the seconds component of the time according to Universal time
getYear ()                  Returns the year according to local time
parse (string)              Parses a date string and returns the number of seconds since January 1, 1970
setDate ()                  Sets the day of the month (1–31) according to local time
setFullYear ()              Sets the four-digit year according to local time
setHours ()                 Sets the hour component of the time according to local time
setMilliseconds ()          Sets the milliseconds component of the time according to local time
setMinutes ()               Sets the minutes component of the time according to local time
setMonth ()                 Sets the month (0–11) according to local time; 0 is January, 1 is February,
                            and so on
setSeconds ()               Sets the seconds component of the time according to local time
setTime ()                  Sets the numeric value corresponding to the time
setUTCDate ()               Sets the day of the month (1–31) according to Universal time
setUTCFullYear ()           Sets the four-digit year according to Universal time
setUTCHours ()              Sets the hour component of the time according to Universal time
setUTCMilliseconds ()       Sets the milliseconds component of the time according to
                            Universal time
setUTCMinutes ()            Sets the minutes component of the time according to Universal time
setUTCMonth ()              Sets the month (0–11) according to Universal time; 0 is January, 1 is
                            February, and so on
setUTCSeconds ()            Sets the seconds component of the time according to Universal time
setYear ()                  Sets the year according to local time
toDateString()              Returns a string representing the date portion of the specified Date object
toGMTString ()              Converts a date to a string, using the Internet GMT conventions
TABLE 3-8        Methods of the Date Object (continued)
82      How to Do Everything with JavaScript


      Method                         Purpose
      toLocaleDateString()           Converts the date portion of a date to a string, using the current locale’s
                                     conventions
      toLocaleString ()              Converts a date to a string, using the current locale’s conventions
      toLocaleTimeString()           Converts the time portion of a date to a string, using the current locale’s
                                     conventions
      toString ()                    Returns a string representing the specified Date object
      toTimeString()                 Returns a string representing the time portion of the specified Date object
      toUTCString ()                 Converts a date to a string, using the Universal time convention
      UTC ()                         Returns the number of milliseconds in a Date object since January 1, 1970,
                                     00:00:00, Universal time
      valueOf ()                     Returns the primitive value of a Date object
      TABLE 3-8        Methods of the Date Object (continued)



        The constructor for the Date class accepts four formats. The actual date the object represents
     depends on the number and type of parameters passed.

      To create a date based on...   Use this...
      A date string                  new Date (“January 1, 2008”)
      Date components                new Date (2008, 0, 31)
      Date and time components       new Date (2008, 0, 31, 12, 0, 0, 0)
      Milliseconds since             new Date (1034214221530)
      January 1, 1970
      Current date and time          new Date ()


               JavaScript expects numbers in the range of 0 to 11 to represent months of the year.
               January is month 0, February is month 1, and so forth.


Convert Strings into Numbers
     JavaScript contains two built-in ways to convert numbers embedded in strings (like "32") into
     actual numbers that can be used in mathematical equations (like 32)— parseInt () and parseFloat ().
         As their names imply, the parseInt function will return an integer (a number without a decimal
     portion), and parseFloat will return a floating-point number (including any decimal portion).

     Use the parseInt and parseFloat Functions
     JavaScript provides parseInt and parseFloat to help you convert numbers inside strings into
     actual number data types. This is an important technique when it comes to Internet web pages,
     since data read in from URLs and forms usually arrives as strings. Here is how they work:
CHAPTER 3: Use Built-in JavaScript Classes        83

1. Start by defining a variable to contain your string.
    var myString;

2. Assign a string that contains a valid number to that variable. This number does not have
   to be an integer.
    var myString;                                                                                  3
    myString = "3.14159265358979323846";                  // The value of Pi...

3. Define a variable to contain your integer.
    var myString, myInteger;
    myString = "3.14159265358979323846";                  // The value of Pi...

4. Call the parseInt () function on the string, and assign the value to the integer.
    var myString, myInteger;
    myString = "3.14159265358979323846";                  // The value of Pi...
    myInteger = parseInt (myString);

5. The parseInt () function should return the value 3 from the string defined in this
   example. We can verify this with a call to the alert message box.
    var myString, myInteger;
    myString = "3.14159265358979323846";                  // The value of Pi...
    myInteger = parseInt (myString);
    alert (myInteger);




6. What would happen if myString were not a valid number? Let’s modify it and find out.
    var myString, myInteger;
    myString = "Madrid, Spain"; // The value of Pi...
    myInteger = parseInt (myString);
    alert (myInteger);
84      How to Do Everything with JavaScript


         The parseFloat () function works in a similar fashion to parseInt (), except the digits after the
     decimal place are included. We can verify this by changing the function name.
     var myString, myInteger;
     myString = "3.14159265358979323846";                 // The value of Pi...
     myInteger = parseFloat (myString);
     alert (myInteger);




Prepare Text Before Sending to Web Server
     Every web page on the Internet has a unique URL (uniform resource locator). Even web pages
     stored on your hard drive have their own unique URL. The following are a few examples of URLs:

      URL                                           URL Description
      http://www.amazon.com/                        Default web page of Amazon.com
      news:comp.infosystems.www.servers.unix        Usenet newsgroup
      file:///C:/temp/test.html                     File residing on user’s hard drive




                                  Uniform Resource Locator (URL)
                                  Limitations
       The URL format only accepts the following characters in the URL string:

            ■   Letters—a to z
            ■   Numbers—0 to 9
            ■   Marks—$ - _ + ! * ‘ ( ) ,
            ■   Special characters reserved for special purposes—; / ? : @ = &

           No other characters can appear in a URL. And the special characters can only be used in
       their designated roles. Characters that fall outside these rules must be properly escaped, as
       described in “Use the escape and unescape Functions.”
CHAPTER 3: Use Built-in JavaScript Classes             85

     Imagine a file with a long and uniquely creative name, such as We're #1 & proud of it; no ifs
ands or buts!.htm. Windows does allow such a name for a file. But when it comes to accessing
this file through a browser, we’re going to have problems. The space, #, &, !, and ; characters are
not allowed in the URL naming scheme. In order to access the file, it will first have to be escaped,
as described in the following section.
                                                                                                            3
Use the escape and unescape Functions
Escaping a file is the process of converting all the invalid characters into specially encoded
symbols before sending the URL to the server to process. To escape a filename, we must use
the escape function built into JavaScript.

    1. Start with a string that has some invalid characters inside it.
        var filename;
        filename =
            "We're #1 & proud of it; no ifs ands or buts!.htm";

   2. Define a variable to contain the escaped character sequence.
        var filename, newFilename;
        filename =
            "We're #1 & proud of it; no ifs ands or buts!.htm";

   3. Assign the result of the escape function on the string to the new variable.
        var filename, newFilename;
        filename =
            "We're #1 & proud of it; no ifs ands or buts!.htm";
        newFilename = escape(filename);

   4. To examine the results of the escape() function, we should display it to the user
      using an alert box.
        var filename, newFilename;
        filename =
            "We're #1 & proud of it; no ifs ands or buts!.htm";
        newFilename = escape(filename);
        alert (newFilename);
86      How to Do Everything with JavaScript


Decide When to Use Regular Expressions
     Regular expressions are a powerful search-and-replace technique that is widely used in other
     environments (such as Unix and Perl), but rarely used in JavaScript. Perhaps if more programmers
     knew about the existence of regular expressions in JavaScript, their use would catch on.
              JavaScript only started supporting regular expressions in version 1.4 of the language,
              which means they will only work in Netscape 4 or Internet Explorer 4 web browsers,
              or subsequent releases.

         A regular expression is a sequence of characters written using a special regular expression
     language, which can be used to match patterns in other strings. To give you an idea of how
     powerful the regular expression pattern matching capability is, I wrote a little JavaScript program
     (primarily using the String object’s substring() method) that checks to see if a string matches the
     standard telephone number format—(XXX) XXX–XXXX, where X represents any number from
     0 to 9. That program contained 69 lines of JavaScript code, just to check a phone number.
         Fortunately, the program can be rewritten using regular expressions, as follows:
     var phonenum = "(415) 555-1212";
     var pattern = /^(d{3}) d{3}-d{4}$/;
     document.write ("Trying to match "" + phonenum + "" with pattern " +
         pattern.toString() + "...<br><br>");
     if (pattern.test (phonenum)) {
         document.write ("This is a valid phone number.");
     } else {
         document.write ("This is NOT a valid phone number.");
     }

         Running this JavaScript results in this output to the browser window.
CHAPTER 3: Use Built-in JavaScript Classes           87

   As you can see, substantial time and effort can be saved by using regular expressions to
check a string against a pattern. We’ll look at the workings of this code in the next section.

Understand the Basics of Regular Expressions
Regular expressions in JavaScript deal with pattern matching. Other programming languages
allow regular expressions to search and replace text, but JavaScript programmers do not have that         3
luxury. Despite this, regular expressions are still a powerful way to search for complex patterns.
For instance, you can use them to

    ■   Validate telephone numbers in more than one format
    ■   Extract all the numbers from a string
    ■   Ensure a date is entered in the valid format
    ■   Verify an e-mail address has the proper format

    As we saw in the preceding code example, the regular expression pattern is quite complex
and can be a little bit intimidating.
var pattern = /^(d{3}) d{3}-d{4}$/;

    As I mentioned, regular expressions have their own language. There are many, many symbols
and special characters to represent different things. The following are some general rules:

    1. We start with defining a variable for our regular expression pattern.
        var pattern;

   2. The forward slash (/) signifies the start and end of a regular expression literal in
      JavaScript. Regular expression literals allow us to create a regular expression object
      without having to use the RegExp class.
        var pattern = //;

   3. The caret (^) and dollar sign ($) represent the start and end of a line. They also represent
      the start and end of a string. If we only wanted to match the pattern to part of the string,
      we would omit them. Similarly, if we wanted to test specifically for a pattern at the
      beginning of a long string, we could just use the caret (^) by itself. The following pattern
      only matches an empty string (“”) so far.
        var pattern = /^$/;

   4. The d represents a single digit. If we add the d to our pattern, it would only match
      a one-character string containing a number from 0 to 9.
        var pattern = /^d$/;
88        How to Do Everything with JavaScript


          5. If we want to match more than one number (as we do with a phone number), we can put
             multiple d tokens together; ddd would represent three numbers. We can also specify
             the number in curly braces: d{3}.
                var pattern = /^d{3}$/;

          6. Other characters in the pattern, such as spaces and hyphens, represent only themselves.
             So the following pattern would match 999-999-9999, which is one way to represent
             a telephone number.
                var pattern = /^d{3}-d{3}-d{4}$/;

           7. Since the parentheses characters have special meaning in regular expression syntax,
              to include them we will need to escape them with a backslash: ( and ). That gives
              us a pattern that matches (999) 999-9999, which is what we want.
                var pattern = /^(d{3}) d{3}-d{4}$/;

         There are many special tokens in the regular expression syntax to match different sets of
     characters. The tokens listed in Table 3-9 are the basic set.


      Character       Meaning
                     Either denotes the start of a special token (for example, d matches a digit) or indicates
                      a special character is to be treated literally ( * matches an asterisk)
      ^               Matches the beginning of a line; also matches the beginning of every string
      $               Matches the end of a line; also matches the end of every string
      *               A special quantifier, meaning the preceding token or group of tokens must match zero
                      or more times
      +               A special quantifier, meaning the preceding token or group of tokens must match one
                      or more times
      ?               A special quantifier, meaning the preceding token or group of tokens must match zero
                      or one time only
      .               Matches any single character except the newline character (n)
      (abcd)          Matches “abcd” and remembers the match
      car|bus         Matches either “car” or “bus”
      {3}             Matches exactly three occurrences of the preceding token or group of tokens
      {3,}            Matches three or more occurrences of the preceding token or group of tokens
      {4,8}           Matches four to eight occurrences of the preceding token or group of tokens
      [abcdef]        Matches any one of the characters a through f
      [a-f]           Matches any one of the characters a through f
      [a-zA-Z0-9]     Matches any single alphanumeric character
      TABLE 3-9       Regular Expression Syntax in JavaScript
CHAPTER 3: Use Built-in JavaScript Classes          89

 Character         Meaning
 [^aeiou]          Matches everything except a, e, i, o, and u
 d                Matches a digit; identical to the pattern [0-9]
 D                Matches a nondigit; identical to the pattern [^0-9]
 s                Matches a space character (there are eight defined space characters)                        3
 S                Matches a nonspace character
 t                Matches a tab
 n                Matches a new line
 r                Matches a carriage return
 w                Matches any alphanumeric (word) character (a–z and 0–9), including underscore ( _ );
                   identical to the pattern [a-zA-Z0-9_]
 W                Matches any nonword character; identical to the pattern [^a-zA-Z0-9_ ]
 0                Matches null
 TABLE 3-9        Regular Expression Syntax in JavaScript (continued)



Create Patterns with a RegExp Object
We’ve already seen how to create patterns with a regular expression literal. A regular expression
literal starts and ends with a forward slash (/), as follows:
var zipCodePattern = /^d{5}(-d{4})?$/;

   JavaScript also provides a class named RegExp to create these patterns as well. We can
rewrite the pattern using this class’s constructor, as follows:
var zipCodePattern = new RegExp ("^d{5}(-d{4})?$");

            The backslash ( ) character needs to be escaped anytime it is included in a string,
            and the RegExp constructor is no exception. The double backslash ( ) represents
            the escaped backslash character.

    The RegExp object provides two main methods for performing its search and match
functions: test() and exec(). Table 3-10 lists the most common methods of the RegExp object.


 Method            Purpose
 compile ()        Compiles a regular expression
 exec ()           Searches a string for a pattern and returns all the matches
 test ()           Compares a string to a pattern and returns true or false based on the result
 TABLE 3-10        Methods of the RegExp Object
90      How to Do Everything with JavaScript


         Once a RegExp object has been created, JavaScript makes it very easy for you to test that
     pattern against any string.
     var myPattern = new RegExp ("hat.*hat");
     document.write ("Pattern 1: "hat.*hat"<br>");
     document.write (myPattern.test ("That is a nice hat.") + "<br>" );
     document.write (myPattern.test ("I love your hat!") + "<br><br>" );

     var myPattern2      = new RegExp ("w+sw+");
     document.write      ("Pattern 2: "w+sw+"<br>");
     document.write      (myPattern2.test ("Jackie Gleason") + "<br>" );
     document.write      (myPattern2.test ("Cher!") + "<br>" );

        The results of this pattern checking can be seen in Figure 3-2.




      FIGURE 3-2     Creating and testing patterns using the RegExp object
CHAPTER 3: Use Built-in JavaScript Classes               91

Understand JavaScript 2.0’s Powerful New Data Types
   Up until this point, we have been examining the classes supported by the vast majority of web
   browsers used today. JavaScript 2.0 introduced a number of new classes, which were listed
   earlier, in Table 3-3. The way objects are created and accessed remains virtually the same from
   previous versions of JavaScript, with the new and dot (.) operators doing most of the work.
       In this section, we will examine some of these new data types and learn how their powerful
                                                                                                                 3
   functionality can be applied in JavaScript programs.
            The rest of the code in this chapter is designed to work in environments that support
            JavaScript 2.0 and will not work elsewhere.

   Use the Boolean, Integer, and Number Data Types
   There are three basic data types in JavaScript known as primitives: numbers, strings, and Boolean
   values. All other data types are built on these three basic building blocks.
       We already examined the String data type earlier in this chapter. The String object provides
   many methods to assist in manipulating strings, including searching (indexOf), extracting a portion
   of a string (substring), and determining the length of a string (length).
       The Boolean data type is very simple compared to String. You can use it to store a Boolean
   value (true or false), and you can retrieve that Boolean value. That’s pretty much it. There is
   really no reason to use the Boolean class in your programming, as the Boolean literals are easier
   to create and just as useful.
   var isFinished : Boolean = false;
   var paidToll : Boolean = true;

       The number primitive is actually represented by two JavaScript data types: Number and
   Integer. The only difference between the two is that an Integer data type cannot contain a decimal
   portion. Other than that, the two classes are identical. Again, for the most part I will continue to
   use numeric literals to create simple numbers, for the sake of convenience.
   var counter : Integer = 0;
   var invoice_amount : Number = 12363.22;


   Use the char Data Type
   Perhaps the one thing that distinguishes the char data type more than anything else is the odd
   way it was named. This data type does not capitalize its initial letter and its name is not a complete
   word. (In fact, the ECMA technical committee wanted to call it the “Character data type” at one
   point during the language’s development, which would have been more in line with how other
   classes were named.)
       The char data type represents only single 16-bit Unicode characters. Some languages call this
   a byte, and it is normally used when allocated memory space is a prime consideration. It exists
92      How to Do Everything with JavaScript


     for compatibility with other languages, and does not have much practical purpose in modern-day
     web programming.

     Use the Object Data Type
     Every class in JavaScript—both user-defined and system-defined—is a member of this data type.
     If you wanted to create a variable that could hold any object in the system, this would be the data
     type to use.
     var myObject : Object = new Date ();
     myObject = new String ("This is a string");
     myObject = new Car (2002, "Ferrari", "Testarosa", "Cherry red");

         The myObject variable, once defined as a member of the Object data type, can act as an
     object for any other class in the system. This ability, where one class can act as an object for
     another related class, is known in object-oriented programming as polymorphism. Inheritance
     and polymorphism are discussed in Chapter 5, when we create our own classes.

     Understand Special Data Types
     JavaScript 2.0 also contains some data types that you may not use in everyday programming—
     or may not ever use. As you learned in the previous chapter, functions can return a value. And in
     JavaScript 2.0, you can assign a data type to that value.
     function addTwo (num1 : Number, num2 : Number) : Number {
         return num1 + num2;
     }

     Use the Void Data Type
     Well, you may sometimes need to define a function that does not return any result. The following
     program does its task and exits without returning a value.
     function errorMessage (msg : String) {
         alert ("A serious error occurredn" + msg +
                 "nPress OK to continue.");
         return;
     }

           Defining a function without any return value, as in this code, is certainly valid. But by doing
     so you have left the return value type ambiguous. Your function can either return a value or not,
     neither of which is an error. Leaving off the data type from the function only tells the system that
     the type of the return value is unknown.
           If you want to explicitly state that your function does not return a value, you can use the Void
     data type. A function defined as type Void is not allowed to return a value—it is an error condition
     if it does.
CHAPTER 3: Use Built-in JavaScript Classes            93

function errorMessage (msg : String) : Void {
    alert ("A serious error occurredn" + msg +
            "nPress OK to continue.");
    return;
}
                                                                                                          3
Use the Never Data Type
Or perhaps your function reports the error and then stops running completely. You can’t do
this in a web browser environment, but you can in other environments, such as on the server.
Functions that cause the program to exit should have the data type of Never, as in “This function
will never return.” The following code example is written using JavaScript in an IIS web server
environment.
function errorMessage (msg : String) : Never {
    response.write ("A serious error occurredn" + msg +
           "nPress OK to continue.");
    response.end;
}

Use the Null Data Type
Finally, the Null data type can only contain one valid value—null. I honestly cannot think of
a reason why you would wish to do this.
var useless : Null = null;

    Well, we have looked at every object and data type that JavaScript allows us to use—almost,
that is. We haven’t talked about arrays yet. JavaScript 2.0 has introduced five new array classes.
In the next chapter, we will examine arrays and see how they can be used to store tons of easily
accessible data.
This page intentionally left blank
Organize Data
Chapter 4   into Arrays
96      How to Do Everything with JavaScript


     How to...
         ■   Create an Array object
         ■   Set and retrieve values in an array
         ■   Use multidimensional arrays
         ■   Use JavaScript 2.0’s enhanced arrays

     In Chapter 2, we examined how our programs could use variables to store data for later retrieval.
     There is almost no limit to the number of variables a program can define. The number is limited only
     by the programmer’s ability to remember what each variable does.
          But you may sometimes be faced with the task of having to store dozens, or even hundreds, of
     related values into variable names for later use. For instance, how would you store the following?

         ■   The names of the 50 U.S. states
         ■   The names of the months of the year
         ■   The album titles of the CDs in your collection
         ■   The list of products in your store inventory

          You may be able to come up with ways to store the first two lists (state and month names) in
     JavaScript code, perhaps by assigning each name its own variable (for example, var Nebraska =
     "Nebraska"). But while this is possible, it’s not that practical. What’s the point of having variables
     (or even constants) whose value won’t ever change and whose value matches the variable name?
          So then, how could you store those types of lists (album titles and products in inventory)? After
     all, these lists could get quite large (your store could carry hundreds of products), the values can
     (and do) change, and even the length of the list will be different over time.
          JavaScript provides Array objects to handle lists of data. Arrays can handle long lists of data
     whose values can be easily retrieved or modified. Arrays can also grow or shrink as required.
     for (counter = 0; counter < 50; counter ++) {
         document.write ("State #" + counter + ": " +
             statesArray[counter]);
     }

          In the code, the variable statesArray contains an array of the 50 U.S. state names. We can
     access this array using its index (which ranges in value from 0 to 49) using the square brackets
     ([]) operator.
     statesArray[counter];

         Of course, the code neglects to show how the Array object was created. There are two ways
     to create Array objects:

         ■ The Array class
         ■ The Array literal
CHAPTER 4: Organize Data into Arrays             97

       Unfortunately, there is a little inconsistency between the official specifications and the way
   each of the major browser manufacturers has implemented arrays in JavaScript. In this chapter, we
   will examine how arrays are created and how to create code that works across all browsers. We will
   also take a look at some of the exciting improvements in arrays in JavaScript 2.0.


Create an Array Object
   There are three ways to create an Array using the JavaScript Array class:                                 4
       ■ new Array ()
       ■ new Array (size)
       ■ new Array (element1, element2, ..., elementN)

   Create an Empty Array
   Passing no arguments to the constructor of the Array class creates an empty array, also called an
   array of zero length. (In JavaScript, the number of items inside an array is known as its length.)
   We can then populate the array manually, as follows.

       1. We start by defining a variable to contain our array.
           var months;

      2. We then create a new Array object using the new operator.
           var months = new Array();

      3. We manually assign a value to the first index of the array. Indexes start at value 0.
           var months = new Array();
           months[0] = "January";

      4. Now our array has a length of 1. We can then populate the rest of the values for our array.
           var months = new Array();
           months[0] = "January";
           months[1] = "February";
           months[2] = "March";
           months[3] = "April";
           months[4] = "May";
           months[5] = "June";
           months[6] = "July";
           months[7] = "August";
           months[8] = "September";
           months[9] = "October";
           months[10] = "November";
           months[11] = "December";
98   How to Do Everything with JavaScript


     5. We now have an array that can be accessed by the rest of our program using only its
        numerical index.
         var months = new Array();
         months[0] = "January";
         months[1] = "February";
         months[2] = "March";
         months[3] = "April";
         months[4] = "May";
         months[5] = "June";
         months[6] = "July";
         months[7] = "August";
         months[8] = "September";
         months[9] = "October";
         months[10] = "November";
         months[11] = "December";

         for (var i = 0; i < 12; i++) {
             document.write (months[i] + "<br>");
         }

     6. As you can see here, JavaScript is able to store a list of related values (months of the
        year) into a single variable, and then easily access each of those values for later use.
CHAPTER 4: Organize Data into Arrays                99

    7. A list such as this (months of the year) is convenient if you want your program to convert a
       numerical month into its string equivalent. Luckily, the Date object’s getMonth() function
       returns the month in a range of 0 to 11, so we do not even have to adjust the value before
       using it.
        var today = new Date();
        var monthnum = today.getMonth();
        document.write ("Today is a lovely " +
            months[monthnum] + " day.");                                                                        4




Specify an Initial Array Length
JavaScript allows you to specify an initial length for your array by passing a single integer as
a parameter.
var months = new Array(12);

    Setting the length of an array in advance like this provides few advantages in JavaScript 1.5, since
arrays grow automatically. Perhaps the one benefit it does provide is to remind you how large an array
you intended to define.
    The length of an array can also be set within the program by altering the length property of
the Array object.
var months = new Array();
months.length = 12;
100      How to Do Everything with JavaScript


      Create and Initialize an Array in One Line of Code
      Looking at the months array defined earlier, we ended up writing 13 lines of code just to create and
      initialize the array. It would be nice if we could create this same array using only one line of code.
           Of course, I wouldn’t have mentioned it if JavaScript couldn’t do it...
      var months = new Array ("January", "February", "March", "April",
          "May", "June", "July", "August",
          "September", "October", "November", "December");

          The constructor of the Array class also accepts a comma-separated list of the initial values of
      the array. The first item listed is assigned the index 0, the next item becomes index 1, and so on.
          This is especially helpful for long lists of items. For instance, if we needed an array containing
      the 50 U.S. states, it would be much easier to create it in one line of code, as opposed to 51 or more.
      var USStates = new Array ("Alabama", "Alaska", "Arizona",
          "Arkansas", "California", "Colorado", "Connecticut",
          "Delaware", "Florida", "Georgia", "Hawaii", "Idaho",
          "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky",
          "Louisiana", "Maine", "Maryland", "Massachusetts",
          "Michigan", "Minnesota", "Mississippi", "Missouri",
          "Montana", "Nebraska", "Nevada", "New Hampshire",
          "New Jersey", "New Mexico", "New York", "North Carolina",
          "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania",
          "Rhode Island", "South Carolina", "South Dakota", "Tennessee",
          "Texas", "Utah", "Vermont", "Virginia", "Washington",
          "West Virginia", "Wisconsin", "Wyoming");

      Use Array Literals
      Just as JavaScript provides ways to create numbers, strings, and regular expressions without having
      to manually create an object, you can do the same thing with arrays.
      var months = ["January", "February", "March", "April",
          "May", "June", "July", "August",
          "September", "October", "November", "December"];




                              Break Long Lines of Code
                              into Several Lines
        To make long lines of code more readable (to yourself and other programmers looking at
        your code), it is a wise idea to include a carriage return before the text scrolls off the right
        side of the screen. JavaScript supports code written over several lines, as long they are placed
        in the proper places. JavaScript will ignore extra spaces and new line characters, as it considers
        the semicolon (;) the actual end of the statement.
CHAPTER 4: Organize Data into Arrays             101

    The square brackets in the preceding code cause JavaScript to interpret their contents as the
contents of a new array. It is equivalent to creating an array using the proper constructor syntax.
var months = new Array("January", "February", "March", "April",
    "May", "June", "July", "August",
    "September", "October", "November", "December");

   All the properties and methods of the Array object are available to objects created using the
Array literal.                                                                                                   4
Call the Properties and Methods of the Array Object
The Array object in JavaScript exposes only three properties. Two of those properties are only set
when the array being called is the result of a regular expression pattern match, as discussed in
Chapter 3. The length property (which is available to all arrays) is the only one of the three that can
be modified, as it indicates the current length of the array.

 Property         Description
 index            Related to regular expression pattern matching; contains the index of the matching
                  substring (read-only)
 input            Related to regular expression pattern matching; contains the original string against which
                  the match was made (read-only)
 length           Retrieves or sets the length of the array


            Not every element in an array has to contain a value. You could just as easily create
            an array that skips every second index number, or skips an arbitrary number of index
            numbers.

    The length property takes into account the number of empty (unused) indexes in an array as
well as the number of elements an array contains. So if you skip a large amount of index numbers,
the length property will be much larger than the number of elements.
var employee = new Array();
employee[127756] = "Tom Jones";
alert(employee.length);

    This code returns 127,757 as the length of the array, since that is the number of elements
(including empty ones) from 0 through 127,756.
102      How to Do Everything with JavaScript


           The Array object also contains a number of helpful methods to make managing the contents
      of the array easier for the programmer, as we can see in Table 4-1.
           Using the methods of the Array object listing in Table 4-1 provides several advanced modification
      functions on the contents of arrays. Four of the methods allow us to treat arrays like either a call stack
      or a queue.
           In programming, a call stack is similar to a stack of pancakes. The last pancake added to the
      top of stack has to be the first pancake taken off (or eaten). This arrangement is sometimes called
      the last in, first out (LIFO) method.
           A queue is much like a line at a bank, where the first person to enter the line is the first person
      served. Not surprisingly, this arrangement is sometimes called the first in, first out (FIFO) method.

       Method                         Description
       pop() and push()               Last in, first out (LIFO); similar to a call stack
       shift() and unshift()          First in, first out (FIFO); similar to a queue


           There are several other interesting methods that allow you to convert an array into a single
      string, split arrays into subarrays, or even concatenate two or more arrays together.
           In the following code, we create a number of arrays using the Array class.
      var MainMenu = new Array("File", "Edit", "View",
          "Window", "Help");
      var FileMenu = new Array("New", "Open", "Close", "Save", "Exit");
      var EditMenu = new Array("Undo", "Repeat", "Cut", "Copy", "Paste");
      var ViewMenu = new Array("Normal", "Web Layout", "Outline");
      var WindowMenu = new Array("New Window", "Arrange All", "Split");
      var HelpMenu = new Array("Contents", "About", "Contact Us");

       Method                                         Description
       concat (array1, array2...arrayN)               Joins two or more arrays into a single array
       join (separator)                               Joins all the elements of an array into a single string, separated
                                                      by the separator indicated or a comma if none is specified
       pop ()                                         Returns the last element of an array and removes it
       push (element1, element2...elementN)           Adds one or more elements to the end of an array and
                                                      returns its new length
       reverse ()                                     Reverses the order of the elements in an array
       shift ()                                       Similar to pop (); returns the first element of an array and
                                                      removes it
       TABLE 4-1          Methods of the Array Object
CHAPTER 4: Organize Data into Arrays                 103

 Method                                    Description
 slice (begin, end)                        Creates a new array from a subsection of the existing array,
                                           as defined by the start and end indexes
 splice (index, howMany, element1,         Used to add or remove elements from an array
 element2...elementN)
 sort (functionName)                       Used to sort the elements of an array
 unshift (element1, element2...elementN)   Similar to push (); adds one or more elements to the
                                           beginning of an array and returns its new length                 4
 TABLE 4-1       Methods of the Array Object (continued)



    These arrays represent a menu of a hypothetical web site. We can use some of the methods
of the Array object on each of these arrays to modify it or extract bits of information.
//Creates a string of all elements of an array
// The array itself is unaffected
var MenuItemsStr = MainMenu.join(" | ");
document.write (MenuItemsStr + "<br><br>");

// Creates a new array that contains all elements of all arrays
// The existing arrays are all unaffected
var AllMenuItems = MainMenu.concat(FileMenu, EditMenu, ViewMenu,
    WindowMenu, HelpMenu);
document.write (AllMenuItems.join(", ") + "<br><br>");

// Reverses the order of elements in an array
// Modifies the existing array
MainMenu.reverse();
document.write (MainMenu.join(" | ") + "<br><br>");

// Creates a new array that contains a subset of an existing array
// The existing arrays are all unaffected
var ChildMenuItems = AllMenuItems.slice(MainMenu.length);
document.write (ChildMenuItems.join(" <font size=+3>||</font> ")
    + "<br><br>");
104      How to Do Everything with JavaScript


          The results from these array manipulations can be seen in the following screenshot.




 Set and Retrieve Values in an Array
      Elements inside the JavaScript Array object are accessed using the square brackets operator.
      var myArray = new Array();
      myArray[16] = "Some value";
      document.write (myArray[16]);

          The number inside the square brackets is called the index. You can think of an array as a
      series of parking spaces, numbered from 0 up to infinity. When the valet parks your car in one of
      those spaces, he has to keep note of the spot number in order to be able to find your car again.
          JavaScript arrays support using strings as indexes. When a string is used as an index, this is
      called a hash table.
      var FruitColors = new Array();
      FruitColors["Apple"] = "red";
      FruitColors["Banana"] = "yellow";
      FruitColors["Grape"] = "purple";
CHAPTER 4: Organize Data into Arrays                105

    Here, the string "Apple" is being used as the index to store the value "red". The string "Apple"
can be referred to as the key. Values stored in hash tables can be retrieved using the key, just as they
can with numerically indexed arrays.
document.write ("Apples are " + FruitColors["Apple"] + ".<br>");
document.write ("Bananas are " + FruitColors["Banana"] + ".<br>");
document.write ("Grapes are " + FruitColors["Grape"] + ".<br>");
     As we saw in Chapter 2, arrays can also be accessed using the for-in statement. The for-in
statement will loop through each of the elements in an array, returning the indexes or keys.                 4
var FruitColors = new Array();
FruitColors["Apple"] = "red";
FruitColors["Banana"] = "yellow";
FruitColors["Grape"] = "purple";

for (var fruit in FruitColors) {
    document.write (fruit + "s are " + FruitColors[fruit]
        + ".<br>");
}
    Here, the for-in loop iterates over the document.write() function three times, once for each
of the items in the array. The resulting output can be seen in Figure 4-1.




 FIGURE 4-1       The for-in loop iterates over a hash table.
106      How to Do Everything with JavaScript


          The same technique can be used for arrays with numerical indexes:
      var Players = new Array();
      Players[0] = "Jaime";
      Players[1] = "Mom";
      Players[2] = "Bart";
      Players[3] = "Liez'l";

      // Who do we have playing bridge?
      for (var name in Players) {
          document.write (name + ": ");
          document.write (Players[name] + " is playing bridge.<br>");
      }

          As you can see from the output in Figure 4-2, the for-in loop was able to iterate over each
      of our bridge players as well.




       FIGURE 4-2      The for-in loop iterates over an array.
CHAPTER 4: Organize Data into Arrays              107

Use Multidimensional Arrays
   The arrays that we have seen thus far in this chapter are sometimes called one-dimensional arrays.
   If you think of an array as a graphical table containing rows and columns, these one-dimensional
   arrays would only have one column, as shown in Figure 4-3.
        A two-dimensional array is an array that would contain more than one column when displayed
   as a graphical table. Two-dimensional arrays are used when you need to store more than one value
   for each item in your list. Figure 4-4 shows a graphical representation of a two-dimensional array.
        A three-dimensional array would look more like a cube, as an element of depth is added to          4
   the graph. Believe it or not, there are such things as four-dimensional arrays and higher. We live
   in a three-dimensional world, though, and it gets increasingly difficult to graphically display
   these complex sets of data.
        Some programming languages allow the definition of multidimensional arrays as a core
   feature of the language. Unfortunately, JavaScript is not one of them. If you want to define a
   multidimensional array in your JavaScript application, you will have to work within the
   limitations of the one-dimensional array.
        There are two techniques you can use to simulate a multidimensional array in JavaScript:

       ■ You can create parallel one-dimensional arrays.
       ■ You can create arrays of arrays.




    FIGURE 4-3      A graphical representation of a simple (one-dimensional) array
108      How to Do Everything with JavaScript




       FIGURE 4-4      A two-dimensional array contains multiple columns.


          One of the first arrays we looked at in this chapter was a listing of the months of the year.
      Let’s continue with that example. We started with the following one-dimensional array:
      var months = new Array ("January", "February", "March", "April",
          "May", "June", "July", "August",
          "September", "October", "November", "December");

          Let’s say we wanted to make a list of the following four items:

          ■   The months of the year
          ■   The birthstone related to each month
          ■   The color of each birthstone
          ■   The meaning associated with each birthstone

         Right now our array only contains months; if we were to arbitrarily add the three other things
      we wish to list, it would only add confusion to the array and make it harder to use.
      var months = new Array ("January", "February", "March", "April",
          "May", "June", "July", "August",
          "September", "October", "November", "December",
          "Garnet", "Amethyst", "Bloodstone or Aquamarine",
          "Diamond", "Emerald", "Pearl, Moonstone, or Alexandrite",
          "Ruby", "Sardonyx or Peridot", "Sapphire",
          "Opal or Tourmaline", "Topaz", "Turquoise or Lapis lazuli",
          "Red", "Purple", "Green/Red or Blue", "White/Clear",
          "Green", "Cream", "Red", "Light Green",
CHAPTER 4: Organize Data into Arrays              109

     "Blue", "Many Colors", "Orange/Brown", "Blue",
     "Constancy", "Sincerity", "Courage", "Innocence",
     "Love and success", "Health and longevity", "Contentment",
     "Married happiness", "Clear thinking", "Hope",
     "Fidelity", "Prosperity");

    As you can see from this code, simply adding the extra lists to the existing array is not the
best solution. Not only is it difficult for humans to read and understand, the programmer will also
have to be careful when creating the program so that things don’t get mixed up.                         4
    We can rewrite that messy array using four parallel arrays, as follows.
var months = new Array ("January", "February", "March", "April",
    "May", "June", "July", "August",
    "September", "October", "November", "December");

var stones = new Array ("Garnet", "Amethyst",
    "Bloodstone or Aquamarine", "Diamond", "Emerald",
    "Pearl, Moonstone, or Alexandrite", "Ruby",
    "Sardonyx or Peridot", "Sapphire", "Opal or Tourmaline",
    "Topaz", "Turquoise or Lapis lazuli");

var colors = new Array ("Red", "Purple", "Green/Red or Blue",
    "White/Clear", "Green", "Cream", "Red", "Light Green",
    "Blue", "Many Colors", "Orange/Brown", "Blue");

var meaning = new Array ("Constancy", "Sincerity", "Courage",
    "Innocence", "Love and success", "Health and longevity",
    "Contentment", "Married happiness", "Clear thinking",
    "Hope", "Fidelity", "Prosperity");

     The elements in each of the arrays match exactly to the same indexes in the other arrays, so
let’s say I want to find out something about the seventh month of the year. (Remember that the
arrays start at index 0, so the seventh month of the year is described at element number 6.)
document.write      ("The seventh month is <b>" + months[6]);
document.write      ("</b>. Its birthstone is <b>");
document.write      (stones[6] + "</b>. The " + stones[6]);
document.write      (" is a <b>" + colors[6] + "</b> colored stone, ");
document.write      ("and it means <b>" + meaning[6] + "</b>");
document.write      (" traditionally.<br>");

    In this manner, we are able to store several columns of information about each month, by
defining them in their own arrays. We can see the results of this code in our web browser
screenshot in Figure 4-5.
110      How to Do Everything with JavaScript




       FIGURE 4-5      The use of parallel arrays can simulate two-dimensional arrays.


          The other method of creating a multidimensional array is to create an array that contains
      other arrays—an array of arrays, as this is called.
          To create an array of arrays, you would go through the following steps.

          1. First, define the four arrays, just as you would if you were defining parallel arrays.
              var   months =    new Array ("January", "February", ...);
              var   stones =    new Array ("Garnet", " Amethyst", ...);
              var   colors =    new Array ("Red", "Purple", ...);
              var   meanings    = new Array ("Constancy", "Sincerity", ...);

         2. Next, define a master array that will hold all four arrays.
              var marray = new Array();

         3. Then, assign each of the four arrays that contain the data to this master array.
              var marray = new Array();

              marray[0] = months;
CHAPTER 4: Organize Data into Arrays                   111

        marray[1] = stones;
        marray[2] = colors;
        marray[3] = meanings;

    4. You should then modify your program to access the subarrays using the name of the
       master array with the appropriate index to the array.
        var marray = new Array();

        marray[0]         =   months;
                                                                                                                    4
        marray[1]         =   stones;
        marray[2]         =   colors;
        marray[3]         =   meanings;

        document.write           ("The fourth month is <b>" + marray[0][3]);
        document.write           ("</b>. Its birthstone is <b>");
        document.write           (marray[1][3] + "</b>. The " + marray[1][3]);
        document.write           (" is a <b>" + marray[2][3] + "</b> "
            + "colored           stone, ");
        document.write           ("and it means <b>" + marray[3][3] + "</b>");
        document.write           (" traditionally.<br>");

     As you see, instead of referring to the array as months[3], we must now refer to it using the
name and index of the master array, as in marray[0][3]. As you can see in Figure 4-6, this technique
is also a valid way to create two-dimensional arrays.
Use JavaScript 2.0’s Enhanced Arrays
JavaScript 2.0 has added three distinct subclasses to the traditional Array class. Each subclass is very
similar to the way arrays have always worked in JavaScript, with some unique differences. Table 4-2
lists the traditional Array class and the three new classes, and describes the different classes.

 Array Object Name              Description
 Array [datatype]               This (the original Array class) is an abstract class. When called, it returns a
                                DynamicArray object. If no data type is specified, it defaults to type
                                Object.
 StaticArray [datatype]         This new subclass does not automatically grow when new elements are
                                added. It cannot contain empty elements and cannot be called without a
                                data type.
 DynamicArray [datatype]        This new subclass is the traditional JavaScript Array object. It cannot be
                                called without a data type.
 ConstArray [datatype]          This new subclass creates an array of constants whose value cannot be
                                changed once set. It cannot contain empty elements. If no data type is
                                specified, it defaults to type Object.
 TABLE 4-2      Array Classes in JavaScript 2.0
112      How to Do Everything with JavaScript




       FIGURE 4-6      The array of arrays technique closely simulates true two-dimensional arrays.


          Each of the Array types is usually instantiated with a data type. Both Array and ConstArray
      provide defaults for the data type, while the others do not. The data type provided when defining
      an array restricts the contents of the array to objects of that data type only.
          In this section, we will examine each of the three new array types and see how they can be
      used in JavaScript programs.

      The StaticArray Class
      The StaticArray class creates arrays of predetermined length whose values can be modified at
      any time. There are two ways to create a new StaticArray:

          ■ new StaticArray [datatype] ()
          ■ new StaticArray [datatype] (size)
          The JavaScript 2.0 specification says that StaticArrays must be defined with a data type.
      To create an array that can accept any data type, we can define the array to accept values of type
CHAPTER 4: Organize Data into Arrays                113

Object. Since Object is the parent data type of all classes in JavaScript, including those that you
create yourself, Object arrays can accept any value.
    Creating a StaticArray without passing in a data type results in an array that can contain any
object. Recall from the last chapter that Object is the data type of every class in the system, including
those that you define yourself.
var myArray : StaticArray = new StaticArray[Object]();
myArray.length = 4;
myArray[0] = "This is the first element";                                                                     4
myArray[1] = 3.141;
myArray[2] = new Car(2001, "Toyota", "4Runner", "Thundercloud");
myArray[3] = new Date();

    This code creates a new StaticArray variable of type Object. We take advantage of this by
storing a string, a number, a user-defined Car object, and a Date object into this array.
    Since the StaticArray has to have a predefined length, we started by initializing the length
property of the array to the value 4, the number of items we intended to store. Attempting to add an
additional item would cause a JavaScript error, unless we manually increased the value of the length.
var myArray : StaticArray = new StaticArray[Object]();
myArray.length = 5;
myArray[0] = "This is the first element";
myArray[1] = 3.141;
myArray[2] = new Car(2001, "Toyota", "4Runner", "Thundercloud");
myArray[3] = new Date();
myArray[4] = "This is a new element.";

    Providing a more specific data type, such as Number, would restrict the elements of the array
to only that type.
var mySecondArray : StaticArray = new StaticArray[Number](6);
mySecondArray[0] = 14.2;
mySecondArray[1] = 13;
mySecondArray[2] = 21.9999;
mySecondArray[3] = 2141330119;
mySecondArray[4] = 0.0000003;
mySecondArray[5] = 1.0121E26;

         Arrays of type StaticArray cannot have missing elements; that is, you cannot skip index
         numbers as you can with DynamicArrays.

    Attempting to add a string to a StaticArray that accepts only numbers will cause a
JavaScript error.
mySecondArray[5] = "This is not allowed.";
114      How to Do Everything with JavaScript


      The DynamicArray Class
      A DynamicArray is similar to a StaticArray, except that the size of the array will adjust itself
      automatically based on the elements you try to add to it. There are two ways to create a
      DynamicArray:

          ■ new DynamicArray [datatype] ()
          ■ new DynamicArray [datatype] (size)
          This means that you can create an empty array and add elements to it without regard for the
      existing array length.
      var Nieces : DynamicArray = new DynamicArray[String]();
      Nieces[0] = "Sofia";
      Nieces[1] = "Monica";
      Nieces[2] = "Tiffany";
      Nieces[3] = "Liz";
      Nieces[4] = "Elke";
      Nieces[5] = "Christine";
      Nieces[6] = "Leah";

          This DynamicArray, Nieces, can continue to grow to almost an unlimited size, limited only
      by the amount of computer memory. Another difference between DynamicArrays and the other
      types of arrays is that you are not obligated to fill every element. The following is valid code
      using DynamicArrays:
      var emps : DynamicArray = new DynamicArray[String]();
      emps[9931] = "John H. Smith";

         Even though we have not provided values for indexes 0 through 9930, we can skip ahead to
      9931 and provide a value for that element of the array.

      The ConstArray Class
      The third new array type supported by JavaScript 2.0 is ConstArray. ConstArrays are very similar
      to DynamicArrays, with three notable differences:

          ■ They can be defined without specifying a data type.
          ■ Their value cannot be changed once set.
          ■ They do not support skipped elements.
          There are four ways to create a new ConstArray:

          ■ new ConstArray ()
          ■ new ConstArray (size)
CHAPTER 4: Organize Data into Arrays              115

    ■ new ConstArray [datatype] ()
    ■ new ConstArray [datatype] (size)
   The ConstArray class takes its cue from the JavaScript constant variable type. (We looked at
constants in Chapter 2.) Once set, the value of a constant cannot be changed.
var months : ConstArray = new ConstArray[String](12);
months[0] = "January";
months[1] = "February";                                                                                 4
months[2] = "March";
months[3] = "April";
months[4] = "May";
months[5] = "June";
months[6] = "July";
months[7] = "August";
months[8] = "September";
months[9] = "October";
months[10] = "November";
months[11] = "December";

    Since the names of the months of the year are not likely to change during the execution of
our program, we can define them as constants. We are then free to access those strings later
in our program using the same square brackets syntax described earlier in the chapter.
    The last two chapters have focused on the built-in classes provided by JavaScript, and in
particular the new classes and data types provided by JavaScript 2.0. The next chapter is all about
creating your own classes, in both JavaScript 1.5 and 2.0.
This page intentionally left blank
Create Your Own
Chapter 5   JavaScript Classes
118      How to Do Everything with JavaScript


      How to...
          ■   Create objects in JavaScript 1.x
          ■   Use an object literal
          ■   Create objects in JavaScript 2.0
          ■   Organize classes using inheritance

      The last couple of chapters discussed how JavaScript’s built-in classes could be used to store
      many types of data (Dates, Numbers, Booleans, etc.). JavaScript also provides a way for you
      to create your own classes, so that you can design your own data types.
           In this chapter, we will examine the methods a JavaScript program can use to define objects
      for its own use. We will also examine the difference between objects created in JavaScript 1.x
      and those created in JavaScript 2.0.


 Learn about Classes in JavaScript
      In some ways JavaScript is an object-oriented programming language, and in some ways it is
      not. JavaScript has always had the ability to create and use objects. And in fact it is practically
      impossible to design a JavaScript program that does not, in some way, use the Document Object
      Model or any of the object-based data types JavaScript provides.
           But JavaScript programs are not normally designed around the object-oriented programming
      model, as Java and C++ programs are. JavaScript does not mandate the use of classes, which
      would force programmers to use the object-oriented programming model discussed in Chapter 3.
      JavaScript programmers are free to write unstructured or procedural programs to fit the task
      at hand.
           Nonetheless, support for user-defined classes and objects is one aspect of the language that
      will gain in acceptance over the coming months and years. Support for classes in JavaScript 1.x
      is limited, but it does exist. Class support in JavaScript 2.0 has been vastly improved. We will
      see the use of classes grow as programmers begin to discover the benefits of organizing their
      code into stand-alone, reusable objects.


 Create Objects in JavaScript 1.x
      There are four ways to create your own objects in JavaScript 1.x:

          ■   Call a constructor function
          ■   Use an object literal
          ■   Extend an existing class
          ■   Extend an existing object

      In the following sections, we will examine each of these methods.
CHAPTER 5: Create Your Own JavaScript Classes             119

Call a Constructor Function
One way to create an object in JavaScript is to create a special function called an object
constructor. It is the job of this constructor to initialize the object for use—essentially to
perform all the necessary setup tasks. The constructor function starts off looking just like
a regular function, but uses a special object—the this object—to add properties to itself.
    To create a constructor, follow these steps:

    1. Define an empty function, with the name of the class you wish to create.
        function Car () {
        }                                                                                              5
    2. The special this object is what a class uses to refer to itself. We can use the this object
       to add a new property inside the constructor function.
        function Car () {
            this.Make = "Toyota";
        }

    3. Since we want the constructor to be flexible and support many different types of Car
       objects, it would be better to define any properties using parameters of the function.
        function Car (make) {
            this.Make = make;
        }

    4. We can then add many more properties to make our Car object complete.
        function Car (make, model, year, color) {
            this.Make = make;
            this.Model = model;
            this.Year = year;
            this.Color = color;
        }

    5. Of course, we can add a property that does not rely on any parameters.
        function Car (make, model, year, color) {
            this.Make = make;
            this.Model = model;
            this.Year = year;
            this.Color = color;
            this.FullName = this.Year + " " +
                "<b>" + this.Make + "</b> " +
                this.Model;
        }
120   How to Do Everything with JavaScript


      6. Now that we have defined a constructor for the Car class, our program can call it to
         create a Car object.
          function Car (make, model, year, color) {
              this.Make = make;
              this.Model = model;
              this.Year = year;
              this.Color = color;
              this.FullName = this.Year + " " +
                  "<b>" + this.Make + "</b> " +
                  this.Model;
          }

          var mySUV = new Car("Toyota", "4Runner SR5",
              2001, "Thundercloud");

       7. With the mySUV object created, we can access any of the properties of the Car class.
          var mySUV = new Car("Toyota", "4Runner SR5",
              2001, "Thundercloud");
          document.write ("I drive a " + mySUV.FullName);
CHAPTER 5: Create Your Own JavaScript Classes           121

   8. In fact, we can create several objects from this one constructor, all with their own
      independent properties. Changing the value of one object’s property does not affect
      the value of the same property inside other objects.
        var mySUV = new Car("Toyota", "4Runner SR5",
            2001, "Thundercloud");
        var mySportsCar = new Car("Acura", "NSX-T",
            1999, "Red");
        var myDreamCar = new Car("Ferrari", "F355 F1",
            2000, "Ferrari Red");
                                                                                                  5
        mySportsCar.Color = "Black";
        document.write (mySUV.FullName + " = " +
            mySUV.Color + "<br>");
        document.write (mySportsCar.FullName + " = " +
            mySportsCar.Color + "<br>");
        document.write (myDreamCar.FullName + " = " +
            myDreamCar.Color + "<br>");




    This method of creating objects will work in JavaScript using all browsers dating back to
Internet Explorer 3.0 and Netscape Navigator 3.0.
122      How to Do Everything with JavaScript

               Property names are case-sensitive in JavaScript. The property myCar.color is not the
               same as myCar.Color.

      Use an Object Literal
      The JavaScript object literal is a convenient way to create an object without having to predefine
      a constructor function. It is, in effect, an unnamed constructor. One of JavaScript’s greatest
      strengths is that it allows programmers to create programs quickly, and the object literal is a
      prime example of how it does this. The tradeoff to creating objects quickly using the object
      literal is that you lose out on the ability to reuse code for other objects or other programs.
           The object literal consists of a number of property-value pairs enclosed in a pair of curly brackets.
      Colons separate the properties and values, and commas separate the property-value pairs.
      { property1 : value , property2 : value , ... , propertyN : value }

          We can create the same mySUV object we created in the last section using an object literal
      as follows:
      var mySUV = {Make:"Toyota",
                   Model:"4Runner SR5",
                   Year:2001,
                   Color:"Thundercloud"};

           We will have to use a bit of a trick in order to define the FullName property using an object
      literal. Within the object literal itself, you cannot refer to any of the other properties. The following
      code shows how we are forced to define the FullName manually:
      var mySUV = {Make:"Toyota",
                   Model:"4Runner SR5",
                   Year:2001,
                   Color:"Thundercloud",
                   FullName:"2001 Toyota 4Runner SR5"};

         When it comes to defining the other two objects from the last section (mySportsCar and
      myDreamCar), the only way to reuse the code from the mySUV object is to copy and paste,
      which most people would agree is not the best way to reuse code.
      var mySportsCar = {Make:"Acura",
                   Model:"NSX-T",
                   Year:1999,
                   Color:"Red",
                   FullName:"1999 Acura NSX-T"};
CHAPTER 5: Create Your Own JavaScript Classes                123

var myDreamCar = {Make:"Ferrari",
             Model:"F355 F1",
             Year:2000,
             Color:"Ferrari Red",
             FullName:"2000 Ferrari F355 F1"};

    As you can see, object literals are best used when you do not anticipate needing to create
other objects of the same type.

Extend an Existing Class
JavaScript allows you to extend the capabilities of a class by assigning your own methods and
                                                                                                         5
properties to it. This includes adding new methods and properties to any of the predefined system
classes. It does this through a system called prototyping.
    JavaScript automatically gives each class a property called prototype that can be used to extend
the functionality at the class level.
ClassName.prototype.member1 = value1;

     A new member (member1) can be assigned a default value (value1) and added to the class
specified (ClassName). This new member is static, in that its value is shared by all objects derived
in that class. Changing the value inside one object changes it for all.
     Let’s start with an example. In the following code, we have defined a function that accepts
a Date object as its parameter and will return a string that represents the name of the season
("Spring", "Summer", "Fall", or "Winter") that the date belongs to.
function getSeason (obj) {
    var mon = obj.getMonth();
    var day = obj.getDay();
    if (mon < 2 || (mon == 2 && day < 20)) {
        return "Winter";
    } else if (mon < 5 || (mon == 5 && day < 21)) {
        return "Spring";
    } else if (mon < 8 || (mon == 8 && day < 23)) {
        return "Summer";
    } else if (mon < 11 || (mon == 11 && day < 22)) {
        return "Fall";
    } else {
        return "Winter";
    }
}
124      How to Do Everything with JavaScript


          Thus, we can call the preceding function using a Date object and get the correct season that
      the date falls into.
      var today = new Date();
      document.write(getSeason(today));

          You might think that it would be more convenient if the getSeason() function was a method
      of the Date object, instead of an external piece of code. To attach the getSeason() function to the
      Date class, we first need to modify it to work on the special this object, as all methods inside
      classes should.
      function getSeason () {
          var mon = this.getMonth();
          var day = this.getDay();
          if (mon < 2 || (mon == 2 && day < 20)) {
              // Covers Jan 1 through Mar 19
              return "Winter";
          } else if (mon < 5 || (mon == 5 && day < 21)) {
              // Covers Mar 20 through June 20
              return "Spring";
          } else if (mon < 8 || (mon == 8 && day < 23)) {
              // Covers June 21 through Sept 22
              return "Summer";
          } else if (mon < 11 || (mon == 11 && day < 22)) {
              // Covers Sept 23 through Dec 21
              return "Fall";
          } else {
              // Covers Dec 22 through Dec 31
              return "Winter";
          }
      }

          We must then attach the getSeason() function to the Date object as follows:
      Date.prototype.getSeason = getSeason;

          We can then call the getSeason() method right from any and all Date objects we create.
      var today = new Date();
      document.write("The season is currently " + today.getSeason());
CHAPTER 5: Create Your Own JavaScript Classes                125




                                                                                                        5




    Even though the getSeason() method is still not technically a member of the Date class,
JavaScript is smart enough to check to see if it exists inside the list of prototype members, which
is where we created it.

Extend an Existing Object
Just as a class can be extended using the prototype property, objects themselves can have new
properties and methods attached to them.
function Car (make, model, year, color) {
    this.Make = make;
    this.Model = model;
    this.Year = year;
    this.Color = color;
    this.FullName = this.Year + " " +
        "<b>" + this.Make + "</b> " +
        this.Model;
126       How to Do Everything with JavaScript

      }

      var mySUV = new Car("Toyota", "4Runner SR5",
          2001, "Thundercloud");
      mySUV.mileage = 12323;
      document.write(mySUV.FullName + " has traveled " +
          mySUV.mileage + " miles.<br><br>");




          Even though the Car class does not define a property named mileage, we were able to create
      one for the mySUV object simply by assigning a value to it. Since we applied this property to
      the mySUV object and not the Car class, other objects derived from the Car class will not have
      a mileage property.


 Create Objects in JavaScript 2.0
      JavaScript 2.0 has totally redesigned the way classes are defined. Although most JavaScript
      environments will still support the old way for the sake of backward compatibility, it is hard
      to compare the two techniques. Prototypes and manually added properties are no longer the
      preferred method for generating user-defined classes and objects in JavaScript.
CHAPTER 5: Create Your Own JavaScript Classes                  127

Define Your Own Classes
In JavaScript 2.0, classes are defined using the following syntax:
class className { statements; }

    As you can see, this syntax is quite simple. In practice, classes are quite easy and straightforward
to define. We can take the Car class defined earlier in the chapter and define it using the
JavaScript 2.0 syntax.

    1. Define a class named Car using the class definition syntax.
        class Car {
                                                                                                             5
        }

    2. Then define all the properties our Car class will possess.
        class Car {
            var Make;
            var Model;
            var Year;
            var Color;
            var FullName;
        }

    3. Remember that JavaScript 2.0 supports data types for variables, so let’s make our
       definition more specific.
        class Car {
            var Make : String;
            var Model : String;
            var Year : Integer;
            var Color : String;
            var FullName : String;
        }

    4. We will need to add a constructor function to the Car class to initialize these variables.
       The constructor usually has the same name as the class, although it is possible to define
       constructors with different names using a special syntax. The this object is still used to
       refer to the current object.
        class Car {
            var Make : String;
            var Model : String;
            var Year : Integer;
            var Color : String;
            var FullName : String;
128   How to Do Everything with JavaScript

               function Car (make, model, year, color) {
                   this.Make = make;
                   this.Model = model;
                   this.Year = year;
                   this.Color = color;
                   this.FullName = this.Year + " " +
                       "<b>" + this.Make + "</b> " +
                       this.Model;
               }
          }

      5. The Car class can be instantiated in the exact same manner as classes defined under
         JavaScript 1.x were, using the new keyword.
          var mySUV = new Car("Toyota", "4Runner SR5",
              2001, "Thundercloud");

      6. With the mySUV object created, we can access any of the properties of the Car class.
          var mySUV = new Car("Toyota", "4Runner SR5",
              2001, "Thundercloud");
          document.write ("I drive a " + mySUV.FullName);

          It is easier to create methods using JavaScript 2.0 classes, as functions can be defined
          inside of the body of the class.
          class Book {
              var title : String;
              var author : String;
              var chapters : Array[String];
              function print_title () {
                  document.write ("Title: " + this.title + "<br>");
              }
              function print_author () {
                  document.write ("Author: " + this.author + "<br>");
              }
              function print_all () {
                  var counter = 0;
                  print_title();
                  print_author();
                  for (chapter in this.chapters) {
                       counter++;
                       document.write ("Chapter " + counter + ": " +
                           this.chapters[chapter] + "<br>");
                  }
CHAPTER 5: Create Your Own JavaScript Classes       129

             }
        }

        Once the Book class is defined, we can create a Book object using the new keyword.
        Since our class does not have a constructor, we can then manually set each of the
        properties. Calling a method of that new object results in the behavior we expect.
        var thisBook = new Book();
        thisBook.title = "How To Do Everything with JavaScript";
        thisBook.author = "Scott Duffy";
        thisBook.chapters = new Array(15);
        thisBook.chapters[0] = "Prepare to Program in JavaScript";                             5
        thisBook.chapters[1] = "Learn JavaScript Fundamentals";
        thisBook.chapters[2] = "Use Built-In JavaScript Classes";
        thisBook.chapters[3] = "Organize Data into Arrays";
        thisBook.chapters[4] = "Create Your Own JavaScript Classes";
        // etc.

        thisBook.print_all();

This results in the following browser output.
130       How to Do Everything with JavaScript


      Organize Classes Using Inheritance
      One of the benefits of organizing your program into classes is that you can establish relationships
      between classes using inheritance. Inheritance allows you to do two things:

          ■ Save programming time, because related classes can share code
          ■ Enforce a standard set of common properties and methods for related classes
          JavaScript 2.0 enables one class to inherit from another using the extends keyword.
      class ClassName extends ParentClass { statements; }

          This establishes a parent-child relationship between the ParentClass and the ClassName
      classes. The best way to understand inheritance is to think of the class structure like a
      hierarchical tree.
          At the top of the tree is the Object class, the parent of all classes in the system. All the
      classes in the system that do not have an explicit parent object derive from the Object class
      by default. Those that do have an explicit parent class defined, inherit from that class instead.
      Note: All classes in JavaScript 2.0 (both system and user-defined) have the Object class
      as either a direct or indirect ancestor, even those that extend from another class.


          We can define the parent class in the normal way.
      class Vehicle {
          var Maker;
          var Price;
          var Color;

            function Vehicle       (maker, price, color) {
                this.Maker =       maker;
                this.Price =       price;
                this.Color =       color;
            }
            function Vehicle       () {
                this.Maker =       "Default";
                this.Price =       0.0;
                this.Color =       "Transparent";
            }
      }

          This code defines a Vehicle class, although there are only three properties. This class represents
      any generic vehicle, whether it is a boat, or a plane, or a car. That class should be able to handle
      any object that can be considered a vehicle.
CHAPTER 5: Create Your Own JavaScript Classes                131

         A class can contain multiple constructors, as long as the number and type of parameters
         (known as the function signature) are unique for each constructor.

    We can then be a bit more specific by defining classes that break down the type of vehicle.
By extending the Vehicle class, our child classes automatically inherit the properties and methods
of the Vehicle class.
class LandVehicle extends Vehicle {
    // Land specific code
    var Speed;
    var xPosition;
    var yPosition;
                                                                                                          5
}
class WaterVehicle extends Vehicle {
    // Water specific code
    var Speed;
    var WaterDisplacement;
    var xPosition;
    var yPosition;
    var zPosition;
}
class AirVehicle extends Vehicle {
    // Air specific code
    var AirSpeed;
    var LandSpeed;
    var xPosition;
    var yPosition;
    var zPosition;
}
class SpaceVehicle extends Vehicle {
    // Space specific code
    var Thrust;
    var DistanceFromEarth;
}

    We can continue to define classes that inherit from these child classes (LandVehicle, AirVehicle,
WaterVehicle, and SpaceVehicle). The idea is that each child class is a more specific version of
the parent class. So LandVehicle would have the following child classes:

    ■   Car
    ■   Train
    ■   Bus
    ■   Truck
132      How to Do Everything with JavaScript



                             The Story of Interfaces

        The ECMA, the designers of the JavaScript 2.0 specification, originally planned to include
        an object-oriented programming concept called interfaces in the specification, but it was
        dropped at the last minute. Interfaces allow you to define a set of standard method names
        and parameter lists without having to provide code for them. A class could then declare,
        “I support the following interfaces...”; this would provide a reliable way to know what
        methods are supported by the class.
            Let’s say you define an interface named DoorLock, which contains two methods, Lock()
        and Unlock(). We know that the Car class implements the DoorLock interface, so we can be
        sure that a Car object has Lock() and Unlock() methods as well. Notice that a Car is not a
        type of DoorLock, so a parent-child relationship (one created by inheritance) should not be
        established.
            By defining a DoorLock interface, we have created a standard set of methods for classes
        that need to define door lock activity, such as the Car class and the House class.



           A Car is a more specific type of LandVehicle, which is a more specific type of Vehicle. If
      we wanted to further define Car, for instance, we could create SUV and SportsCar classes that
      inherit from it, and so on.
           There are obviously two major benefits to having classes inherit in such a manner. The first
      is the ability to reuse code. We defined a constructor all the way back in the Vehicle class.
           function Vehicle       (maker, price, color) {
               this.Maker =       maker;
               this.Price =       price;
               this.Color =       color;
           }

         Assuming none of the child classes defined a constructor for itself, all the descendants of the
      Vehicle class can use the original Vehicle constructor.
      class Vehicle {
          var Maker;
          var Price;
          var Color;

           function Vehicle (maker, price, color) {
               this.Maker = maker;
CHAPTER 5: Create Your Own JavaScript Classes               133

          this.Price = price;
          this.Color = color;
     }
}

class LandVehicle extends Vehicle {
    // Land specific code
    var Speed;
    var xPosition;
    var yPosition;
}                                                                                                      5
class Car extends LandVehicle {
    // Car specific code
    var Model;
    var Year;
}

// Car inherits the Vehicle constructor
var myCar : Car = new Car ("Ford", 19500, "Blue");
myCar.Model = "Focus";
myCar.Year = 2002;
myCar.Speed = 32;

// Car inherits the properties of Vehicle
document.write ("Vehicle class properties: " + myCar.Maker + "<br>");

// Car inherits the properties of LandVehicle
document.write ("LandVehicle class properties: " + myCar.Speed + "<br>");

// Car has its own properties as well
document.write ("Car class properties: " + myCar.Model + "<br>");

    As you can see from Figure 5-1, even though the Car class itself has only two properties, it
does inherit all of the properties from its parents.
    Another benefit of using inheritance is what computer geeks like to call polymorphism.
Essentially, a variable defined as the Vehicle data type can contain any of the objects derived
from Vehicle (like LandVehicle or Car). This allows a program to act on an object without having
to know or care what the exact type of the object is. If it can act on the parent object, the same
actions can be performed on any of the child objects.
134      How to Do Everything with JavaScript




       FIGURE 5-1      Classes inherit the properties and methods of their parents.


           Perhaps the best demonstration of this would be with our own type of number, which we will
      call SuperNumber.
      class SuperNumber extends Number {
          override function toString() {
              return super.toString() + " !!!!";
          }
      }

          The only difference between a regular Number class and a SuperNumber class is that the
      SuperNumber will return four exclamation marks appended to the end of the number when a
      user calls the toString() function.
          Once we have defined a SuperNumber, we can use it just like we would use a number. Any
      function that works on Numbers will be able to handle SuperNumbers, due to the inheritance
      relationship. Even the existing arithmetic operators will be able to handle these variables without
      modification.
      var x : SuperNumber = new SuperNumber(13);
      var y : SuperNumber = new SuperNumber(22);
CHAPTER 5: Create Your Own JavaScript Classes                 135

var z : Number = x + y;
alert (z);

    We can see the result of the program here.




                                                                                                          5
         This illustration depicts the result we would expect to see when JavaScript 2–compatible
         browsers are eventually released.

Choose Between Static and Instance Members
We examined the concept of static class members when we discussed the built-in Math method
in Chapter 3. Basically a static member is any property or method that is defined only in the class
itself, and not in any of the objects derived from that class. You do not even have to have an object
of a particular class defined in order to access its static members.
     Static members are defined using the static keyword.
class Books {
    static const MAX_WIDTH = 8.5;
    static const MAX_HEIGHT = 11;
    static const MAX_WEIGHT = 10;
    var title;
    var author;
    var page_count;
}

    In the Books class defined here, we have defined three static members. They happen to be
defined as constants, but variables and even functions can be defined as static. In order to access
them, we call them through the Books class, and not through any object created based on Books.
alert (Books.MAX_HEIGHT);
136       How to Do Everything with JavaScript

               This illustration depicts the result we would expect to see when JavaScript 2–compatible
               browsers are eventually released.

          Instance members are any members that are not static. Instance members are accessed
      through objects that have been created, and they cannot be accessed using the class directly.
      var myBooks = new Books();
      myBooks.title = "How To Do Everything With a Pencil";
      myBooks.author = "Mary Major";

          In this code, both title and author are instance members, and they can be accessed only by
      using an object (myBooks) based on the class Books, and not the class itself.

      Make Class Members Public or Private
      Another common task in object-oriented programming is to define members that cannot be
      accessed from outside the class. This is primarily used for security and data integrity.
          Members are made private using the private keyword, and made public using the public
      keyword. By default, members that are not explicitly defined as either are public.
      class Car {
          private     var   Make : String;
          private     var   Model : String;
          private     var   Year : Integer;
          private     var   Color : String;

            public function setMake (value) : Void {
                this.Make = value;
            }
            public function setModel (value) : Void {
                this.Model = value;
            }
            public function setYear (value) : Void {
                this.Year = value;
            }
            public function setColor (value) : Void {
                this.Color = value;
            }
      }

         In this code, all the properties of the Car class are defined as private. This means that they
      cannot be accessed from outside the class. Attempting to do the following will cause an error.
      var myCar = new Car();
      myCar.Make = "Mercedes";
CHAPTER 5: Create Your Own JavaScript Classes              137

    To set the properties, we have to call the public methods we created for ourselves. The
following code will work.
var myCar = new Car();
myCar.setMake ("Mercedes");

    Notice how we created a Car class that has made it impossible to read the values of the
properties. In the real world, the class would also contain a number of functions to retrieve the
values as well.
    Obviously, there is more to learn about classes in JavaScript, including getters and setters,
packages, and namespaces. But these topics go beyond the scope of this chapter, and of this
book. For more information on classes, consult the official JavaScript 2.0 specification on the
                                                                                                      5
Mozilla web site, located at http://www.mozilla.org/js/language/js20/core/classes.html.
    In the next chapter, we will start to learn how to apply the concepts learned in the previous
four chapters, as we use JavaScript inside web pages. We will learn about some of the key HTML
tags and where JavaScript should be placed in the web page.
This page intentionally left blank
Build
Part II   JavaScript-
          Enabled
          Web Sites
This page intentionally left blank
Embed JavaScript
Chapter 6   in a Web Page
142      How to Do Everything with JavaScript


      How to...
          ■   Understand basic HTML structure
          ■   Use <script> to add JavaScript to a web page
          ■   Use <noscript> for browsers that don’t support scripting
          ■   Load an external JavaScript file
          ■   Call JavaScript using hyperlinks

      Up until this point in the book, we have been concentrating on JavaScript’s programming
      syntax—the statements and definitions that are the nuts and bolts of the language. As you’ve
      seen, JavaScript has many features that make it an ideal language for many tasks, and one of
      its strongest features is its ability to integrate into a wide variety of other environments.
           Versions of JavaScript exist in many different environments:

          ■ An Application Server Pages (ASP) language for Microsoft IIS web servers (one of
              several supported languages)
          ■   Server-Side JavaScript (SSJS) for Netscape/iPlanet web servers
          ■   A server-side programming language for other web servers
          ■   An embedded language for Adobe Acrobat PDF documents
          ■   An embedded language for Macromedia Flash files (ActiveScript)

           But even today, almost 10 years after it was first introduced, JavaScript’s biggest success
      remains as an embedded programming language for web pages. It is supported by virtually
      every web browser in use today—it is installed on hundreds of millions of PCs worldwide. In
      this chapter, we will examine how to embed JavaScript in HTML pages and some basic text
      formatting techniques.


 Understand Basic HTML Structure
      Hypertext Markup Language, or HTML for short, is the language that web pages are written in.
      HTML is known as a markup language, because it uses a set of predefined tags, or markup, to
      provide formatting and other instructions to the web browser.
          For instance, the following example contains a number of HTML markup tags:
      <font size="2"><b>Now is the time</b> for all
      good men <u>to come to the aid</u> of <i>their party</i>.</font>

           As you can see, the HTML markup tags are always enclosed in angle brackets (< and >).
      Most HTML tags have both a starting tag (the bold text tag, <b>, for instance) and a closing tag
      (like </b>), although there are some exceptions to this rule.
CHAPTER 6: Embed JavaScript in a Web Page                143

    The following shows how an HTML document with the preceding markup would appear in a
standard web browser.




                                                                                                         6




         Closing tags always start with a forward-slash character (/) followed by the name of
         the related start tag. For instance, if the start tag is <font>, the end tag must be called
         </font>.

     Entire books have been written on the subject of HTML. Actually, to be truly accurate, you
could say enough books to fill more than a few bookshelves (or even bookcases) have been
written on the topic. My goal, in this chapter and the ones that follow, is not really to teach the
ins and outs of HTML. But since JavaScript programs rely so much on what’s happening inside
the browser (frames, forms, browser events, etc.), it is impossible to understand what is going on
with JavaScript without first understanding the HTML it relates to. For reference, Appendix A
lists each of the HTML 4.01 tags and gives a brief description of their use.

         The major browser makers (Microsoft and Netscape) have in some cases added their
         own tags, so their lists might not match the official list in Appendix A.
144      How to Do Everything with JavaScript



                             Why XML and XHTML
                             Are the Coming Thing
        Although humans can easily read HTML documents using a web browser, computers
        themselves have a difficult time finding specific data to extract from a web page. For instance,
        it would be very difficult to create an application that can reliably download daily flight
        schedules from all the airline web sites.
            XML (Extensible Markup Language) is an ideal language for transmitting computer data
        over the Internet. Whereas HTML is an extremely flexible markup language, with very few
        mandatory elements or attributes, XML has a strict set of formatting rules. Programmers can
        impose additional rules on individual types of documents by creating an XML schema or
        DTD. XML is the new standard language for data formatting over the Internet, and it is the
        foundation of many of the Web Services initiatives, including Sun ONE and Microsoft .NET.
            A new version of HTML has been created that allows web documents to be valid XML
        as well, called XHTML. In fact, the World Wide Web Consortium (W3C) has stopped
        developing the HTML standard (version 4.01) and has been hard at work at XHTML standards—
        versions 1.0 and 1.1 have already been released.
            For more information on the XHTML standard, visit the W3C web site at
        http://www.w3c.org/markup.



           In addition, as mentioned in Chapter 1, a special set of tags denotes comments in HTML:
      <!-- indicates the start of commented text, and --> indicates the end. Comments serve as useful
      documentation or author notes, such as the following:
      <!-- Survey.html
           Purpose: To gather visitor opinions on this site
           Author: John Q. Doe
      -->

      <!-- Copyright 2003, Scott J. Duffy Incorporated
           All rights reserved. -->

         As you can see, comments can extend over several lines. All text that appears inside HTML
      comment markup is ignored by the browser and not displayed to the user in the main display.
               Don’t forget that the user can see the underlying HTML code in most browsers by
               selecting View | Source from the menu bar, so your comments won’t be entirely private.
CHAPTER 6: Embed JavaScript in a Web Page              145


                       What “Officially Deprecated” Means

  The World Wide Web Consortium (W3C), the group that creates and maintains several
  important specifications dealing with the Internet including HTML, has indicated a number
  of HTML tags are deprecated.
      Indicating that a tag is deprecated is a polite way of saying support for it in the
  specification will likely be dropped in a future release. The W3C would like to encourage
  web developers to employ another method instead, such as using Cascading Style Sheets
  (CSS) for defining fonts.
      However, given the widespread use of such tags as <font>, <center>, and <u>, it is highly      6
  unlikely that the major browser makers are going to drop support for them anytime soon.



Build an HTML Document
One of the strengths of HTML is simplicity: it is very easy to build a web page using just a few
basic tags. There are three essential elements to building a web page:

    1. Every HTML document must begin with the HTML start tag (<html>) and end
       with the HTML end tag (</html>). The only exception is for <!DOCTYPE> or
       <?xml?> declaration statements, which are then placed before the HTML tags.
       (The <?xml?> declaration is used to define documents that conform to XHTML,
       which is beyond the scope of this book. However, we will look at <!DOCTYPE>
       in the following section.)
        <html>
        </html>

   2. The HTML document is then divided into two sections, a head and a body. The head
      section is where a document title, descriptive keywords, style sheets, and JavaScript
      functions are defined.
        <html>
            <head>
                <title>How to Do Everything with JavaScript</title>
            </head>
        </html>

   3. The body section is where the contents of the document are placed. Often this will be
      plain text (sentences and paragraphs), marked up with some formatting HTML tags like
      <b>, <i>, and <p>.
        <html>
            <head>
146      How to Do Everything with JavaScript

                      <title>How to Do Everything with JavaScript</title>
                  </head>
                  <body bgcolor="white">
                      <h1>A typical document header</h1>
                      <p>The start of a paragraph.</p>
                      <p><b>Our second paragraph.</b></p>
                  </body>
              </html>

          Granted, the web page in our example is fairly simple, but even web pages with hundreds of
      lines of code start with three simple tags: <html>, <head>, and <body>.
               Get in the habit of creating all your HTML documents using lowercase tag names, properly
               nested tags, and properly quoted attribute values. It will pay off when you want to start
               creating XHTML 1.0 documents, because XHTML has very strict rules.

          You are probably already familiar with the basics of HTML. If not, since it’s not feasible to
      compress a tutorial on HTML into one chapter, I have included a list of useful web sites at the
      end of this chapter.

      Indicate the Document Type with <!DOCTYPE>
      There is only one way to indicate to a browser (or any other application reading your HTML file)
      which version of HTML your web page is written for: <!DOCTYPE>. Up until a few years ago,
      this tag was ignored entirely by web browsers. But recent versions of browsers look for this code
      to determine which set of rules to use in interpreting the web page.
           An HTML document that conforms to the HTML 4.01 specification would have the
      following <!DOCTYPE> as the very first line of the page, even before the <html> tag:
      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
          "http://www.w3.org/TR/html4/loose.dtd">

          If a browser encounters a web page that uses this <!DOCTYPE> tag, the browser will expect
      valid HTML 4.01 Transitional code in the rest of the document. Transitional HTML includes all
      the deprecated tags (such as <font>). There is also a version of HTML called Strict that does not
      include deprecated tags, and another called Frameset that allows browser frames to be created.
      (We will look at browser frames in Chapter 10.)
          If we wanted to use a different version of HTML, like XHTML (the XML compliant version
      of HTML), we would use a different <!DOCTYPE>, like so:
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
CHAPTER 6: Embed JavaScript in a Web Page                 147

   When a browser encounters this <!DOCTYPE>, it knows to treat the contents as XHTML 1.0
Transitional. Depending on the browser, this may be slightly different from the way it treats
HTML 4.01 code.

Add a Title and Define Document Keywords
The HTML head element contains information about the current document, such as its title,
keywords, and other data that is not considered content. The HTML <title> tag is used to
specify a title for the document, and it is mandatory in HTML 4.01.
<html>
    <head>
        <title>This is the document title</title>
    </head>                                                                                              6
    <body></body>
</html>

    The contents of the <title> tag are usually displayed in the title bar of the window, as you can
see here:




    Optionally, you can specify a number of keywords, which will make it easier for Internet
search engines to find your web site. Keywords and a brief description of the web page can be
specified using the <meta> tag. For instance, if you had a page focused on exotic pets, you might
have the following <meta> tags:
<meta name="description" content="Articles, pictures, and stories
    about exotic pets">
<meta name="keywords" content="exotic pets, reptiles, amphibians,
    frog, toad, salamander, newt, siren, lizard, iguana, gecko,
    monitor, chameleon, dragons, turtles, tortoises, leopard,
    butterfly, butterflies, moth, bees, flies, stick insects,
    beetles, wasps, hornet, roaches, ants, cricket, grasshopper,
    tarantula, scorpion, centipede, millipede">

     When used to specify web page descriptions and keywords, the <meta> tag takes two
attributes: name and content. In the preceding code, the first <meta> tag sets the description
148      How to Do Everything with JavaScript


      for the web page—usually a sentence or two that is often displayed by Internet search engines
      to give potential visitors an accurate description of what to expect from this page.
           The second <meta> tag in the example defines a number of keywords—words or phrases
      separated by commas that give search engines help in indexing the page. Some Internet search
      engines rank web pages with these <meta> tags higher than they would the same page without
      the <meta> tags.

      Format Text with HTML Elements
      HTML provides a number of elements to help web page developers format and style text. These
      tags fall into two broad categories: phrase elements and font style elements. Phrase elements are
      tags that structure text. The way these elements are presented to the user depends on the browser.
      Font style elements are tags that specify specific font properties for text. Since font style properties
      are fairly specific, developers can be more confident about the way browsers will present text to
      the user.
          The following are the phrase elements in HTML 4.01:

          ■   <abbr> indicates an abbreviated form
          ■   <acronym> indicates an acronym
          ■   <cite> indicates a citation or reference to other sources
          ■   <code> designates a fragment of computer code
          ■   <dfn> indicates the defining instance of a term
          ■   <em> indicates emphasis; usually displayed as italic text
          ■   <kbd> indicates text to be entered by the user
          ■   <samp> indicates sample output from programs, scripts, and so forth
          ■   <strong> indicates stronger emphasis; usually displayed as bold text
          ■   <var> indicates an instance of a variable or program argument

      Again, each of these elements indicates the type of text it contains, but gives only a hint as to
      how the browser should handle them.
         The following tags are the font style elements of HTML 4.01:

          ■ <b> bold text
          ■ <big> larger than normal text
          ■ <i> italic text
CHAPTER 6: Embed JavaScript in a Web Page                 149

    ■   <s> strikethrough text (officially deprecated)
    ■   <small> smaller than normal text
    ■   <strike> strikethrough text; same a <s> (officially deprecated)
    ■   <tt> teletype or monospace text
    ■   <u> underlined text (officially deprecated)

    In the vast majority of HTML pages, phrase elements are not used. Many web page designers
prefer to set fonts and styles for their pages explicitly. On top of the uncertainty of how different
browsers will render these tags, using such predefined document structure elements limits
designers’ design choices.
    Hundreds of millions of web pages exist that use only HTML elements like the ones listed
here to style the text on their pages. For example, the following HTML code creates a web page            6
that uses many of the style tags discussed so far in this chapter.
<html>
    <head><title>Sample document</title></head>
    <body>
    <h1>Traveling to the Caribbean</h1>

     <p><b>Barbados</b> - Barbados is a lovely island, with
     <i>wonderful weather</i> and a <i>constant cool breeze</i>. The
     locals are friendly, and one can clearly see that a British
     influence still exists, even today.</p>

     <p><b>St. Lucia</b> - St. Lucia is a lush, tropical paradise.
     Fewer tourists tend to visit St. Lucia than some of the other
     islands, which means it is easier to explore the local way
     of life.</p>

    <p><b>Bahamas</b> - Bahamas is <strike>frequently visited
by</strike> <u>a popular spot for</u> Americans. The islands have a
number of casinos, the most spectacular of which is the <i>Atlantis
Hotel on Paradise Island</i>. The rumor is that one of their hotel rooms
goes for <big>$40,000 a night</big>, which is about $39,800 more than
most people can afford to spend on a place to sleep.</p>
    </body>
</html>
150      How to Do Everything with JavaScript


          As you can see from the following screen capture, HTML elements style text to make the
      output easier to read. Text that should be boldface, italic, or crossed out is presented exactly as
      one would expect.




      Format Text with Style Sheets
      For years, web designers have wanted a more precise way to style and lay out web pages, similar
      to the tools desktop publishing software has provided for a long time. Finally, along came style
      sheets, which have alleviated most of the designer’s concerns about styling web pages.
               The W3C homepage for Cascading Style Sheets is http://www.w3.org/Style/CSS. Not
               surprisingly, that page is itself a great example of how style sheets can be used to format
               a web page.

          Style sheets, also sometimes called Cascading Style Sheets (CSS for short), have a number
      of benefits for web developers. They provide

          ■ The ability to separate style from content
          ■ The ability to apply a single style to an entire web site
          ■ A more fine-grained ability to control style
CHAPTER 6: Embed JavaScript in a Web Page                  151

    ■ The ability to specify exact layout positioning
    ■ The ability to script and dynamically change styles using JavaScript (also called
        Dynamic HTML)
    ■ The ability to specify different styles depending on browser environment (e.g., PC versus
        mobile phone)

     In fact, the HTML specification is slowly phasing out the use of the HTML tags listed in the
last section to define style in favor of style sheets. Using style sheets to define a document’s style
is the present and future of the language.
     A style sheet is defined inside the HTML <style> element, which is usually defined inside
the document head section.
<html>                                                                                                     6
    <head>
        <title>HTML Style Sheets</title>
        <style type="text/css">

           // Style sheet goes in here

         </style>
     </head>
     <body>
     <h1>Traveling to the Caribbean</h1>

    <p><b>Barbados</b> - Barbados is a lovely island, with
    <i>wonderful weather</i> and a <i>constant cool breeze</i>. The
    <!-- Etc. -->
    </body>
</html>

    In the case of our HTML document, we can define a custom style sheet that replaces some of
the formatting we were using.
<style type="text/css">
    .island {font-weight: bold}
    .highlight {font-style: italic}
    .underlinethis {text-decoration: underline}
    .bigmoney {font-size: larger}
</style>

     In fact, you could add some really interesting text effects to our boring document, as shown
in the following example. And once the style sheet has been defined, you simply alter the HTML
to use those styles.
152     How to Do Everything with JavaScript

      <html>
          <head>
              <title>Sample document</title>
              <style type="text/css">
              .island {
                  color: white;
                  background-color: black;
                  font-weight: bold
              }
              .highlight {
                  font-style: italic;
                  background-color: yellow
              }
              .underlinethis {
                  text-decoration: underline overline
              }
              .bigmoney {
                  color: green;
                  font-size: xx-large
              }
              </style>
          </head>
          <body>
          <h1>Traveling to the Caribbean</h1>

         <p><span class="island">Barbados</span> - Barbados is a lovely
         island, with <span class="highlight">wonderful weather</span>
         and a <span class="highlight">constant cool breeze</span>. The
         locals are friendly, and one can clearly see that a British
         influence still exists, even today.</p>

         <p><span class="island">St. Lucia</span> - St. Lucia is a lush,
         tropical paradise. Fewer tourists tend to visit St. Lucia than
         some of the other islands, which means it is easier to explore the
         local way of life.</p>

         <p><span class="island">Bahamas</span> - Bahamas is
         <strike>frequently visited by</strike> <span class="underlinethis">a
         popular spot for</span> Americans. The islands have a number of
         casinos, the most spectacular of which is the <span
         class="highlight">Atlantis Hotel on Paradise Island</span>.
         The rumor is that one of their hotel rooms goes for <span
         class="bigmoney">$40,000 a night</span>, which is about $39,800 more
CHAPTER 6: Embed JavaScript in a Web Page                  153

       than most people can afford to spend on a place to sleep.</p>
       </body>
   </html>

       The resulting web page would not win any design awards, but you can see that style sheets
   allow you to do things regular HTML does not.




                                                                                                              6




        Clearly, style sheets involve much more than the small glimpse I have been able to give you
   in this short section. I have listed a few web sites you can visit to learn more about style sheets at
   the end of this chapter. We will also revisit this subject in Chapter 12.


Use <script> to Add JavaScript to a Web Page
   Now that you have been introduced to some basic HTML formatting elements, it’s time to tie
   that in to the use of JavaScript. The HTML <script> tag allows web developers to embed
   JavaScript commands in their web pages. There is no restriction as to the number of <script>
   sections a web document can contain, although for the sake of programming efficiency it is
   best to keep the number of scripts on a single page to a minimum.
        The HTML <script> element generally accepts only two attributes when you are working
   with embedded script content: language and type. The language attribute exists for backward
   compatibility. JavaScript is the only scripting language supported by all major web browsers,
   so if this attribute is omitted, "JavaScript" is the default.
154      How to Do Everything with JavaScript


          The type attribute specifies the MIME type for the embedded script, which is "text/javascript"
      for our purposes. MIME is a standard way to describe the contents of a file over the Internet,
      such as "text/plain: and "image/gif ". This gets around the problem of three-letter filename
      extensions (.htm or .txt) left over from MS-DOS, 20 years ago.
          The MIME standard, which originated with e-mail systems, allows a web server to tell a browser
      how to interpret the stream of bits being sent. For instance, the only way for a web browser to
      know that the file http://www.example.com/ is an HTML document is through its MIME type.
      <script language="JavaScript" type="text/javascript">
          var a = 1;
          var b = 2;
          var c = a + b;
          document.write (c);
      </script>

          Later in this chapter, we will look at another use for the <script> tag that deals with external
      JavaScript content.


 Use <noscript> for Browsers That Don’t
 Support Scripting
      Even today, with all the technical advances made in web browsers and web programming
      languages, not every browser supports JavaScript. For instance, many mobile phones provide
      Internet access, but they are severely limited in screen size, color, audio, and scripting capabilities.
      There are also web browsers for PCs (like the one embedded in Microsoft Word) that do not
      support advanced capabilities such as JavaScript. And some pre-JavaScript browsers are still in
      use, such as Netscape Navigator 1.0.
           It is true, however, that supporting non-JavaScript-compatible devices is less important now
      than in 1995, when JavaScript first came out. But as the variety of computer operating systems
      and hardware devices increases over time, it may again become important to provide alternate
      content for some users.
           The HTML <noscript> tag is used to provide content to users whose browsers do not support
      JavaScript. It works because JavaScript-enabled browsers ignore any content between the <noscript>
      tag, for instance:
      <html>
          <head>
              <title>JavaScript Test</title>
          </head>
          <body>
              <h1>for Loop</h1>
              <script language="JavaScript" type="text/javascript">
              <!-- // Begin
CHAPTER 6: Embed JavaScript in a Web Page   155

var Fahrenheit;
for (var Celsius = 10; Celsius <= 60; Celsius = Celsius + 5) {
    document.write (Celsius + "&deg;C = ");
    Fahrenheit = (Celsius * 9/5) + 32;
    document.write (Fahrenheit + "&deg;F<BR>");
    if (Fahrenheit > 100) {
        // It's getting hot in here
        break;
    }
}

        // End -->
        </script>                                                                      6
        <noscript>
        You must have a JavaScript-enabled browser
        to visit this web page.
        </noscript>
    </body>
</html>

  This code will show users with JavaScript-enabled browsers the following output.
156      How to Do Everything with JavaScript


      However, users whose browsers do not support JavaScript will see this message instead.




      The only reason the JavaScript is not output to the screen as well is the HTML comment tags,
      <!-- and -->, that surround the script.
          Inside the <noscript> tag, you can choose to simply inform the user that a JavaScript-enabled
      browser is required. But you could also provide replacement content for the JavaScript, as in this
      example:
      <noscript>
          10°C = 50°F <BR>
          15°C = 59°F <BR>
          20°C = 68°F <BR>
          25°C = 77°F <BR>
          30°C = 86°F <BR>
          35°C = 95°F <BR>
          40°C = 104°F <BR>
      </noscript>

         This would allow users with a wide variety of browsers and hardware devices to view your
      web site properly. Of course, it is not always possible to replace JavaScript content with plain
      HTML text.
CHAPTER 6: Embed JavaScript in a Web Page                  157

Load an External JavaScript File
   JavaScript does not always have to be embedded inside the HTML file. Often it is convenient to
   have one file that contains the JavaScript and have multiple HTML files import it for their use.
   Using this technique, it would be easier to make changes to the JavaScript, since you do not have
   to change each of the HTML files.
        First, you must have a text file that contains nothing but JavaScript. Let us assume the following
   file exists on the web server, and is named sample.js.
   // SAMPLE.JS
   //
   // isFloat() function:
   //     Checks a string to see if it contains a
   //     floating-point number; returns true or false
                                                                                                               6
   //
   function isFloat (s)
   {
       // Format accepts "9", "9.", "9.9", and ".9"
       var reFloat = /^((d+(.d*)?)|((d*.)?d+))$/;

        return reFloat.test(s)
   }

            The .js file extension is commonly used in Windows systems to indicate that the
            file contains JavaScript, although any extension (such as .txt) can be used.

       We use the src attribute of the HTML <script> tag to import the external JavaScript file.
   <html>
       <head>
           <title>JavaScript Test</title>
           <script language="javascript" src="sample.js"></script>
       </head>
       <body>
           <h1>Check for a Floating Point Number</h1>

           <script language="JavaScript" type="text/javascript">
               document.write("Is "12.345" a float? " +
                   isFloat("12.345") + "<br><br>");
               document.write("Is "Twelve" a float? " +
                   isFloat("Twelve") + "<br><br>");
           </script>
       </body>
   </html>
158      How to Do Everything with JavaScript


      We can then call the isFloat() function defined in our external JavaScript file in another <script>
      section elsewhere in the web page. In this manner, the isFloat() function can easily be shared
      among multiple web pages.
               HTML <script> tags that import an external JavaScript file cannot also contain
               JavaScript. They must be empty.

          The result of importing an external JavaScript file is shown in Figure 6.1.


 Call JavaScript Using Hyperlinks
      Not all JavaScript executes immediately after a web page is loaded. We will examine web browser
      events, which allow JavaScript to run in response to user actions, in Chapter 9. Another way to
      invoke JavaScript in response to a user event is as the destination of a hyperlink.
      <A HREF="javascript:alert('Hello')">Click me</A>




       FIGURE 6-1      Functions defined in external JavaScript files can be called elsewhere in the
                       HTML page.
CHAPTER 6: Embed JavaScript in a Web Page               159

       Loading this HTML into a web browser causes a clickable hyperlink to be displayed along
   with the caption “Click me.” When the user clicks the link, a JavaScript alert() message box pops
   up, saying “Hello.” The secret is the special "javascript:" prefix inside the HREF URL. This
   informs the browser that what we really intend to do is invoke a JavaScript command instead.
       Several JavaScript commands can be appended in one string, if separated with a semicolon.
   <A HREF="javascript:alert('Hello');alert('Goodbye')">Click me</A>

      More commonly, JavaScript hyperlinks are used to call predefined functions, instead of
   embedding one or more JavaScript statements inside the HREF attribute value itself.
   <A HREF="javascript:submitform()">Click here to submit the form</A>

        In this example, when the user clicks the hyperlink labeled “Click here to submit the form,”
   JavaScript will call a function named submitform(), which we assume is defined elsewhere on           6
   the web page.
        In the next chapter, we will examine the issues web developers face when creating cross-
   platform-compatible JavaScript. JavaScript programs that work in one web browser will not
   necessarily work in another, as there are dozens of combinations of browsers, hardware
   platforms, and operating systems. Knowing how to work around these differences is important
   in real-world web development.


Learn More about the Topics in this Chapter
   The following are a few web sites where you can learn more about HTML and Cascading
   Style Sheets:

       ■   Webmonkey HTML Basics: http://hotwired.lycos.com/webmonkey/teachingtool
       ■   SitePoint: http://www.webmasterbase.com
       ■   Web Design Group CSS Reference: http://www.htmlhelp.com/reference/css
       ■   Dave Raggett’s Introduction to CSS: http://www.w3.org/MarkUp/Guide/Style
This page intentionally left blank
Create Scripts
Chapter 7   That Work in
            Every Browser
162      How to Do Everything with JavaScript


      How to...
          ■   Understand browser differences
          ■   Detect what type of browser the user is running
          ■   Query the document model
          ■   Stick to web standards
          ■   Write cross-browser code

      In the early days of JavaScript development, handling irregularities between the different browser
      makers and versions was a difficult task. After all, some browsers did not support JavaScript at
      all (like Netscape 1.0). Even if you had a browser that supported JavaScript, the underlying
      document model (DOM) was different between different browsers, which meant JavaScript
      errors were a common sight.
           This difficulty of developing JavaScript code that worked correctly in every browser was
      caused primarily by several factors:

          ■ New browser releases every few months
          ■ An ongoing contest between browser companies to add new features
          ■ Lack of an HTML or JavaScript standard
          It took some time, but eventually the problems started to go away as JavaScript stabilized.
      And as users began to gradually upgrade to version 4.0 browsers and beyond, JavaScript
      developers had an easier time developing cross-platform-compatible code.
          Unfortunately, some of the impending changes to JavaScript will force web developers to
      have to start coding for browser differences again. The reasons for this new period of instability
      are likely to include:

          ■ Inconsistent support for JavaScript 2.0
          ■ New browser releases every few months (particularly from Mozilla)
          ■ Inconsistent JavaScript support for new technologies, such as XML and CSS
      Only time will tell how much heartache these factors will cause web developers.


 Understand Browser Differences
      According to a recent survey, Microsoft Internet Explorer (IE) is used by approximately 94 percent
      of web surfers. Netscape and Mozilla have a combined usage of approximately 2 percent. The
      remaining 4 percent is divided among other companies such as Opera or is lost due to rounding.
CHAPTER 7: Create Scripts That Work in Every Browser            163

     These numbers are likely to change over the coming months and years. The largest Internet
service provider (ISP) in the United States recently announced it would start using Netscape as
its default browser, and that could potentially have a large impact on these numbers.
     Looking at recent browser popularity statistics a little closer, as in Table 7-1, we can see that
half of surfers have not yet upgraded to the most recent versions of their preferred web browsers.
     Fully 54 percent of all web surfers are using browsers that are not the latest release from either
Microsoft or Netscape. So be careful when creating JavaScript programs that rely too much on
proprietary or recently added features. Using those features without taking proper precautions
can cause errors for a significant portion of your audience, even if the application works fine in
the browser installed on your PC.

What Kind of Errors Can Occur?
When designing any computer program, it is important to keep in mind that errors are likely to
occur despite the programmer’s best efforts to avoid them. This is especially true of JavaScript
programs that are used across a wide variety of browsers and operating systems. When developing             7
JavaScript code, you are likely to find the following sources of errors:

    ■ Differences in the Document Object Model of each browser version
    ■ Client computers running old browsers (such as Netscape 3.0) that do not support
         certain JavaScript functionality
    ■ Client computers with certain technologies turned off, such as cookies or Java
    ■ New web-enabled technologies, such as hand-held devices, mobile phones, and even
         appliances, such as refrigerators

    In this chapter, we will take a look at some of the common techniques for avoiding these
types of errors.


 Browser                                               Usage
 IE 6                                                  46%
 IE 5                                                  44%
 IE 4                                                  2%
 Netscape 4                                            2%
 Netscape 6, Netscape 7, Mozilla (collectively)        1%
 Older IE                                              less than 1%
 Older Netscape                                        less than 1%

Source: TheCounter.com (http://www.thecounter.com)
 TABLE 7-1         Recent Web Browser Usage Statistics
164      How to Do Everything with JavaScript


      Detect What Type of Browser the User Is Running
      Running a modern or complex JavaScript program in an older browser is likely to cause numerous
      problems. Perhaps the easiest way to avoid these types of errors is to detect what type of browser
      the user is running and then either disable some of the program features or provide alternative
      code that performs the same task in a slightly different manner.
               Detecting the browser name and version information is often called browser sniffing.
               Much as a bloodhound can detect the unique scent of an individual, a browser sniffer
               attempts to detect and return the unique details of the browser software.

          To detect the browser manufacturer and version number, we will rely on the navigator DOM
      object. The navigator object has several methods and properties, but the three that we are
      interested in at the present time are appName, appVersion, and userAgent.
      var browserString = navigator.appName;
      var browserVersion = navigator.appVersion;
      var browserAgent = navigator.userAgent;

      alert (browserString);
      alert (browserVersion);
      alert (browserAgent);




                             Specifying JavaScript
                             Version Numbers
        The browser makers started off with the best of intentions. Both Netscape and IE allow
        developers to specify a JavaScript version number within the language attribute of the <script>
        tag. This prevents scripts from running in browsers that do not support the specified JavaScript
        version number. To create a script that will only run in browsers that support JavaScript 1.2,
        you would use the following code:
        <script language="JavaScript1.2">

            The same can be done for all versions of JavaScript up to version 1.5. (A listing of
        JavaScript version numbers and how they relate to browsers can be found in Chapter 1.)
            Unfortunately, very few web developers knew that this could be done, and fewer still
        actually used this technique when creating cross-browser scripts. On top of that, this method
        does not help developers solve the DOM-related differences between the various browsers.
            So, although this technique is still available, it cannot be relied on to solve cross-browser
        scripting problems.
CHAPTER 7: Create Scripts That Work in Every Browser                165

    For Netscape web browsers (including the open-source Mozilla web browser), the
navigator.appName property always returns the same value regardless of the version or
operating system.




    For Microsoft Internet Explorer, the navigator.appName property also returns a predictable
value, regardless of the version.


                                                                                                       7



   Therefore, if your web page needed to display different text depending on the browser a visitor
was running, you could simply query the navigator.appName property, like so:
var browserString = navigator.appName;

if (browserString == "Netscape") {
    // Do something for Netscape/Mozilla here
    document.write ("Long live the lizard.");

} else if (browserString == "Microsoft Internet Explorer") {
    // Do something for Microsoft here
    document.write ("You will be assimilated.");

} else {
    // The browser is not one of the major two
    document.write ("Why must you always be so different?");
}

    However, navigator.appName is extremely limited in the amount of information it
provides. Other navigator properties provide more useful information. For instance, the
166      How to Do Everything with JavaScript


      navigator.appVersion property provides more specific browser version information. For Netscape
      browsers, the string returned from that property is quite straightforward.




               This screenshot was taken from Netscape 7.0 running on Windows 98. Just to make life
               more confusing for web developers, both Netscape 6 and 7 return their version number
               as “5.0.” However, Netscape did not produce a version 5 (the version number jumped
               from 4.8 to 6.0), so this version number is inaccurate.

          Similarly, Microsoft Internet Explorer returns its version information in the
      navigator.appVersion string, as we can see from the following snapshot taken from
      Microsoft Internet Explorer 6.0.




          Recent releases of the Microsoft web browser always report the version number as 4.0
      compatible. However, the actual version number is embedded later in the same string (in this
      case, MSIE 6.0).
          The Mozilla 1.x, Netscape 6.0, and Netscape 7.0 browsers are all based on the same source
      code, so their behavior is very similar. If you ever need to get the exact browser name and version
      number from these browsers, you can query the userAgent property of the navigator object. As
      you can see from the following illustration, it contains some very specific version number
      information, right down to the exact date the browser was compiled.
CHAPTER 7: Create Scripts That Work in Every Browser             167

   Using these three properties, we can create a JavaScript function that will detect the exact
browser type the user is running:
function getBrowserInfo() {
    // Define variables to contain the results
    var browserName = navigator.appName;
    var browserVersionNum = parseFloat(navigator.appVersion);
    var browserAgent = navigator.userAgent;

     // Boolean (true or false) variables to detect browser type
     var is_IE = (browserAgent.indexOf("MSIE") != -1);
     var is_NN = (browserName.indexOf("Netscape") != -1);

     // Based on browser type, retrieve version number
     if (is_NN) {
         if (browserVersionNum >= 5.0) {
                                                                                                    7
             var tempStart = browserAgent.indexOf("Netscape/");
             if (tempStart == -1) {
                  // "Netscape/" not found; must be Mozilla
                  tempStart = browserAgent.indexOf("rv:");
                  tempStart += 3;
                  browserName = "Mozilla"
                  var tempEnd = browserAgent.indexOf(")", tempStart);
             } else {
                  // "Netscape/" found; must be Netscape Gecko
                  tempStart += 9;
                  var tempEnd = browserAgent.length;
             }
             var browserVersion =
                  browserAgent.substring(tempStart, tempEnd);
         } else {
             // version < 5.0; must be old Netscape
             var browserVersion = browserVersionNum;
         }

     } else if (is_IE) {
         var tempStart = browserAgent.indexOf("MSIE");
         tempStart += 5;
         var tempEnd = browserAgent.indexOf(";", tempStart);
         var browserVersion =
             browserAgent.substring(tempStart, tempEnd);
     }

     // Create new property of navigator object based on real
168       How to Do Everything with JavaScript

            //     version number
            navigator.appRealVersion = browserVersion;

            return;
      }

      getBrowserInfo();

      document.write ("<h1>You appear to be running:<br><br>");
      document.write ("<b>" + navigator.appName + "</b> <i>version</i> ");
      document.write ("<b>" + navigator.appRealVersion + "</b></h1>");

           As you can see, we have to do a fair amount of coding gymnastics to figure out the actual
      version number of the various flavors of Netscape browser. For Netscape 4 and earlier, the
      navigator.appVersion property returns the correct value. Since Netscape 6 and 7 and Mozilla
      all return 5.0 as the navigator.appVersion, we have to start searching the navigator.userAgent
      property for the appropriate value.
               The preceding code has been simplified for the purposes of this example and thus does
               not cover all the possible browser types or versions. For an excellent example of a
               browser-detecting script, I recommend checking out Bob Clary’s Practical Browser
               Sniffing Script at http://bclary.com/xbProjects-docs/ua, which uses the properties of the
               navigator object to determine the browser type and version. That web site also contains
               a script (at http://bclary.com/xbProjects-docs/xbDOM) that allows you to use one
               standard set of DOM objects across all browsers.

          The following illustrations show how our little function runs in Netscape 2.0 and Netscape 7.0.
CHAPTER 7: Create Scripts That Work in Every Browser               169




                                                                                                      7



     Microsoft Internet Explorer has always provided its version number in the exact same way.
It reports itself as Netscape 4.0 compatible in the navigator.appVersion property and leaves the
actual software version number embedded elsewhere in the same string. It is relatively easy to
search for it using the indexOf() method of the JavaScript String object.

Query the Document Model
The problem with relying on code that checks for browsers by name and version is that it’s
not foolproof. Currently, about 96 percent of web surfers use one of the two major browsers—
Netscape or IE. But what about the other 4 percent—surfers who choose another brand, such
as Opera or Konqueror? New browsers are being developed, and web sites will not work reliably
if they are only coded to work with the top two brands.
     The other problem is that as new versions of IE and Netscape are released, support for
different features changes. For instance, Netscape 4 supported a layout method called layers,
but support was later dropped when Netscape 6 came out. (We will discuss layers more in the
section entitled “Write Cross-Browser Code.”)
     The easiest way to get around the problem of the wide variety of available browsers (both in
the present and in the future) is to write code that checks to see if a DOM method exists before
attempting to use it.
     The first official version of the Document Object Model (known as DOM 1) defines a
method of the document object called getElementById(). Recent browsers (such as IE 5 and
Netscape 6) support it, but older browsers do not.
     Simply calling the getElementById() method in a browser that does not support it will cause
an error:
var objptr = document.getElementById("carname");
170      How to Do Everything with JavaScript


          So if you wanted to check to see if the current browser supports the getElementById()
      method before using it, you would simply query the document object to see if it has a member
      by that name before calling it:
      if (document.getElementById) {
           var objptr = document.getElementById("carname");
      }

          The preceding code will work in any browser, since browsers that do not support that method
      will not execute the code inside the if statement. Of course, in those browsers, the variable objptr
      would not be set, so it is best to have alternate code to handle those situations:
      if (document.getElementById) {
           var objptr = document.getElementById("carname");
      } else {
           alert ("Sorry, this web page will not work in your browser.");
      }

          Of course, if you have to surround each and every call to a DOM method with its own if
      statement, your program will be long and inefficient. So the best approach may be to combine
      the browser sniffing method with the DOM detection method to get the best of both worlds.


 Stick to Web Standards
      In the early days of web development, the two largest browser makers were competing
      aggressively for market share—perhaps too aggressively. One of their favorite tactics was to
      try to outdo each other in terms of features. Consumers would download and install the newest
      release of their favorite browser, and within days the next release would be available for download.
      Large companies, who sometimes require months to test and approve new software for use,
      found themselves up to two full versions behind the current release.
           Of course, this led to two HTML standards instead of one, which made the web developer’s
      job a lot more complicated than it had to be. Luckily for us, both Microsoft and Netscape
      eventually decided that they would hold off implementing new HTML and JavaScript features
      until they were approved by a standards committee.
           However, as a result of the early “wild West” mentality, there are a number of nonstandard
      coding practices that should be avoided in order to achieve cross-platform compatibility. Table 7-2
      contains a list of elements that are not part of the HTML 4 standard.
           These proprietary markup tags should be avoided if you wish to create web pages that work
      consistently in any browser.
               If you want to check your web page to see if it conforms to the official standards, the
               W3C web site provides an HTML validation service at http://validator.w3.org. This
               tool is the easiest way to see how far your web page deviates from the official standards.
               It even identifies any HTML code that contains problems.
CHAPTER 7: Create Scripts That Work in Every Browser              171

    Proprietary Markup         Supporting Browser(s)
    <layer>                    Netscape 4 (only)
    <marquee>                  IE
    <bgsound>                  IE
    <embed>                    IE, Netscape
    <noembed>                  IE, Netscape
    <multicol>                 Netscape
    <spacer>                   Netscape
    <nobr>                     IE, Netscape
    <wbr>                      IE, Netscape
    <blink>                    Netscape
    <xmp>                      IE, Netscape
    <listing>                  IE, Netscape
                                                                                                        7
    <plaintext>                IE, Netscape
    <keygen>                   Netscape
    <layer>, <ilayer>          Netscape
    <nolayer>                  Netscape
    <server>                   Netscape
    TABLE 7-2      Proprietary Markup Tags, Not Part of Official HTML Standard



Write Cross-Browser Code
   Earlier in this chapter, we played with some JavaScript code that could be used to detect the
   exact name and version number of the client browser. In this section, we will put similar code
   to use with dynamic HTML.
       Dynamic HTML (or DHTML for short) is an extension of the HTML standard that allows
   JavaScript programs to change and modify a web page after it has been loaded in the browser,
   without having to go back to the web server for a new page. For the most part, JavaScript
   accomplishes this through the manipulation of methods and properties in the browser’s DOM.
       Dynamic HTML is used regularly by Internet sites to provide fancy drop-down menus,
   images, and text that change when you move the mouse cursor over them and e-commerce
   shopping carts that recalculate the total cost of an order every time a check box is selected or
   cleared. In recent months, advertisers have caught the DHTML bug and are creating dynamic
   advertising that travels across the web page (and can’t be turned off or avoided).
       Cross-browser DHTML is difficult to code, however, since the JavaScript code required for
   Netscape and Microsoft browsers is quite different. While standardization has made programming
   HTML and basic JavaScript much easier, compared with only a few years ago, the implementation
   of vastly different DOMs among the browsers is one of the last remaining wilderness areas.
172      How to Do Everything with JavaScript


           Figure 7-1 shows an example of a web page that uses DHTML. The hierarchical tree on the
      left side of the screen can be expanded and contracted with a simple mouse click. Menu items
      are displayed and hidden dynamically, without having to request new HTML from the web
      server. This type of DHTML menu gives a nice effect for visitors to your web page.
           One of the first difficulties you are likely to encounter is that Netscape 4 uses a method
      called layers to define areas of a web document that can have a style applied to them.
      <html>
          <head><title>Layers sample</title></head>
          <body>

                <h1>Netscape Layers Example</h1>

                <layer id="mylayer">
                <font color="white"><b>A black square</b></font>
                </layer>

                <layer id="mylayer2">
                <b>A gray square</b>
                </layer>

              <script language="JavaScript" type="text/javascript">
                  document.layers["mylayer"].bgColor = "black";
                  document.layers["mylayer2"].bgColor = "#CCCCCC";
                  document.layers["mylayer2"].moveBy (60, 10);
              </script>
          </body>
      </html>

          This HTML code is designed to work in Netscape 4.x web browsers only. Our code defines a
      Netscape layer named mylayer using the HTML <layer> tag. We define a second layer named
      mylayer2. Using JavaScript, we are able to change the background colors of the two layers, and
      move one of them so that they don’t completely overlap. The effect can be seen in Figure 7-2.
          Unfortunately, the preceding code does not work in any version of IE or in the newer
      Netscape 6 browsers. We will have to modify our code a little to detect the type of browser
      running, and perform different tasks based on that.
          First, we need to change the layers to work in all browsers. The following code does not
      properly conform to HTML standards (since the <layer> tag is not part of the standard), but it
      will work in both IE and Netscape.
CHAPTER 7: Create Scripts That Work in Every Browser   173




                                                                                   7




FIGURE 7-1   An expandable tree menu using DHTML


<layer id='mylayer'>
    <div id='mydiv' style='position:absolute'>
         <font color="white"><b>A black square</b></font>
    </div>
</layer>

<layer id='mylayer2'>
    <div id='mydiv2' style='position:absolute'>
         <b>A gray square</b>
    </div>
</layer>
174      How to Do Everything with JavaScript




      FIGURE 7-2      Creating layers in Netscape 4


          Notice how we use the HTML standard <div> tag nested inside the nonstandard <layer> tag.
      Browsers that do not support <layer> will ignore it, as browsers that do not support <div> will
      ignore that tag.
          Next we need to modify the script to detect the type of browser running. We could use the
      getBrowserInfo() script from earlier in the chapter, but our needs are much simpler than that.
      All we need to do is detect the difference between Netscape 4, Netscape 6, and IE. To do that,
      we can use the following JavaScript code.
           <script language="JavaScript" type="text/javascript">
               var ua = navigator.userAgent.toLowerCase();
               var ie4 = ua.indexOf("msie") != -1;

                if (document.layers) {
                    // Netscape 4 code goes here
                } else if (document.getElementById && ie4) {
                    // IE code goes here
                } else if (document.getElementById) {
                    // Netscape 6 code goes here
CHAPTER 7: Create Scripts That Work in Every Browser                175

         }
     </script>

    This code works in a fairly simple fashion. Netscape 4 is the only browser whose document
object has a layers property, so checking for that property’s existence confirms that the browser
type is Netscape 4. We can do the same trick using the getElementById method of the document
object, except we still need to differentiate between IE 4 and Netscape 6. The navigator.userAgent
property allows us to do that.
    Finally, we add in the browser-specific DHTML code to manipulate the two <layer> or
<div> tags on the screen to create a visual effect.
<html>
    <head><title>Layers sample</title></head>
    <body>

          <h1>Cross-Browser Style Sheets Example</h1>                                                  7
          <layer id='mylayer'>
              <div id='mydiv' style='position:absolute'>
                   <font color="white"><b>A black square</b></font>
              </div>
          </layer>

          <layer id='mylayer2'>
              <div id='mydiv2' style='position:absolute'>
                   <b>A gray square</b>
              </div>
          </layer>

          <script language="JavaScript" type="text/javascript">
          var ua = navigator.userAgent.toLowerCase();
          var ie4 = ua.indexOf("msie") != -1;

          if (document.layers) {
              // Netscape 4 code goes here
              document.layers["mylayer"].bgColor = "black";
              document.layers["mylayer2"].bgColor = "#CCCCCC";
              document.layers["mylayer2"].moveBy (60, 10);

          } else if (document.getElementById && ie4) {
              // IE code goes here
              var div1 = document.getElementById("mydiv");
              var div2 = document.getElementById("mydiv2");
              div1.style.backgroundColor = "black";
              div2.style.backgroundColor = "#CCCCCC";
176      How to Do Everything with JavaScript

                      div2.style.pixelLeft = div1.offsetLeft + 60;
                      div2.style.pixelTop = div1.offsetTop + 10;

                } else if (document.getElementById) {
                    // Netscape 6 code goes here
                    var div1 = document.getElementById("mydiv");
                    var div2 = document.getElementById("mydiv2");
                    div1.style.backgroundColor = "black";
                    div2.style.backgroundColor = "#CCCCCC";
                    div2.style.left = (div1.offsetLeft + 60) + "px";
                    div2.style.top = (div1.offsetTop + 10) + "px";

              }
              </script>
          </body>
      </html>

         The resulting cross-browser compatible code can be seen in IE 6 in Figure 7-3 and
      Netscape 7.0 in Figure 7-4. The results are completely identical to those in Netscape 4.




       FIGURE 7-3      Microsoft IE 6 interprets the <div> tag and the DHTML JavaScript code
                       correctly.
CHAPTER 7: Create Scripts That Work in Every Browser                 177




                                                                                                        7




 FIGURE 7-4      Even though Netscape 7.0 requires slightly different JavaScript, the same effect
                 is created.

This is a good example of the difficulties JavaScript programmers sometimes face when developing
code that works in any browser.
    In the next chapter, we will take a look at one of JavaScript’s primary duties on the Internet—
helping users fill out forms. You will learn how to build a form in HTML, learn about all the
controls that can go into a form, and see how JavaScript can be used to validate the data entered
before it is sent to the server for processing.
This page intentionally left blank
Manipulate
Chapter 8   Web Forms
180      How to Do Everything with JavaScript


      How to...
          ■   Request user input using an HTML form
          ■   Retrieve and set form control values
          ■   Prepare form data for server submission
          ■   Handle multiple forms

      In previous chapters, we have seen how JavaScript can be used to provide dynamic web pages
      that contain animated menus or are slightly different depending on the web browser being used
      or the time of day. As time goes on, developers will find it easier than ever to include these special
      JavaScript tricks on their own personal home pages.
           What has made JavaScript indispensable as a development tool for most professional web
      developers is its ability to handle user input. JavaScript makes the gathering and processing
      of user information easier—for both the user and the web developer. JavaScript can assist in
      many ways:

          ■   Store and retrieve bits of information on the user’s computer (called cookies)
          ■   Verify that all mandatory form fields were provided
          ■   Validate the proper formatting of user-entered data
          ■   Provide instant feedback to the user without having to go to the web server

          And best of all, it is often very easy to do all these things—only a few lines of code are needed.
      By solving many more problems than it created, JavaScript quickly became an indispensable tool
      for serious web developers.


 Understand HTML Forms
      The best and most flexible way to ask for user input is with HTML forms. A form, in web
      programming, is a series of one or more user controls that are designed to capture user input.
      A user control is typically a text box, a list box, or a button of some sort that allows the user to
      provide information to the web browser. In fact, web forms are modeled after paper forms, like
      those you fill out for a job application or a survey.
          There are 13 user controls in HTML:

          ■   Text box Allows a single line of text input
          ■   Password box       Allows a single line of text input, protected by asterisks
          ■   Text area Allows one or more lines of text input
          ■   Hidden     Can contain a single line of text, hidden from the user
          ■   List box User can choose from one or more predefined choices
          ■   Radio button       User can choose one of many predefined choices
          ■   Check box       User can choose any number of many predefined choices
CHAPTER 8: Manipulate Web Forms              181

    ■   File   User can upload a file from the local machine to the web server
    ■   Push button     Causes a program-defined action to occur
    ■   Submit button     Causes the form to be submitted
    ■   Image button Creates a graphical submit button
    ■   Reset button Causes the form to be cleared
    ■   Object    Creates a special (user-defined) input control
     Each of these controls performs a special function in requesting user input. Which control
you use depends a lot on the individual circumstances. For instance, when you need the user to
select one of 50 choices (like selecting which state they live in), you would normally go with a
list box control, which allows you to provide dozens of options in very little space. Choosing to
display 50 radio buttons instead takes up a lot more space and may cause the rest of the form
to scroll off the bottom of the screen.

Request User Input Using an HTML Form
To see what a typical HTML form looks like, let’s examine the web page in Figure 8-1. The             8
United States Postal Service (www.usps.gov) provides this online form to register address changes
of families or businesses that move and would like their mail forwarded to their new location.




 FIGURE 8-1      The change of address form on the U.S. Postal Service web site
182      How to Do Everything with JavaScript


          The first form field on the screen, labeled “Prefix Title,” allows the user to select from a
      number of name prefixes (such as “Dr.,” “Mr.,” and “Mrs.”). If they do not use a prefix before
      their name, they can select “N/A” for not applicable. This control is called a list box, since by
      pressing the down arrow button, the user will see several options from which they can choose.




          The form field labeled “First Name” is a text box, allowing the user to enter one or more
      characters using the keyboard. Sometimes, programmers place restrictions on this field using
      JavaScript, but often the user can enter any combination of letters, numbers, or special symbols.
      Programmers can use HTML to specify a maximum length for this field.
          When the user has finished entering his or her personal data, they are asked to click on an
      HTML submit button. The submit button causes the data from the web form to be sent to a program
      waiting on a web server for processing. Using JavaScript, web developers can have the data validated
      before allowing the web server submission to proceed.

      Process Form Input with Client-Side JavaScript
      Once the form has been filled out and submitted, it is often sent to a web server for processing.
      It is important to note that it does not have to be sent to a web server—oftentimes web forms can
      be processed entirely on the client using JavaScript. You will often see these client-side forms in
      the form of online calculators and similar tools, where JavaScript is smart enough to calculate the
      desired result and perform the requested action without needing help from a web server.
CHAPTER 8: Manipulate Web Forms                183

    Figure 8-2 shows an example of such a client-side form. The web page displayed in the
figure (http://javascript.internet.com/calculators/amortization.html) can calculate the monthly
mortgage payments if you provide the amount of the loan, the interest rate, and the amortization
term. This is calculated using a JavaScript function embedded in the web page.
    We will examine how to create JavaScript code that can respond to web forms later in this
chapter, in the “Catch Web Form Submissions with onsubmit” section.

Process Form Input on a Web Server
Web forms that require complex processing—those that access a database, for instance—must be
submitted to an application waiting on the server. There are many prominent technologies available
to create these form-handling programs:

    ■ Server-side JavaScript
    ■ Application Server Pages (ASP)
    ■ Java Servlets
                                                                                                       8




 FIGURE 8-2      Calculating monthly mortgage payments using an HTML form
184      How to Do Everything with JavaScript


          ■   Java Server Pages (JSP)
          ■   Perl
          ■   PHP
          ■   A compiled binary written in almost any language (such as C)

          Once these programs accept the data submitted by the web form, they usually perform any
      processing required and then respond to the browser with another HTML page. The communication
      process between client and server is depicted in Figure 8-3. It shows an example of a user performing
      a search at one of the major search engine web sites. The web server accepts the keywords using
      an HTML form, checks its database for related web pages, and returns a new HTML web page
      with the results.

      Insert an HTML Form into a Web Page
      Forms are added to web pages in the same way that images, text, and other elements of the page
      are, with HTML markup. Developers can define all the parts of a form, including the controls it
      contains and how they are arranged, using standard HTML tags.

      Use the <form> Tag
      In HTML, forms are defined using the <form> tag. The <form> tag allows you to define the type
      of form you wish to create, including the URL of the program waiting to accept the user’s input
      (if any). These are specified using the <form> element’s attributes. An attribute is an element’s
      named parameter and associated data. Attributes are specified in the following manner:
      <element attribute1="value1" attribute2="value2" ... attribute3="value3">




       FIGURE 8-3      Communication between client and server when an HTML form is submitted
CHAPTER 8: Manipulate Web Forms           185

   The <form> element has the following attributes:

   ■    id   String that must be unique across the entire web page
   ■    class    List of associated CSS classes
   ■    style Inline CSS style commands
   ■    title Advisory title
   ■    lang ISO language code
   ■    dir Direction of text (right to left or left to right)
   ■    action    URI of program that will handle form data
   ■    method      The way data will be transmitted to the server (either GET or POST)
   ■    enctype MIME encoding type
   ■    accept List of MIME types accepted for file upload
   ■    accept-charset List of supported charsets

    In addition to all those attributes, the <form> element can also contain a number of event       8
handlers. Events are actions usually initiated by the user, such as a mouse movement or certain
keypresses. Event handlers are JavaScript code and functions that are designed to act when
certain events happen. We will examine all the predefined HTML event handlers in more detail
in Chapter 9.




                        Have a Form’s Contents
                        Mailed to You
  The <form> tag’s action attribute allows you to specify the web server URI for the program
  that will process the form. Typically, this program is an ASP page, Java servlet, or a Perl
  script running on the target web server.
       You can also direct the browser to e-mail you the contents of the form instead. This is
  done by providing an e-mail address using the mailto: protocol to the action attribute. To
  construct a URI using the mailto: protocol, you simply append the actual e-mail address
  to the mailto: string, like so:
  mailto:president@whitehouse.gov

      If you used the preceding string as the URI for the action attribute, the contents of the
  web form would be mailed to the President of the United States.
      This technique is not guaranteed, however, since it uses the mail program installed on the
  user’s computer. The program might not be set up correctly for sending e-mail, or the user
  might cancel the e-mail from being sent.
186      How to Do Everything with JavaScript


          For now, we are only concerned with two possible events that can happen to a web form:

          ■ onsubmit JavaScript code that will be run before the form is submitted
          ■ onreset JavaScript code that will be run before the form’s data is erased
          Some HTML elements have mandatory attributes, that is, attributes that must always be
      present. The <form> element is one of those, as the action attribute must always be specified
      in order for the HTML to be valid.
          The most basic type of form is the following:
      <form action="#">
      </form>

          This HTML code creates an empty form that does not contain any controls. Forms such
      as this are quite useless, of course, because they have no purpose. HTML <form> elements by
      themselves are invisible, in that they do not have a visual component. Form controls (buttons and
      text boxes, for instance) are the visual components of forms. Forms can also contain text, tables,
      and other HTML elements.
               It is common to use the pound sign (#) as the value of the action attribute of the <form>
               tag when none is needed, since the action attribute is mandatory and cannot be omitted.
               You might use this for forms designed to only exist on the client, which will never need
               to be submitted to a server. The pound sign (#) is one of the shortest valid URLs.

      Add Form Controls
      As we have seen, forms are pretty useless without controls. Form controls allow a web page to
      accept user input. Some controls allow users to enter text themselves, and some provide users
      several predefined options to choose from. Form controls are added to <form> elements with
      HTML of their own. Table 8-1 lists the common input controls along with the HTML required
      to add them to a web page.

      Accept Text Input with a Text Box
      Perhaps the most common type of form control is the text box. In fact, the text box control is
      the default type of the <input> element. The following HTML code will create a web form with
      a single text box inside.
      <form action="#">
          <input>
      </form>
CHAPTER 8: Manipulate Web Forms                 187

 Control Name                               HTML Code
 Text box                                   <input type="text"…>
 Password box                               <input type="password"…>
 Text area                                  <textarea…> </textarea>
 Hidden text                                <input type="hidden"…>
 List box                                   <select…> </select>
 Radio button                               <input type="radio"…>
 Check box                                  <input type="checkbox"…>
 File upload                                <input type="file"…>
 Push button                                <input type="button"…>
 Push button                                <button…>
 Submit button                              <input type="submit"…>
 Image button                               <input type="image"…>
 Reset button                               <input type="reset"…>
                                                                                                          8
 Object control                             <object…> </object>
 TABLE 8-1        A List of HTML Form Controls



     Of course, creating a form like that has several drawbacks. First, anyone who encountered
that form in their web browser would not know what to do with it—the control is unlabeled. It’s
just a text box sitting on a page by itself. Second, web developers looking at that code might find
it a bit confusing, since the <input> control has so many forms. It might be better to explicitly set
the control type.
     A better example of a web form would be the following:
<form action="#">
    Please enter your age: <br>
    <input type="text" name="age">
</form>

    This type of web form is easier to use for both the web developer and the web page visitor.
    The text box control has several attributes that give developers more control over the look
and behavior of the control:

    ■ id String that must be unique across the entire web page
    ■ class List of associated CSS classes
188      How to Do Everything with JavaScript


          ■   style Inline CSS style commands
          ■   title Advisory title
          ■   lang ISO language code
          ■   dir Direction of text (right to left or left to right)
          ■   name The name of the control
          ■   value The default value
          ■   size The size of the control on the screen, in characters
          ■   maxlength     The maximum number of characters that can be entered
          ■   readonly Locks the control so its value cannot be modified by the user
          ■   accesskey Sets the keyboard shortcut key
          ■   tabindex Sets the order in which controls receive focus on a form
          ■   disabled    Locks the control so that it cannot receive focus or be modified by the user
               In web programming, we say a control has focus when it is the currently active control.
               The browser often lets us know which control has focus by using a flashing vertical line
               for text boxes or some other highlight for buttons and other controls. Most browsers
               draw a temporary dotted box around nontext controls that have focus.

          Besides the preceding attributes, our input control can also capture a number of events as
      well. We will examine all the predefined HTML event handlers in more detail in Chapter 9.
      For now, we will only concern ourselves with the following HTML events:

          ■ onfocus JavaScript code that will be run when a control receives focus
          ■ onblur JavaScript code that will be run when a control loses focus
          ■ onchange JavaScript code that will be run when a control loses focus and
              the value of its contents has been altered

          By using some of these attributes on our text box, we can improve the look and behavior of
      our control:
      <form action="#">
          Please enter your <u>a</u>ge: <br>
          <input type="text" name="age" size="5" maxlength="3"
               value="" accesskey="A">
      </form>
CHAPTER 8: Manipulate Web Forms                189

     We have reduced the horizontal length of the control to five characters wide by using the
size="5" attribute on the <input> control. By specifying maxlength="3" we are restricting input
to a maximum of three characters in length. Since we are asking for an age, it is reasonable to
assume three digits will be enough.
     The value="" attribute sets the default contents of the field to an empty string. The accesskey
parameter, which is set to "A" in our example, allows users to jump to the control by using the
ALT-A key combination in most versions of Windows, or the CONTROL-A key combination for
most Mac systems.
         The key combination required to activate an access key is dependent on both the
         browser type and operating system, so check your browser documentation if you
         cannot get it to work.




                                                                                                         8




Provide a List Box Control
A list box is a convenient control to use when you need the user to select one of multiple choices.
In HTML, list boxes are created using the <select> element, and items in the list are defined
using the <option> element. There are two types of list boxes you can use inside your web-based
forms: the drop-down list box and the scrolled list box.
190      How to Do Everything with JavaScript



                             Privacy and the Internet

        HTML forms are commonly used to allow visitors to log in to a web site. Users must
        normally supply a valid user ID and password to the server before being allowed into
        the restricted areas of the site.
            From a developer’s point of view, a text box should be used to request the user ID from
        the user. As an added level of security, a password box control should be used to request a
        user’s password. The password box replaces the characters typed in with asterisks, so that
        password becomes ********. This is done so that other individuals looking at the same
        computer monitor (from over the user’s shoulder, for instance) will not be able to read the
        password.
            You should know, however, that this is a very weak type of security. Unless the form
        data is encrypted using Secure Sockets Layer (SSL), typically using HTTPS protocol, the
        password will be sent over the Internet as plain text, which can be easily read by anyone
        along the path or by anyone with access to the web server’s activity logs.


          The drop-down list box appears as a text box with a small arrow button next to it. Clicking
      the arrow causes the control to create a scrollable pop-up window in which the user can select
      one of multiple choices, as you can see here.
CHAPTER 8: Manipulate Web Forms                191

    Users cannot type their own text into the text box—they must select one of the predefined
items. This type of control is best used when there are at least three options to choose from, such
as when asking the user to select their home state or country. Other controls, such as radio buttons
and check boxes, are better for having the user select from only two or three options.
    The scrolled list box appears as a combination of a multiline text box attached to a vertical
scroll bar, as you can see here.




                                                                                                         8




    A scrolled list box is created by specifying the number of items to be displayed at once using
the size attribute of the HTML <select> element. Users may select more than one option from a
scrolled list box if the developer has specified the multiple attribute. A user can select multiple
options by holding down the CTRL (PC) or COMMAND (Mac) key on the keyboard when selecting
items from the list.
    The following HTML will create a form with a single drop-down list box inside it.
<form action="#">
What would you like for dinner?<br>
    <select name="dinner">
        <option selected value="1">Chicken</option>
        <option value="2">Beef</option>
        <option value="3">Pork</option>
        <option value="4">Fish</option>
        <option value="5">Vegetables</option>
192      How to Do Everything with JavaScript

          </select>
      </form>

           By specifying the size attribute, we can modify the drop-down list box to become a scrolling
      list box. Since our size attribute only allows three items to display at once, the user will be able
      to see the remaining two items by using the scroll bar.
      <form action="#">
      What would you like for dinner?<br>
          <select name="dinner" size="3">
              <option value="1" selected>Chicken</option>
              <option value="2">Beef</option>
              <option value="3">Pork</option>
              <option value="4">Fish</option>
              <option value="5">Vegetables</option>
          </select>
      </form>

          The HTML <select> element has several attributes that give web developers more control
      over the look and behavior of the list box control:

          ■   id   String that must be unique across the entire web page
          ■   class   List of associated CSS classes
          ■   style Inline CSS style commands
          ■   title Advisory title
          ■   lang ISO language code
          ■   dir Direction of text (right to left or left to right)
          ■   name Name of the control
          ■   size Number of rows to display at once
          ■   multiple Allows the control to accept multiple selections
          ■   tabindex Sets the order in which controls receive focus on a form
          ■   disabled    Locks the control so that it cannot receive focus or be modified by the user

          Beside the preceding attributes, our list box control can also capture a number of events as
      well. We will examine the predefined HTML event handlers in more detail in Chapter 9. The list
      box can capture the following three events:

          ■ onfocus JavaScript code that will be run when a control receives focus
          ■ onblur JavaScript code that will be run when a control loses focus
          ■ onchange JavaScript code that will be run when a control loses focus and
              the value of its contents has been altered
CHAPTER 8: Manipulate Web Forms              193

    The HTML <option> element has several attributes of its own:

    ■   id   String that must be unique across the entire web page
    ■   class   List of associated CSS classes
    ■   style Inline CSS style commands
    ■   title Advisory title
    ■   lang ISO language code
    ■   dir Direction of text (right to left or left to right)
    ■   selected   Defines this list item as the default
    ■   disabled    Locks the control so that it cannot receive focus or be modified by the user
    ■   label Defines a label for the list item
    ■   value The string returned to the server when a user selects the item

    The <option> element can also receive a number of events. We will examine all the
predefined HTML event handlers in more detail in Chapter 9.                                               8
Accept Text Input with a Text Area
One variation of the text box is the text area. The text area control accepts multiple lines of input
and is defined using the HTML <textarea> element. One drawback of the text area control is that
you cannot easily restrict the amount of data a user adds to that control.
    The most common attributes for the <textarea> element are rows, cols (columns), and name.
As you would expect, you specify the height of the control using the rows attribute, and the width
of the control using the cols attribute. For example, the following text area will hold 5 rows that
are 60 characters wide.
<form action="#">
    <textarea rows="5" cols="60">
    This is my example text area.
    </textarea>
</form>

    Default text is inserted between the <textarea> and </textarea> tags.

Add a Push Button Control to a Form
Unlike other controls, push buttons (or just buttons) are generally not used to provide user input.
Their purpose is to cause the browser to execute some JavaScript code through the button’s onclick
event handler. There is a special type of push button control called a submit button that can be
used to provide user input. We will examine submit buttons in the next section.
194     How to Do Everything with JavaScript


          In HTML, there are two ways to create a simple push button: with the <input> element and
      with the <button> element. The <input> element is used to create the most basic type of push
      button, as follows:
      <form action="#">
          <input type="button" value="Push me" onclick="dothis()">
      </form>

          The push button defined in this form will call a JavaScript function named dothis() when
      pressed. The value attribute defines the button’s caption, or the text label on the button.
          The <button> element allows developers to create a more complex type of push button. The
      <button> element accepts complex HTML input (including text and images) as its caption. For
      example, the following push button displays a check mark image next to the word OK, which is
      in bold print. It too will call the JavaScript dothis() function when clicked.
      <form action="#">
          <button onclick="dothis()">
              <img src="checkmark.gif">
              <font size="6"><b><i>OK</i></b></font>
          </button>
      </form>

         Here is how this special type of push button looks in a browser window.
CHAPTER 8: Manipulate Web Forms                 195

Add a Submit Button
Submit buttons are a special type of form control, in that they cause a form to submit itself to the
server. The variables and data defined in the form are sent to the web server application defined
in the action attribute of the <form> element, using the method defined in the method attribute.
     For instance, the following code defines a form that submits itself to an ASP web page. The
ASP web page is responsible for processing the data and sending a new web page for the browser
to display.
<form
    action="http://www.example.com/scripts/myscript.asp"
    method="GET">
    Full Name: <input type="text" name="fullname"><br>
    Age: <input type="text" name="age" size="5"><br>
    Date of Birth: <input type="text" name="DOB" size="10"><br>
    <input type="submit" value="Submit Form">
</form>

     When the user clicks the Submit Form button, the three other form controls on the form              8
(fullname, age, and DOB) will be sent to the ASP web page, along with whatever text the user
entered in those fields.
         Only named form fields will be submitted to the server for processing. Fields without
         an assigned name attribute, even text fields, will not be submitted to the server. It is
         common to omit the name of submit buttons. The only time it would be useful to name
         them would be if there were more than one submit button on a form and the server
         needed to know which button was used to submit the form.

Catch Web Form Submissions with onsubmit
Previously in this chapter, in the section entitled “Use the <form> Tag,” we saw that the HTML
<form> element has a number of predefined event handlers. Handling an event is known as
catching it, and in this section we will take a brief look at one of the <form> element’s events
and how to catch it.
    The onsubmit attribute allows us to specify some JavaScript code that will be executed
before the web form is submitted to the web server. This JavaScript code is usually stored inside
a function, and so the event handler only refers to that function. But sometimes the JavaScript
code will appear directly in the event handler attribute.
<script language="JavaScript" type="text/javascript">
function checkname() {
    alert("Your name is " + document.forms[0].fullname.value);
}
</script>

<form action="http://www.myserver.com/formhandler"
196      How to Do Everything with JavaScript

          method="GET"
          onsubmit="return checkname()">
          What is your name? <br>
          <input type="text" name="fullname"> <br>
          <input type="submit" value="Submit Form">
      </form>

          In the preceding HTML code, we have specified a JavaScript function that will be called at the
      time the form is submitted to the web server using the onsubmit event handler attribute of the
      <form> element. The function that will be called is checkname(), which we have defined just
      above the form. Once the checkname() function finishes, the form data will be sent to the URL
      http://www.myserver.com/formhandler for processing.
          Here you can see the HTML form that is created. I have already typed in the five letters of
      my first name as an example.




          The button labeled “Submit Form” is actually a submit button, which will cause the form
      to be sent to the web server. Before it is submitted, however, the checkname() function is called.
      That function simply retrieves the contents of the text box and displays it in a JavaScript alert box.
      Once the alert box is accepted by the user, the form sends its data to the web server for processing.
CHAPTER 8: Manipulate Web Forms                197




    Our onsubmit event handler actually has the ability to stop the web form from being submitted.
Returning the Boolean value false from the function causes processing to stop without the form
being submitted to the server.
<script language="JavaScript" type="text/javascript">
function checkname() {
    var username = document.forms[0].fullname.value;
    if (username != "Scott") {
        alert("Sorry, " + username + ". I cannot let you proceed.");
        return false;
    } else {
        return true;                                                                                   8
    }
}
</script>

    The preceding JavaScript function, when called by the same HTML form, will not submit to
the web server if the user does not type Scott into the name field.

Catch Events on Form Controls
Like the HTML <form> tag, form controls can also have programmable events. A program
can define a JavaScript function or code that will be executed when a certain event occurs. For
instance, JavaScript can detect when the mouse cursor passes over a control, when it has gained
or lost focus, or when its value has changed.
    For example, the following code demonstrates how some of the text box control’s events can
be captured.
<html>
    <head>
        <title>Capture Form Control Events</title>
        <script language="JavaScript" type="text/javascript">
        <!-- // Begin

          function modifylayer(changetext) {
              var lefield = document.getElementById("lastevent");
              lefield.innerHTML = changetext + "<br><br>&nbsp;";
198      How to Do Everything with JavaScript

                }

               // End -->
               </script>
           </head>
           <body>
               <h1>Capture Form Control Events</h1>

                <form action="#" method="get">
                Move the mouse in and out of this field,
                or change its contents.<br>
                <textarea name="samplefield" rows="10" cols="30"
                    onmouseover="modifylayer('mouseover')"
                    onmouseout="modifylayer('mouseout')"
                    onchange="modifylayer('change')"
                    onkeypress="modifylayer('keypress')"
                    >Sample text</textarea><br><br>

                Last event captured:
                <div id="lastevent"
                    style="background-color:#CCCCCC; font-weight:bold">
                <br><br>&nbsp;
                </div>
                </form>

          </body>
      </html>

          The body of the HTML document has an HTML <form> that contains a single control—
      a multiline text box called a <textarea>. We have also defined an HTML <div> area, which
      contains text that we can change using JavaScript.
          The <textarea> also defines a number of event handlers. The web browser will call a
      JavaScript function named modifylayer() if any of the following events occurs for this control:

          ■ onmouseover When the mouse cursor enters the control
          ■ onmouseout When the mouse cursor leaves the control
          ■ onchange When the contents of the control have changed and
              the control has lost focus
          ■ onkeypress When a keyboard key has been pressed
          We define the modifylayer() function using the <script> tag inside the document header
      section. That function will write the name of the event out to the <div> area we have defined.
CHAPTER 8: Manipulate Web Forms                 199

         You can see a list of all the browser events supported by Internet Explorer on
         Microsoft’s web site at http://msdn.microsoft.com/workshop/author/dhtml/reference/
         events.asp. We also discuss web browser events more thoroughly in Chapter 9.

     Of course, there is also a way to capture the name of the event without having to pass it to the
function explicitly using the window.event DOM object. We could modify our JavaScript code
to the following to take advantage of this technique.
           function modifylayer() {
               var lefield = document.getElementById("lastevent");
               var ename = window.event.type;
               lefield.innerHTML = ename + "<br><br>&nbsp;";
           }

    With this type of function, we would no longer need to pass the name of the event inside
each event handler. The modifylayer() function can handle all four events on its own.
           <textarea name="samplefield" rows="10" cols="30"
               onmouseover="modifylayer()"                                                                8
               onmouseout="modifylayer()"
               onchange="modifylayer()"
               onkeypress="modifylayer()"
               >Sample text</textarea><br><br>

   We can see from the following screen capture what this web page will look and act like in
a web browser.
200      How to Do Everything with JavaScript


 Retrieve and Set Form Control Values in JavaScript
      One of the code samples from the preceding section demonstrated one of the many possible ways
      of retrieving values from a web form. The DOM provides JavaScript programs several ways to
      access the controls on a form and their values, including:

          ■ As a property of the forms array
          ■ As key values in the elements array
          ■ Using one of three different methods of the document object
               Not all of these techniques work in older versions of the major browsers, so you may
               have to employ some of the cross-browser scripting techniques discussed in Chapter 7.

      Access Form Values Using the forms Array
      One technique that will work in all JavaScript-enabled browsers is accessing form controls using
      the forms array. The forms array is a property of the DOM document object; it contains an indexed
      list of all the forms on a web page. Indexes in JavaScript start at zero.
           We start by creating a variable that refers to the form itself.
      var myform = document.forms[0];

         We can then access any control on the form by name. For instance, the following code allows
      you to access the contents of a text box called fullname:
      var fullname = myform.fullname.value;

          As in “Accept Text Input with a Text Box,” earlier in this chapter, value is a property of the
      text box control. The preceding code placed the contents of that text box in a variable we called
      fullname.
          Using this technique allows us to access any control on the form, as long as it is named. The
      following code demonstrates a form that contains a text boxes, a list box, and a group of radio
      buttons. Before the form is submitted, a function named checkform() verifies that the user entered
      text or made a selection in each of the fields.
      <html>
        <head>
          <title>JavaScript Test</title>
          <script language="JavaScript" type="text/javascript">
          <!-- // Begin

           function checkform() {
              var myform = document.forms[0];

               // Accessing text boxes is easy
CHAPTER 8: Manipulate Web Forms   201

      var fullname = myform.fullname.value;
      var emailaddr = myform.email.value;

      // Which drop down item is selected?
      var ageIdx = myform.age.selectedIndex;
      var age = myform.age.options[ageIdx].value;

      // Which radio button is selected?
      var hearObj = myform.hear;
      var hear = "";

      for (var i = 0; i < hearObj.length; i++) {
         if (hearObj[i].checked) {
            hear = hearObj[i].value;
         }
      }

      // Check if any fields are blank
                                                                            8
      if ((fullname == "") || (emailaddr == "") ||
          (age == "None") || (hear == "")) {
         alert("Some information appears to be missing.");
         return false;
      } else {
         return true;
      }
  }

  // End -->
  </script>
</head>
<body>
    <h1>JavaScript forms Array</h1>

      <form action="#" onsubmit="return checkform()">
      <center>
      <table width="400" cellspacing="12">
      <tr>
         <td align="right"><b>Name:</b></td>
         <td><input type="text" name="fullname"></td>
      </tr>
      <tr>
         <td align="right"><b>Email:</b></td>
202      How to Do Everything with JavaScript

                 <td><input type="text" name="email"></td>
              </tr>
              <tr>
                 <td align="right"><b>Age:</b></td>
                 <td><select name="age">
                 <option value="None">-- Please select --</option>
                 <option value="16-32">16-32</option>
                 <option value="33-49">33-49</option>
                 <option value="Over 50">50+</option>
                 </select></td>
              </tr>
              <tr>
                 <td align="right"><b>How did you<br>
                    hear about us?</b></td>
                 <td valign="top">
                 <input type="radio" name="hear" value="t"> TV<br>
                 <input type="radio" name="hear" value="r"> Radio<br>
                 <input type="radio" name="hear" value="n"> Newspaper<br>
                 <input type="radio" name="hear" value="o"> Other</td>
              </tr>
              <tr>
                 <td align="middle" colspan="2">
                 <input type="submit" value="Send to server"></td>
              </tr>
              </table>

            </center>
            </form>
        </body>
      </html>

          Figure 8-4 shows how this form would look in a typical web browser.
          If we were to try to submit this form without filling out one of the fields, the checkform()
      function would catch it, and report this error:




      Access Form Values Using the elements Array
      Another way to access the controls on forms is through the elements array. The elements array
      is a sequential list of all the form controls that appear on a web page. To access the value of
CHAPTER 8: Manipulate Web Forms                203




                                                                                                        8




 FIGURE 8-4      A web page that contains various form controls


a specific control, you need to know its position in the array beforehand. This array is convenient
if you need to access all the controls in an array or search the array for a specific control.
var earray = document.forms[0].elements;
for (var count = 0; count < earray.length; count++) {
    alert(earray[count].name);
}

    The preceding code demonstrates how the elements array can be queried. It successfully
finds the first control on the form.
204      How to Do Everything with JavaScript


      Access Form Values Using getElementById()
      Both the techniques we have just examined (forms array and elements array) are the old way
      of using the DOM. The main problem with those methods is that they are specific to forms.
      If you wanted to access the contents of the <h1> element (the document heading) and change it,
      you could not.
          The getElementById() DOM method is the new preferred way to access any object on a web
      page—whether it is a form control, a <div> tag, or even a Java applet embedded in the page.
          To retrieve the value of the fullname text box, we would use the getElementById() function
      as follows:
      var fullname = document.getElementById("fullname").value;

          This code looks for an element with an ID of fullname anywhere inside the current document.
      JavaScript does not know (or care) at this point what type of object it is—it could be any HTML
      element. As its name implies, this function attempts to look up an element by its ID. Most
      HTML elements have an ID attribute (id=""), and in order to use this function on an element,
      you should set the ID attribute accordingly.
      <input type="text" id="fullname" name="fullname">

              Most browsers will also search for elements by their name attributes if they cannot find
              an ID that matches.

      Access Form Values Using getElementsByName()
      Just as the getElementById() function will search for elements by ID attribute, the
      getElementsByName() function will search for elements by their name. The one difference
      between the two functions is that getElementsByName returns an array of elements. Thus,
      it can return more than one element.
      var hearObj = document.getElementsByName("hear");

          This code will return an array of all the elements named hear on the web page. Earlier we
      created some HTML that included a set of radio buttons named hear—there were four elements
      named hear on the page (see “Access Form Values Using the forms Array”). Using this code on
      that form would return an array of four elements. The JavaScript code we used would then
      correctly determine which of the four radio buttons were selected.
      for (var i = 0; i < hearObj.length; i++) {
          if (hearObj[i].checked) {
               hear = hearObj[i].value;
          }
      }
CHAPTER 8: Manipulate Web Forms          205

Access Form Values Using getElementsByTagName()
The final method provided by the new JavaScript DOM is getElementsByTagName(). This
method is very helpful in retrieving elements that are not named, such as the submit button on
our previous form example. This function allows us to look up objects on a web page by their
HTML element name.
var mybutton = document.getElementsByTagName("input");
mybutton[6].value = "Please wait...";
mybutton[6].disabled = true;

    By adding this code to the beginning of our checkform() function, we can disable
the submit button to stop the user from submitting the form more than once. The
getElementsByTagName(“input”) function returns an array of all the <input> elements
on a web page. We know the submit button is the seventh element on the web page created
using the HTML <input> tag—the other six are two text boxes and four radio buttons. Since
the array starts at index zero, the submit button is located in the sixth index in the array.
                                                                                                   8




                                  Button has been disabled and
                                  caption set to “Please wait.”
206      How to Do Everything with JavaScript


          So as you can see, the DOM provides a number of different methods for accessing the
      contents of a form. In the next chapter, we will examine the ins and outs of browser events.
      We will start off by looking at the different types of events in HTML and how to write event
      handlers to deal with them. And we will look at some of the special cross-browser compatibility
      issues that arise when dealing with events.
Handle Browser
Chapter 9   Events
208      How to Do Everything with JavaScript


      How to...
          ■   Write JavaScript event handlers
          ■   Handle events using the event property
          ■   Trigger events in JavaScript
          ■   Overcome browser incompatibility

      The dictionary defines an event as “something that takes place” and that is exactly what it means
      in web programming as well. An event handler is JavaScript code that is designed to run each
      time a particular event occurs. Of course, this means that your JavaScript code may execute
      dozens of times, or not at all, depending on the circumstances.
           There are 18 events officially defined in the HTML 4.01 specification. In addition, browsers
      that support the official DOM Level 2 Events specification need to provide several more events for
      programmers to work with. However, Microsoft and Netscape have gone beyond the events listed
      in the official specifications and provide many more: IE supports more than 75 events, and Netscape
      supports at least 50.
               The DOM Level 2 Events specification can be found on the official W3C web site at
               http://www.w3.org/TR/DOM-Level-2-Events.

          The key to knowing how to write appropriate event handlers is understanding what the
      events are and when they occur. For instance, the following events are just three of the official
      18 HTML 4.01 events:

          ■ load event Occurs when the HTML document has finished loading in the browser
              window
          ■ click event Occurs when the left mouse button has been clicked
          ■ keypress event Occurs when a keyboard key has been pressed
          JavaScript can be used to intercept these events when they occur and take certain actions
      (sometimes it is allowed to cancel the event). Intercepting an event is called capturing the event,
      and it is done by writing event handler code. If no event handling code is written, the browser
      will continue to process the event as normal using default behavior.
          In this chapter, we will examine the various events provided by most HTML elements and
      how event handlers should be written for each. We will also see how a JavaScript program can
      cause these events to occur manually, and we’ll look into the differences in event handling
      between the various browsers.

 Write JavaScript Event Handlers
      You saw some examples of event handlers in the previous chapter, in the “Catch Web Form
      Submissions with onsubmit” section. Writing an onsubmit event handler enabled our JavaScript
      program to check that all the fields on a form were filled out before the form submission was
      allowed to continue.
CHAPTER 9: Handle Browser Events             209

    Events fall into four major categories:

    ■       User interface events
    ■       Mouse events
    ■       Key events
    ■       HTML events

    User interface events happen as controls or other objects on a web page gain and lose focus.
These events are often caused by other user actions (such as a tab key press or a mouse click),
but they can happen programmatically as well.
    Mouse events occur when the user moves the mouse or presses one of the mouse buttons.
These events allow a web page to respond to mouse movements by, for example, highlighting
an image when the mouse moves over it.
    Key events occur when the user presses and/or releases one of the keyboard keys. Only
certain HTML elements can capture keyboard events, as we will see later in this chapter.
    Finally, there are several events specific to certain HTML elements. They often relate to the
browser window itself or to form controls and other objects embedded in a web page. The onsubmit
event handler discussed in the last chapter falls into this category.
                                                                                                        9
Handle User Interface Events
User interface events deal exclusively with the transfer of focus from one object inside the web
page to another. There are three user interface events defined in most web browsers.

 Event Name                         Event Handler Name             Defined In
 focus                              onfocus                        HTML 4.01
 blur                               onblur                         HTML 4.01
 activate                           onactivate                     DOM Level 2


    For example, let’s assume we have a web page with two text boxes.

<form action="#">
    <input type="text" name="box1"><br>
    <input type="text" name="box2">
</form>

    Say the active cursor is presently inside the text box named box1. When we hit the keyboard
TAB key,  we expect focus to transfer to the second text box, box2. Ignoring for a moment the
keyboard events, the three user interface events fire (occur) in a predictable order.
    First, the activate event fires on box2. Next, the blur event fires on box1. Finally, the focus
event fires on box2. We can modify the web page slightly to see that the events always fire in
a predictable order.
210      How to Do Everything with JavaScript

      <script type="text/javascript" language="javascript">
       function upd(instr) {
          document.forms[0].statusbox.value += instr + "; ";
      }
      </script>
      <form action="#">
          <input type="text" name="box1"
              onblur="upd('blur box1')"><br>
          <input type="text" name="box2"
              onfocus="upd('focus box2')"
              onactivate="upd('activate box2')"><br><br>
          Event firing order:
          <input type="text" name="statusbox" size="40">
      </form>

           In the preceding code, we have added a third text box called statusbox to the screen, to display
      the results of our event firing test. We have provided JavaScript to the three event handlers (onblur,
      onfocus, and onactivate) that will append the event and control names to the end of the statusbox
      text box.
           The results of the test are shown in Figure 9-1. As you can see, the events listed in the status
      box match the order we expected.




       FIGURE 9-1      User interface events are fired in a predictable order.
CHAPTER 9: Handle Browser Events              211

Handle Mouse Events
The seven mouse events listed in the following table all relate to actions taken by the user using
the mouse. JavaScript programs have the ability to track mouse movement and button clicks as
they relate to the web page and controls inside.

 Event Name                Event Handler Name               Defined In
 mousedown                 onmousedown                      HTML 4.01
 mouseup                   onmouseup                        HTML 4.01
 mouseover                 onmouseover                      HTML 4.01
 mousemove                 onmousemove                      HTML 4.01
 mouseout                  onmouseout                       HTML 4.01
 click                     onclick                          HTML 4.01
 dblclick                  ondblclick                       HTML 4.01


    Tracking these mouse events is often done to enhance the user’s experience by highlighting
menu items as the mouse pointer rolls over them or by updating screen text to provide more
information about the element beneath the pointer.                                                     9
    For example, the following HTML code inserts an image into an web page using the <img>
element. By capturing the mouseover and mouseout events, we can cause the image to change
when the mouse pointer is over the image and change back to the original image once it leaves.
<script type="text/javascript" language="javascript">
function changeimage(num) {
    var img = document.getElementById("SampleImage");
    if (num == 1) {
        img.src = "NewImg.gif";
    } else {
        img.src = "OriginalImg.gif";
    }
}
</script>

<img src="OriginalImg.gif"
    id="SampleImage"
    alt="Sample image"
    onmouseover="changeimage(1)"
    onmouseout="changeimage(2)" >

     The mouseover event fires the moment the mouse pointer enters the boundaries of the image.
The onmouseover event handler calls the changeimage() function with a parameter of 1. The
changeimage() function starts off by assigning a reference to the image to a variable based on
its id, SampleImage. The src attribute of the image allows us to dynamically modify the image
displayed in the browser.
212      How to Do Everything with JavaScript


          The mouseout event fires once the mouse pointer leaves the boundaries of the image. The
      changeimage() function handles this event as well, causing the image to go back to its original source.
          We can see the effects of this image rollover in Figure 9-2.

      Handle Key Events
      JavaScript programmers rarely use key event handlers to catch key events. While there are a few
      situations where you might want to use them, this type of event handling is more commonly found
      in Windows applications (such as Visual Basic programs) than in web-based programming.
          Like the user interface events, key events fire in a predictable sequence. There are three main
      key events in HTML.

       Event Name               Event Handler Name               Defined In
       keypress                 onkeypress                       HTML 4.01
       keydown                  onkeydown                        HTML 4.01
       keyup                    onkeyup                          HTML 4.01


          By slightly modifying the code found in the “Handle User Interface Events” section, we can
      see the predictable order the events fire in.
      <script type="text/javascript" language="javascript">
       function upd(instr) {
          document.forms[0].statusbox.value += instr + "; ";
      }
      </script>
      <form action="#">
          <input type="text" name="box1"
              onkeypress="upd('keypress')"
              onkeydown="upd('keydown')"
              onkeyup="upd('keyup')"><br><br>
          Event firing order:
          <input type="text" name="statusbox" size="40">
      </form>




                             Before                                            After
       FIGURE 9-2      The mouseover and mouseout events power image rollover effects.
CHAPTER 9: Handle Browser Events                  213




                                                                                                              9




 FIGURE 9-3       The order of the key events is keydown, keypress, and keyup.


    As you can see from the screenshot in Figure 9-3, the order of events is

    1. keydown
    2. keypress
    3. keyup

     The keydown event occurs when almost any keyboard key has been pressed down, including
nonalphanumeric keys such as HOME, ESCAPE, INSERT, and DELETE. The keypress event, on the other
hand, only fires when certain alphanumeric keys are pressed, including punctuation, SPACEBAR, and
ENTER. The keyup event is the complement to keydown, since it fires when almost any key has been
released.
     Both the keydown and keypress events can be canceled. To cancel an event, you just need to make
its event handler return false. Canceling a keydown or keypress event will cause the browser to ignore
those keys. For example, if you wanted to restrict the types of characters entered into a form field, you
could capture its keydown event and return false anytime a key is not in an acceptable range.
214      How to Do Everything with JavaScript

      <script type="text/javascript" language="javascript">
        function checkkey() {
           var keycode = window.event.keyCode;
           if (keycode < 48 || keycode > 57) {
               return false;
           } else {
               return true;
           }
      }
      </script>
      <form action="#">
           <input type="text" name="box1"
               onkeydown="return checkkey()"><br>
      </form>

          The preceding code shows how the keydown event can be captured. Since we want to be able
      to cancel the event, we include a return statement inside the event handler along with a call to the
      checkkey() function.
               The first 127 characters of the Unicode character set match the corresponding ASCII
               codes character for character. More information on the Unicode character set can be
               found at http://www.unicode.org.
          The checkkey() function gets the Unicode character code associated with the key by checking
      the keyCode attribute of the window.event DOM object. We compare the value of the keyCode
      against the range of values for numeric keys, which happen to be 48–57. If the keyCode we
      intercepted falls outside that acceptable range, we return false from the function to indicate that
      the key is to be ignored. Of course, we return true if the key falls inside the acceptable range.
               The keyCode property of the window.event object is only available in Netscape version 6
               and later and Internet Explorer.
         This results in a text box that only accepts numeric input and ignores all other characters.
      The following table lists several common characters along with their keyCode values.

       keyCode Values                        Correspond To
       48 through 57                         0 through 9
       65 through 90                         A through Z (capital letters)
       97 through 122                        a through z (lowercase letters)
       46                                    . (period)
       44                                    , (comma)
       40 and 41                             ( and ) (parentheses)
       36                                    $ (dollar sign)
       35                                    % (percent sign)
       34                                    " (quotation mark)
CHAPTER 9: Handle Browser Events              215

Handle HTML Events
In this context, HTML events means any events that do not belong in the user interface, mouse, or
key event categories. Some HTML events are triggered directly by a user action, while others are
fired only as an indirect result of a user action.
     The following table lists the HTML events, the event handler name, and the official specification
that defined them.

 Event Name         Event Handler Name        Fires When (Event)                     Defined In
 load               onload                    Browser finishes loading document      HTML 4.01
 unload             onunload                  Browser about to unload document       HTML 4.01
 submit             onsubmit                  Form about to be submitted             HTML 4.01
 reset              onreset                   Form about to be reset                 HTML 4.01
 select             onselect                  Text box contents selected             HTML 4.01
 change             onchange                  Form control contents changed          HTML 4.01
 abort              onabort                   User aborts download of image          DOM Level 2
 error              onerror                   Error occurs on object loading         DOM Level 2
 resize             onresize                  Size of object about to change         DOM Level 2           9
 scroll             onscroll                  User uses the scroll bar               DOM Level 2


    Let’s take a quick look at what these events do.

    ■ load event The onload event handler is called when the HTML document finishes
          loading into the browser window. This event is commonly relied on to do any initialization
          required in the document. For instance, if form fields need to be preloaded with text, and
          that was not covered by the HTML code itself, it is best to wait until the document is fully
          loaded before initializing those fields.
    ■ unload event The unload event fires when a browser is leaving the current document.
          This happens when the browser window is being closed or the user has moved on to
          another document. The main purpose of this event is to perform cleanup tasks before
          the document closes.
          The unload event is commonly used in some of the seedier web locations to provide final
          pop-up advertising before a user leaves a web site. This is generally considered bad
          etiquette. The unload event should be avoided unless absolutely necessary.

    ■ submit event The submit event occurs just before a form is submitted to a web server.
          It is common to capture this event to perform edit checking before allowing a form
          submission to continue. Since this event can be canceled, JavaScript can stop the
          form from being processed if everything is not in order.
    ■ reset event The reset event occurs when the reset button on a form is clicked. The reset
          button clears a form by resetting all the values back to their defaults.
216      How to Do Everything with JavaScript


         ■ select event The select event occurs when the user selects text inside a text box or text
              area. Text can be selected by holding the left mouse button down while dragging across
              the text or by holding the SHIFT key down while using the arrow keys to move the cursor
              across the text.
         ■ change event The change event occurs when a control loses focus (the user tabs out of
              it) and its value has been altered. This way, in text boxes the change event does not fire
              for each and every keystroke when a user is entering a value but only when the user
              leaves the field. This same event fires on radio buttons, check boxes, and select lists in
              the same manner.
         ■ abort event The abort event occurs when the browser stops trying to load an image
              on the web page. This can occur when the user hits the browser’s Stop button or clicks
              a link to go to another page. In my experience, this event is rarely used.
         ■ error event The error event occurs when an error happens while the web page is being
              loaded. This could be an error specific to a particular object (such as a Java applet’s failing
              to load) or a run-time error caused by poorly written JavaScript code. This is another event
              that is rarely captured in most web pages.
         ■ resize event The resize event fires when an object is being resized—for instance, if a
              browser window has been resized by the user, or a frame. There may be times when you
              would like to be able to resize the individual controls inside the window based on the
              available space, although capturing this event is still rare.
         ■ scroll event For web objects that scroll, such as the browser window or a text area form
              control, the scroll event is fired anytime the object’s scroll bar is changed. This can be done
              using the mouse to move the scroll bar manually, by using arrow keys, or by other means.
          The following code demonstrates how the load event can be captured using the onload event
      handler. Our web page contains a form, and the onload event handler code populates a list box on
      that form with some predefined values.
      <html>
          <head>
              <title>JavaScript Sample Web Page</title>
              <script language="JavaScript" type="text/javascript">
              <!-- // Begin

               function initialize() {
                   var lst = document.getElementById("samplelist");
                   var opn = new Array(20);
                   var temp;
                   var counter;

                    for (counter = 1; counter <= 10; counter++) {
                       opn[counter] = document.createElement("option");
                       lst.options.add(opn[counter]);
                       temp = counter * 10;
                       opn[counter].innerText = temp.toString();
CHAPTER 9: Handle Browser Events            217

              }
         }

        // End -->
        </script>
    </head>
    <body onload="initialize()">
        <h1>Initialize a Form with onload</h1>

         <form action="#">
             <select id="samplelist"></select>
         </form>

    </body>
</html>

     In the preceding HTML code, the browser calls the JavaScript initialize() function as soon
as it finishes loading into the browser window. This is done by programming the onload event
handler in the <body> tag.
     Inside the initialize() function, the program adds 10 items to the empty <select> list box
defined in the body of the web page. We can see the results of this function in Figure 9-4.         9




 FIGURE 9-4       Ten items have been added to the drop-down list box.
218      How to Do Everything with JavaScript


 Handle Events Using the Event Property
      There are two ways to set the JavaScript event handler for an HTML tag:

          ■ Set the event handler property inside HTML
          ■ Set the event handler property inside JavaScript
          We have already seen how to set the event property in HTML:
      <img src="OriginalImg.gif"
          id="SampleImage"
          alt="Sample image"
          onmouseover="changeimage(1)"
          onmouseout="changeimage(2)" >

         In this code, we have set the JavaScript functions that will handle the mouseover and
      mouseout events using the corresponding event handlers.
         We could rewrite the code using JavaScript to set the event handlers:
      <img src="OriginalImg.gif"
          id="SampleImage"
          alt="Sample image">


      <script type="text/javascript" language="javascript">
          var img = document.getElementById("SampleImage");
          img.onmouseover = changeimageover;
          img.onmouseout = changeimageout;
          function changeimageover() {
              img.src = "NewImg.gif";
          }
          function changeimageout() {
              img.src = "OriginalImg.gif";
          }
      </script>

          The HTML <img> tag has two attributes called onmouseover and onmouseout that
      can be set using HTML and JavaScript. Setting event attributes using JavaScript adds
      some flexibility, in that the JavaScript function used to handle the event can be changed
      dynamically, after the page has been displayed. But as you can see from the sample
      JavaScript code, you cannot pass parameters using this technique, so it is also less flexible
      in some respects.
CHAPTER 9: Handle Browser Events               219


                          How Event Bubbling Works

     Let’s assume you have a web form that contains a push button. You have created JavaScript
     onclick event handlers for both the <form> tag and the <input type="button"> tag. When you
     click the push button control using the mouse, which onclick event handler do you think will
     be called—the one for the button or the one for the form? In fact, the browser will execute
     both event handlers.
         The onclick event handler for the button will be called first, since it is the innermost
     element. Next, the onclick event handler for the form will be called. If there are any other
     onclick event handlers eligible to handle this event (for instance, on the <body> tag), they
     will be called in turn as well. This process, where an event is first handled by the innermost
     element, followed by the next innermost element, and so on, is called event bubbling.



Trigger Events in JavaScript
   There will be times when you would like to have your JavaScript program cause an event to              9
   occur. This is called triggering the event, and many objects inside the web page provide methods
   you can call to trigger the event.
      There are two ways to cause an event to be triggered in JavaScript:

       ■ Call the method associated with the event
       ■ Call the fireEvent method to fire the event manually

   Call the Method Associated with an Event
   The first technique is to call the method associated with an event. Most events have a method that
   will simulate the activity that causes the event to fire. For instance, the HTML <form> object has
   a method called submit() that will attempt to submit the form, causing the submit event to fire.
       We can demonstrate this with the following HTML code. The code shows how to use
   a hyperlink to simulate a submit button.
   <script type="text/javascript" language="javascript">
   function clickme() {
       document.forms[0].submit();
   }
   </script>
   <form action="http://www.example.com/cgi-bin/entry.pl"
220      How to Do Everything with JavaScript

          method="get">
          Please enter your full name: <br>
          <input type="text" name="fullname"><br>
          <a href="javascript:clickme()">Click here to
              <b>submit</b> the form</a>
      </form>

          When the user clicks the hyperlink inside the form, JavaScript calls the clickme() function.
      The clickme() function calls the submit() method on the form object, which causes the form to
      submit itself. The submit() method acts exactly as if the user clicked a submit button on the form,
      causing the submit event to fire.
               In IE, calling the submit() method will cause the form to submit, but will not call any
               submit event handlers attached to the form. If your <form> has an onsubmit attribute,
               you will have to call those JavaScript functions manually before calling the submit() method.

           Other events also have associated methods that cause the event to occur. For instance, the
      focus() method will cause a control to gain focus, while the blur() method will cause a control
      to lose focus. Similarly, there is a click() method that allows HTML objects to simulate being
      clicked with the mouse.

      Use the fireEvent Method
      The second technique is to call the fireEvent() method to trigger the event manually. In IE,
      fireEvent() is a method of most objects in the DOM, and it can be used to trigger events. For
      example, you can trigger the onclick event of a push button control in the following manner:
           var btn1 = document.forms[0].helpButton;
           btn1.fireEvent("onclick");

           Unfortunately, this method is not very reliable. Although this technique is supposed to be able
      to trigger events on any object, I have found that it does not work for certain events or objects, such
      as the onsubmit event on a form object, or the onclick event on a submit button object.
               Given that it is not part of the official DOM standard and does not work in any browser
               other than IE, developers should be very careful when using this technique.


 Overcome Browser Incompatibility
      Browser events are a weak spot when it comes to cross-browser compatibility. Sure, HTML defined
      a small number of standard events, and the various DOM specifications (Levels 1 and 2) have taken
      events a step further. But browser manufacturers have added many more programmable events for
      JavaScript developers to use, as evidenced by the more than 50 events supported by both Netscape
      and IE.
          Some of the additional events are slight modifications of existing events. For instance, IE
      provides onbeforeactivate and onbeforeunload event handlers to allow programmers to capture
CHAPTER 9: Handle Browser Events                 221

the onactivate and onunload events before they fire. These additional events are cancelable,
which means you can stop the activate or unload events from occurring, while the existing
onactivate and onunload events fire after the event occurs, and therefore cannot be canceled.
    Other event handlers allow programmers access to events that are not specified by the standards:

    ■   onbeforeprint and onafterprint allow access to browser print events.
    ■   ondrag, ondragstart, and ondragend allow access to drag-and-drop events.
    ■   onmousewheel allows access to the mouse wheel movements.
    ■   oncut, oncopy, and onpaste allow access to copy-and-paste events.

    The problem is, of course, that these events are generally supported by only one browser and not
another. They are also often supported only by newer versions and not by older browsers. Although
having access to some of these interesting events might be tempting from a programmer’s point of
view, you will have to take some of the precautions listed in Chapter 7 and use browser sniffing code
before relying on these methods.
    Of course, one good thing about these proprietary events is that they will generally not cause
the browser to crash if they are coded properly. For instance, the following code tries to capture the
onpaste event on a text box control.
<form action="#">                                                                                           9
    <input type="text" name="myctl" onpaste="pasteevent()">
</form>

     Of course, since the onpaste event handler is being set inside the HTML element, the browser will
simply ignore that code if it does not support the paste event on that control. The only consequence is
that the paste event will not be captured in incompatible browsers.
     However, if you are absolutely relying on this event handler to perform some critical code,
such as submitting the form, you will have to use browser sniffing code to provide alternate code
for browsers that do not support it.
     In the next chapter, we will discuss browser frames. JavaScript programs face special
challenges when dealing with a multiple-frame environment, and we will examine some of
the issues and how best to work around them.
This page intentionally left blank
Communicate
Chapter 10   Between Browser
             Frames
224      How to Do Everything with JavaScript


      How to...
          ■   Create a frameset
          ■   Define and name frames in a frameset
          ■   Call JavaScript functions from other frames
          ■   Handle synchronization between frames

      In web programming, a frameset is used to divide a single web page into two or more smaller
      pieces. Each of these pieces, or frames, is a separate HTML web page. Web developers can
      define several important properties for these frames, including the overall dimensions, location,
      and visibility of the borders.
          In this chapter, we will examine the use of framesets on the Internet today. In particular, we
      will see some the challenges faced by JavaScript programmers when using frames and look at
      some suggestions for overcoming them.


 Learn the Basics of HTML Frames
      Frames are extremely useful for displaying the static sections of a web site, such as menus,
      banners, and site-navigation tools. Since all the frames in a frameset are independent of each
      other, they provide several important benefits to web site developers and visitors. When used
      properly, frames can

          ■ Decrease the length of time required to navigate a web site
          ■ Make a web site easier and more intuitive for visitors to use
          ■ Make a web site easier for developers to maintain
          Figure 10-1 shows an example of a web page that uses frames. The figure contains three
      frames: a top frame with links to other areas of the site, a left frame that contains a menu,
      and a center frame (known as the main frame) that contains the key contents of the web site.
          As convenient as frames are for both web programmers and visitors, there are quite a few
      people who do not like them. A number of problems can be introduced when frames aren’t used
      properly:

          ■ Browser bookmarks can’t be properly set.
          ■ Web sites look awful at very small or very large monitor resolutions.
          ■ Search engines can’t accurately index the contents of a frameset.
          Adding to these problems is the increasing use of and browser support for Cascading
      Style Sheets (CSS). Style sheets can provide many of the same benefits as frames, including
      user-friendly navigation and even static banners and menus. Many popular web sites that once
      contained framesets now use DHTML menus and other more modern dynamic elements.
CHAPTER 10: Communicate Between Browser Frames               225




                                                                                                 10

 FIGURE 10-1     Example of a web site (ZVON.org) that contains frames



Create a Frameset in HTML
In HTML, frames are created using a combination of two tags: <frameset> and <frame>.
The <frameset> tag is used to define the dimensions and positioning of the frames inside the
frameset. The <frame> tag is used to define the properties of the individual frames, such as
the source HTML document, and the visibility of the frames borders.
    The <frameset> element has the following attributes:
   ■    id String that must be unique across the entire web page
   ■    class List of associated CSS classes
   ■    style Inline CSS style commands
   ■    title Advisory title
   ■    lang ISO language code
   ■    dir Direction of text (right to left or left to right)
   ■    rows A comma-separated list of row heights
   ■    cols A comma-separated list of column widths
226      How to Do Everything with JavaScript


          The <frameset> tag also supports the onload and onunload event handlers.
          The web page shown in Figure 10-1 consists of four separate HTML files. One HTML file
      contains the frameset layout—typically only a <head> section and the <frameset> and <frame>
      tags. The other three HTML files contain the individual contents of each of the three frames—
      each HTML file in this example relates to exactly one frame.
          Of course, this is not always true. More than one frame can relate to the same HTML file, and
      some frames can be dynamically generated using JavaScript, and so will have no file associated
      with them. The only way to tell is by looking at the code.
          The following code is a complete example of a frameset document.
      <html>
          <head>
              <title>Framesets</title>
          </head>
          <frameset rows="100, *">
              <frame src="banner.html" name="banner">
              <frameset cols="150, *">
                  <frame src="menu.html" name="menu">
                  <frame src="mainbody.html" name="bodyframe">
              </frameset>
          </frameset>
      </html>

           The preceding HTML code defines a frameset with three frames. It uses a technique discussed
      later in this chapter, in the section entitled “Create Nested Framesets.” We can tell the number of
      frames in a document by counting the number of <frame> tags.
           Notice that the frameset document contains the usual <html>, <head>, and <title> tags, but it
      does not contain a <body> tag. This is because a frameset document cannot contain a <body> of
      its own—that is not allowed. We can, however, use all the valid contents of the <head> section,
      including JavaScript code, meta data, and style sheet definitions using the appropriate HTML tags.

      Handle Browsers That Do Not Support Frames
      Providing a site using frames may be convenient to many visitors to your site. The vast majority
      of web surfers today (more than 99 percent, by the latest estimates) have browsers capable of
      displaying frames. But there is still a small minority of web browsers that do not support them.
      Many early browsers, such as IE 2 for Windows or Netscape 2 for OS/2, do not. And other
      web-enabled devices, such as PDAs and mobile phones, often have difficulty rendering frames
      correctly.
          HTML provides the <noframes> tag to allow web developers to display content for users
      whose browsers do not support the <frameset> tag. Browsers that do support the tag will ignore
      the contents of any <noframes> sections.
CHAPTER 10: Communicate Between Browser Frames                      227

    For instance, we can revise the HTML code we saw earlier to include a <noframes> tag;

<html>
    <head>
        <title>Framesets</title>
    </head>
    <frameset rows="100, *">
        <frame src="banner.html" name="banner">
        <frameset cols="150, *">
            <frame src="menu.html" name="menu">
            <frame src="mainbody.html" name="bodyframe">
        </frameset>
        <noframes>
        It appears you are using a browser that does not support
        frames. If you would like to view this site, you will
        need to upgrade your browser. I suggest either Netscape
        or IE.
        </noframes>
    </frameset>
</html>

    According to the HTML 4.01 specification, the <noframes> tag must be contained inside                10
a <frameset> tag.

Set Frame Size Values with the rows and cols Attributes
As we saw earlier in the chapter, the size and positioning of frames inside the frameset are handled
with the HTML <frameset> tag. The two main attributes of the <frameset> tag are rows and cols.
The rows attribute is used to define the row heights of the horizontal frames of a frameset, and the
cols attribute is used to define the column widths of the vertical frames. Each attribute accepts
a list of one or more values, separated by commas.
     There are three ways to specify a size value in the rows and cols attributes:

    ■ Absolute size, in pixels
    ■ Relative size, as a percentage
    ■ A combination of absolute and relative sizes, using the asterisk symbol
    Both rows and cols are optional attributes. The default value for each is "100%"; this defines
one frame that takes up all the available space in a browser window.
    Examples of the three types of size value and what they represent are shown in Table 10-1.
228        How to Do Everything with JavaScript


       Value                     Frame Size
       250                       250 screen or print pixels
       25%                       25 percent (1/4) of the total available screen or print pixels
       *                         An equal share of the available space, after the sizes of the other frames have
                                 been taken into account
       3*                        An unequal share of the available space, after the sizes of the other frames
                                 have been taken into account
       TABLE 10-1       Examples of Size Values and How They Affect the Frameset



                The special asterisk value is explained in more detail later in this chapter, in the section
                entitled “Set Frame Size Values Using Both Absolute and Relative Values.”


          Both the rows and cols attributes accept one or more values, separated by commas. Each
      value you provide creates one frame inside the frameset.

      Set Frame Size Values Using Absolute Pixel Values
      HTML allows you to define the exact size of a frame, called its absolute size. The absolute size
      of a frame is set by specifying a positive integer value for the rows and/or cols attributes.
          For example, a frameset with two horizontal frames, one 200 pixels high and the other
      280 pixels high, would be created with the following HTML code:
      <frameset rows="200, 280">
          <!-- <frame> tags go here -->
      </frameset>

                Even absolute sizes are not always absolute. If the actual size of the browser window
                does not match the sum of the sizes of the frames, the browser will automatically resize
                the frames to fit into the available space.

           Of course, you’re not restricted to only two frames. You can set any number of frames in
      a frameset. The following code sample defines four horizontal frames:
      <frameset rows="200, 200, 400, 400">
          <!-- <frame> tags go here -->
      </frameset>

                Although there is theoretically no maximum number of frames you can define in one
                frameset, for aesthetic reasons you might want to limit the number to three or four.
CHAPTER 10: Communicate Between Browser Frames                        229

Set Frame Size Values Using Relative Values
There is another way to define the size of frames beside specifying their exact pixel measurements.
Developers can specify the size as a percentage of total available space. This is called a relative
size, because the size of the frame is based purely on the size of the browser window, which can
vary between one computer and another.
<frameset rows="50%, 50%">
    <!-- <frame> tags go here -->
</frameset>

    The preceding code will create two frames, each taking up 50 percent of the available vertical
space in the browser window. In a window that is 480 pixels high, this would create two horizontal
frames, each 240 pixels high. If the user’s browser window were taller than 480 pixels, the actual
height of each frame in pixels would be adjusted to the proper relative size.

Set Frame Size Values Using Both Absolute and Relative Values
The third alternative is to combine the two approaches—to create some frames that are absolute
in size and others with sizes relative to the available space. To create this useful effect, specify the
absolute number of pixels for the fixed frames and use an asterisk (*) in place of the relative sizes.
     For example, if you wanted to make the first frame 200 pixels high and to let the second
frame automatically resize to fit the rest of the window, you could use the asterisk (*) when
setting the height:                                                                                          10
<frameset rows="200, *">
    <!-- <frame> tags go here -->
</frameset>

This results in a frameset that contains two frames, one 200 pixels high and the other which takes
up all of the remaining vertical space.
    If you were to use the asterisk more than once, the web browser would automatically resize
those frames equally to fill the available space after the fixed-height frames were taken into
consideration.
<frameset rows="200, 200, *, *">
    <!-- <frame> tags go here -->
</frameset>

     The <frameset> tag in the preceding code will create a frameset that contains four frames. The
first two frames will each be 200 pixels high, for a total of 400 pixels. If the viewable area of
the browser window is 480 pixels in height, the last two will split the remaining 80 pixels evenly,
so they will each be 40 pixels high. And if the browser window’s height expands to 600 pixels, those
two frames will have heights of 100 pixels each, since they will evenly split the 200 pixels left
after the fixed-height frames are accounted for.
230      How to Do Everything with JavaScript


          There is also a way to instruct the browser to distribute available space unevenly when using
      asterisks, by providing an asterisk multiplier. An asterisk multiplier is a number that can optionally
      precede an asterisk, causing it to get more than an equal distribution of space.
          For instance, the following frameset defines four frames, two of which are automatically
      sized by the browser. But the remaining space will be allocated unequally.
      <frameset rows="200, 200, *, 3*">
          <!-- <frame> tags go here -->
      </frameset>

          Prefixing the asterisk that defines the final frame with the number 3 will cause that frame to
      have a height that is three times that of the third frame. This means that the fourth frame will get
      three-quarters of the available space, while the third frame will only get one-quarter of the available
      space. So, if the browser window had a height of 800 pixels, the browser would split the remaining
      400 pixels by assigning 100 pixels to the third frame and 300 pixels to the fourth frame.

      Define Horizontal Frames with Rows
      So far throughout this chapter, you have seen code like the following, which will create three
      horizontal frames.
      <frameset rows="80, 45, *">
          <!-- <frame> tags go here -->
          <frame src="frame1.html">
          <frame src="frame2.html">
          <frame src="frame3.html">
      </frameset>

          These are called horizontal frames because each frame spans the entire width of the browser
      window. Since we have used the rows attribute, horizontal lines separate the three frames in the
      preceding example. In Figure 10-2 you can see how these horizontal frames would look in a browser.

      Define Vertical Frames with Columns
      Defining a set of vertical frames is not much different than defining horizontal ones. The cols
      attribute of the <frameset> tag allows you to create frames that have a vertical border instead
      of a horizontal one.
      <frameset cols="165, *">
          <!-- <frame> tags go here -->
          <frame src="frame1.html">
          <frame src="frame2.html">
      </frameset>

         The preceding HTML code will create a frameset that contains two frames. The first will
      have a width of 165 pixels, while the second will take up the remaining horizontal space in the
      browser window. Figure 10-3 shows how vertical frames look.
CHAPTER 10: Communicate Between Browser Frames     231




FIGURE 10-2   An example of horizontal frames created using the rows attribute

                                                                                   10




FIGURE 10-3   Creating vertical frames using the cols attribute
232      How to Do Everything with JavaScript


      Define Frames with Rows and Columns
      Framesets need not be only horizontal or only vertical. Web developers can create framesets that
      contain both rows and columns, like a grid. This is done by specifying values for both the rows
      and cols attributes.
          For instance, to create a frameset that has three rows and two columns, you would use the
      following HTML code:
      <frameset rows="50, 100, *" cols="50%, 50%">
          <!-- <frame> tags go here -->
          <frame src="frame1.html">
          <frame src="frame2.html">
          <frame src="frame3.html">
          <frame src="frame4.html">
          <frame src="frame5.html">
          <frame src="frame6.html">
      </frameset>

         The preceding code creates a frameset that contains six frames, arranged into three rows and
      two columns. Notice that the number of rows and columns does not have to be equal. Figure 10-4
      shows how this complex frameset will look in a browser.




       FIGURE 10-4     A frameset with both rows and columns
CHAPTER 10: Communicate Between Browser Frames                        233

Create Nested Framesets
Creating complex framesets using both the rows and cols attributes has its limitations. Specifically,
the rows and columns are created in a grid pattern—all the columns in one row will be the same
width, and all the rows will be the same height, as shown in Figure 10-4. It will always be a perfectly
aligned grid, although the size of the cells in the grid can differ.
     What could you do if you wanted to create unequal rows and columns? How could you
create a row that has only one column, but define several columns for the next row? The answer
is nested framesets.
     A nested frameset is achieved by placing one or more framesets inside another, thus
subdividing a single frame into smaller pieces. All nested framesets must begin with a single,
outer frameset.
<frameset rows="80, *">
    <!-- <frame> tags go here -->
    <frame src="frame1.html">
    <frame src="frame2.html">
</frameset>

For instance, the preceding HTML code creates a simple frameset that contains two
horizontal frames.
    Now let’s say we want to further subdivide the second frame into two columns. This
can be done with a second frameset:                                                                         10
<frameset rows="80, *">
    <!-- <frame> tags go here -->
    <frame src="frame1.html">
    <frameset cols="150, *">
        <frame src="frame2.html">
        <frame src="frame3.html">
    </frameset>
</frameset>

    I have replaced the second frame in the original code with a second frameset. This nested
frameset divides the second frame into two columns. You can see the effect of this type of
frameset in Figure 10-5.

Define and Name Frames in a Frameset
Now that you understand how simple and complex framesets are created using the <frameset>
tag, we should take a brief look at how the frames themselves are defined. Individual frames are
defined using the <frame> tag. The <frame> tag has the following attributes:

    ■ id Documentwide unique ID
    ■ class List of associated CSS classes
    ■ style Inline CSS style commands
234      How to Do Everything with JavaScript


          ■   title Advisory title
          ■   longdesc Link to a longer description of the frame
          ■   name Internal name of the frame
          ■   src URI to the HTML document
          ■   frameborder Visibility of the frame borders
          ■   marginwidth Amount of space, in pixels, between the vertical border (or window
              frame) and the HTML contents
          ■ marginheight Amount of space, in pixels, between the horizontal border (or window
              frame) and the HTML contents
          ■ noresize Controls whether the user can resize the frame
          ■ scrolling Visibility of the scroll bar
           All of the preceding attributes are optional. However, the <frame> tag is rarely defined
      without an explicit src attribute. This is the attribute that allows you to specify the source HTML
      file for the frame.




       FIGURE 10-5      Using a nested frameset to subdivide frames into unequal pieces
CHAPTER 10: Communicate Between Browser Frames                    235

       When using JavaScript in conjunction with frames, it is often handy to use the name attribute
   to assign a unique name to the frame.
   <frame src="/dir/subdir/myframe.html" name="frame1">

       The frame’s source can be any valid URI—it does not even have to exist on the same web
   server as the other frames.
   <frame src="http://www.cnn.com/" name="frame1">

            Using the contents of another web site inside your own site is known as web site
            framing, and that practice has some potential legal ramifications involving trademark
            and copyright law. There is a very good article on the topic at http://www.gigalaw.com/
            articles/2000-all/kubiszyn-2000-04-all.html that you should read if you are interested in
            framing another web site without the owner’s permission.

       The default frame is created with resizable borders. You can easily create borders that cannot
   be resized by specifying the noresize attribute.
   <frame src="myframe.html" name="frame1" noresize>

   The noresize attribute does not need to have a value assigned to it—its presence inside a <frame>
   tag signifies a fixed border.
            In XHTML, the XML-compliant version of HTML, every attribute must be assigned                 10
            a value. In XHTML, you would assign noresize the value of its own name, such as
            noresize="noresize".

       By default, frames have visible borders separating one frame from the next. However,
   this is not always desirable, since these borders do not always match the style of a site.
   Fortunately, it is fairly easy to make the borders invisible, making the individual frames
   less noticeable.
   <frame src="myframe.html" name="frame1" noresize
       frameborder="0">

   Of course, you will need to add this frameborder attribute to each of the frame tags in a frameset
   to remove all borders.


Call JavaScript Functions from Other Frames
   As discussed in the first section of this chapter, a web page made up of three frames actually
   consists of four separate HTML files—one file for each of the frames and one master file for
   the frameset.
       These frames are independent of each other, but they are not ignorant of each other. It is
   possible for each frame to access the contents of any other frame, including any JavaScript
   variables and functions defined there.
236      How to Do Everything with JavaScript


      Access Another Frame Using JavaScript
      As discussed in Chapter 8, we can use the following JavaScript code to access the contents of
      a form:
      var myform = document.forms[0];
      var fullname = myform.fullname.value;

          This code will create a variable named myform, which directly refers to the first form on a web
      page. It will then use the myform variable to access a control named fullname and its contents.
          But how would we access the contents of that form if it were in another frame? Let’s assume
      for a minute that we have a frameset that is defined with the following HTML code.
      <html>
          <head>
              <title>Framesets</title>
          </head>
          <frameset rows="100, *">
              <frame src="banner.html" name="banner">
              <frameset cols="150, *">
                  <frame src="menu.html" name="menu">
                  <frame src="mainbody.html" name="bodyframe">
              </frameset>
          </frameset>
      </html>

          If we were in the second frame of that frameset (menu), how would we access the contents of
      a form contained in the third frame (bodyframe)?
          We do this by accessing the window object for the frameset. JavaScript provides several
      types of window objects for use in programs. The various JavaScript window objects, and their
      descriptions, are listed in Table 10-2.
                The window object and the Document Object Model in general are discussed in greater
                detail in Chapter 11.



       Object Name            Description
       window                 The current frame or window
       top                    The topmost window
       parent                 The frameset that contains the current frame (not always the topmost window)
       self                   The current frame or window; same as the window object
       TABLE 10-2      The JavaScript Window Objects
CHAPTER 10: Communicate Between Browser Frames                      237

     Each of the window objects listed in Table 10-2 contains an array named frames. When a
window object refers to an entire frameset, that object’s frames array contains one element for
each of the frames contained in the document. When a window object refers to a single frame,
this array will normally be empty. Of course, if the individual frames are also framesets, the
frames array will not be empty.
     To access the contents of the bodyframe frame from JavaScript code inside the menu frame,
we start with the topmost window, using the top object. We then access the third element (index
2, since arrays start at index 0) in that array.
var bodyframe = top.frames[2];

    The bodyframe variable represents a reference to the third frame defined in our frameset. We can
then access the document contained by that window using the document object from that frame.
var bodyframe = top.frames[2];
var bodydocument = bodyframe.document;

   Finally, we can access the form, and the elements on that form, in the usual manner from the
document object represented by bodydocument.
var   bodyframe = top.frames[2];
var   bodydocument = bodyframe.document;
var   myform = bodydocument.forms[0];
var   fullname = myform.fullname.value;                                                                  10
     This code is broken into four lines for manageability and easy reading. If a program needed
to reference more than a few elements on that form, or other objects on the bodyframe frame,
having a local variable that refers to that frame would be handy. To save some unnecessary
keystrokes, the preceding code can be written all on one line, like this.
var fullname = top.frames[2].document.forms[0].fullname.value;

This code is harder for the average programmer to read, however, and is slightly more confusing.
Code that is difficult to understand can often be a source of errors.
    Instead of using the frames array, a frame can also be accessed by name.
var fullname = top.bodyframe.document.forms[0].fullname.value;

Accessing the frame by name makes the code a bit easier to read and allows frames to be
resorted without large code changes.

Call a JavaScript Function Located in Another Frame
You’ve already seen how the contents of a frame (its forms and other HTML components) can be
accessed from external frames, so it should be no surprise that JavaScript variables and functions
can be accessed externally as well.
238      How to Do Everything with JavaScript


         To demonstrate, let’s assume we have a JavaScript function named sayhello() defined in the
      menu frame.
      function sayhello() {
          // This function says "hello" to the user
          alert("Hello!");
      }

          We could define a button in the bodyframe frame that will call the sayhello() function from
      the menu frame when clicked.
      <form action="#">
          <input type="button" value="Say Hello"
              onclick="top.menu.sayhello()">
      </form>

          Figure 10-6 shows the result of clicking the Say Hello button in the browser window.
          As long as JavaScript variables are defined outside of any function, they too can be accessed
      from another frame.




       FIGURE 10-6      Calling a JavaScript function defined in another frame
CHAPTER 10: Communicate Between Browser Frames                      239


                          Cross-Frame Scripting Can Be Risky

     Cross-frame scripting occurs when a frame that originates in one domain (like
     www.myserver.com) attempts to access a frame that originates in a different domain
     (like www.example.com) using JavaScript.
         The problem with cross-frame scripting is that a web site could define a frame that
     points to a secure web site, such as Microsoft’s Hotmail. The originating web site could
     then access any cookies or other sensitive user information from the frame, allowing them
     to use that information in a malicious manner. Because this a security risk, all IE browsers
     from version 4 on do not allow cross-frame scripting.



Handle Synchronization Between Frames
   In the last section, we saw some JavaScript code that relied on the existence of a JavaScript
   function in another frame.

   <form action="#">
       <input type="button" value="Say Hello"                                                               10
           onclick="top.menu.sayhello()">
   </form>

       But what happens if the user clicks the button before the menu frame has even finished
   loading? Most web browsers load frames in no particular order, and it is quite possible (actually,
   quite probable) that some frames will load slower than others. In this case, a JavaScript error will
   occur, since the sayhello() function could not be found.
       This problem can be described as one of synchronization. When dealing with frames that
   communicate with each other, we need a way to determine if all the frames are fully loaded
   before proceeding. There are several techniques a JavaScript programmer can employ to handle
   synchronization between frames.
       The first technique is to create a cascading effect between the frames, where each frame is
   responsible for loading the frames that depend on it. Using this method, we would have the menu
   frame load the contents of the bodyframe frame.

   top.bodyframe.document.location = "mainbody.html";

   We could then be guaranteed that the menu frame has already loaded in the browser window
   by the time the bodyframe document has finished loading as well.
       The second technique is to create one or more Boolean JavaScript variables in the
   frameset document. Each of the frames can set its respective Boolean variable to true when
240      How to Do Everything with JavaScript


      it has completely loaded. For example, we can modify our frameset document to the following
      HTML and JavaScript code:
      <html>
          <head>
              <title>Framesets</title>
              <script type="text/javascript" language="JavaScript">
              var banner_loaded = false;
              var menu_loaded = false;
              var body_loaded = false;
              </script>
          </head>
          <frameset rows="100, *">
              <frame src="banner.html" name="banner">
              <frameset cols="150, *">
                  <frame src="menu.html" name="menu">
                  <frame src="mainbody.html" name="bodyframe">
              </frameset>
          </frameset>
      </html>

          We can then add the following JavaScript code to the end of the menu frame in order to set
      the appropriate variable to true.
      <script type="text/javascript" language="JavaScript">
          var menu_loaded = true;
      </script>

          Inside the code for the bodyframe, we should move the call to the sayhello() function into
      a separate function, and add an if statement around it for safety.
      <script type="text/javascript" language="JavaScript">
          function callhello() {
              // Check the variable named menu_loaded first
              if (top.menu_loaded == true) {
                  top.menu.sayhello();
              }
          }
      </script>
      <form action="#">
          <input type="button" value="Say Hello" onclick="callhello()">
      </form>

          In this example, the Say Hello button will not work until the menu frame has completely loaded.
CHAPTER 10: Communicate Between Browser Frames                       241

   Lastly, we could use a technique similar to the DOM-based browser sniffing code from Chapter 7.
We could simply test for the existence of the frame and the sayhello() function before accessing them.
<script type="text/javascript" language="JavaScript">
    function callhello() {
        // Check if the frame and function exist first
        if (top.menu) {
            if (top.menu.sayhello) {
                top.menu.sayhello();
            }
        }
    }
</script>
<form action="#">
    <input type="button" value="Say Hello" onclick="callhello()">
</form>

     This same technique can be used to test for the existence of JavaScript variables or web
form controls.
     In the next chapter, we will investigate the various objects that make up the DOM.
It is through the methods and properties of these objects that we are able to interact with
the web browser.
                                                                                                           10
This page intentionally left blank
Interact with the
Chapter 11   Web Browser
244      How to Do Everything with JavaScript


      How to...
          ■   Manipulate the contents of a web page
          ■   Examine the entire browser window
          ■   Retrieve properties from the web browser software
          ■   Examine the operating system’s display settings
          ■   Access the web browser history list
          ■   Send the browser to a new location

      Although JavaScript has a powerful yet flexible core language syntax, it doesn’t have any built-in
      functions for reading data from file, database, or keyboard input, nor for writing data to a screen
      or printer. In each of its environments, JavaScript relies on an external object model to provide it
      basic input-output functionality.
            Table 11-1 lists some of the environments that provide support for JavaScript (or some version of
      it), and the object model that provides additional functionality beyond the core JavaScript functions.
            The object model used by web browsers is called the Document Object Model, or DOM
      for short. The DOM is a standard API (application programming interface) to the structure of
      documents. It allows JavaScript developers easy access to the document contents (such as forms,
      text, and style) as well as to browser-specific features (such as menus, scroll bars, and events).
      The DOM has evolved since the first browser was introduced many years ago, but the basic
      objects in a browser have not changed.
            The DOM specification is managed by the W3C, along with the HTML and XML specifications.
      Recent releases of the DOM standard now include methods and properties related to browser
      events, manipulation of style sheets, document validation, and XPath expressions.
            Many of the extensions to the DOM standard will not be covered in this chapter, as they
      either do not relate directly to HTML or are too advanced for our purposes. If you are interested
      in learning more about the new DOM, I encourage you to check out the specifications and other
      documents located on the W3C DOM web site: http://www.w3.org/DOM.

       JavaScript Environment         Object Model
       Web browsers                   DOM
       .NET (JScript)                 .NET Framework
       ASP (JScript)                  ASP object model
       Server-side JavaScript         Server-side extensions
       TABLE 11-1       JavaScript Environments and Their Respective Object Models
CHAPTER 11: Interact with the Web Browser                 245

Learn the Basics of the Document Object Model
   To understand the DOM, you must first understand how the specification has evolved. There were
   six basic objects in the original DOM, sometimes called DOM Level 0:

       ■   document
       ■   window
       ■   history
       ■   location
       ■   screen
       ■   navigator

       DOM 0 defines some other objects as well, such as forms, frames, and images. But to get to
   these objects, programs have to go through the top-level objects listed here. Objects could not be
   dynamically created, modified, or removed, since DOM 0 was static and the document could not
   be altered once rendered by the browser.
       Figure 11-1 is a good representation of the objects in the original DOM and how they related
   to each other.




                                                                                                          11




    FIGURE 11-1        The original Netscape DOM
246      How to Do Everything with JavaScript


           When the W3C adopted the DOM as a new web standard in 1998, it was called DOM Level 1,
      which is sometimes abbreviated to DOM 1. DOM 1 was the first attempt to adapt the object model
      for the emerging XML standard, which was set to revolutionize structured document formatting.
              Unlike subsequent versions of the DOM, DOM Level 0 was never an official standard.



          The DOM standard treats HTML (and XML) documents as hierarchies of data (called nodes).
      In DOM, the following parts of the document are all considered nodes:

         ■    Markup tags (elements)
         ■    Attributes
         ■    Text
         ■    XML character data (CDATA) sections
         ■    Entity references
         ■    Entities
         ■    Processing instructions
         ■    Comments
         ■    The document itself

           Nodes that are contained in other nodes are considered children of those nodes, while nodes
      that are at the same level as other nodes are considered siblings.
           DOM 1 allows programmers to access, add, delete, move, or modify almost any of the objects
      in the DOM tree. More specifically, DOM 1 separates a core set of API from an HTML-specific
      set. The HTML-specific API adds browser-related methods and properties to the objects defined
      in the core set.
           For example, let’s consider the following simple HTML code:
      <html>
          <head><title>My title</title></head>
          <body>
              This is <b>a test</b> of the <i>emergency broadcast system</i>.
              I repeat, this is only a test.
          </body>
      </html>

          Figure 11-2 shows how the preceding HTML code would look in a DOM 1 hierarchy. This
      hierarchy is also called the DOM tree.
          The next version of the DOM, known as Level 2, became an official W3C standard in
      November 2000. The core standard did not change much from the previous release, as DOM 2
      only added a few new properties and methods to the interfaces already defined in DOM 1. Its
CHAPTER 11: Interact with the Web Browser             247




 FIGURE 11-2      How a simple HTML document would look in a DOM tree


main purpose was to add support for views, events, and style sheets to the DOM API. It also
defined a specification for DOM traversal, the ability to move forward and backward through
a DOM hierarchy.
    DOM Level 3 was still in the W3C Working Draft stage at the time this book was published.       11
DOM 3 proposes to add two new interfaces to the core specification and will also add support
for XPath.




                       The Uses of XPath

  XPath is a simple yet powerful language for addressing parts of an XML document. For
  instance, you would use the following XPath expression to access the first <form> element
  on an XHTML web page.

      /html/body//form[1]

     This expression will match the first <form> element that is a descendant (but not
  necessarily a direct child) of a <body> element, which is itself the direct child of the root
  <html> element.
248      How to Do Everything with JavaScript


         The remainder of this chapter focuses on JavaScript programming for DOM 1, since the vast
      majority of browsers in use today support that version.


 Manipulate the Contents of a Web Page
      Perhaps the most useful of all the DOM objects is the document object. The document object
      provides access to the entire contents of a web page, as it is the root of all other objects in the
      HTML hierarchy. In Figure 11-2, the document object stands in place of the <html> element,
      at the top of the tree.
           The document object contains the following five arrays in JavaScript:

          ■   images
          ■   applets
          ■   links
          ■   forms
          ■   anchors

           Each of the document object’s arrays contains an enumerated list of the related elements on
      a web page. The images array contains a list of images, the applets array contains a list of Java
      applets, and so on. We have already seen how the forms array is a convenient way of accessing all
      the HTML <form> elements on a web page.
           In addition to the five arrays, the document object also provides JavaScript read and write
      access to any cookies associated with a web site (through the document.cookie property). A cookie
      is a piece of text a browser will store locally on behalf of a web site. Cookies are frequently used to
      store user ID and session information, so that a web site will be able to recognize known users
      when they return.
           The document object also contains the following six methods:

          ■   open()
          ■   close()
          ■   write()
          ■   writeln()
          ■   getElementById()
          ■   getElementsByName()

          The open(), close(), write(), and writeln() methods are used for printing raw HTML text to
      a web page. I have often used document.write() in this book’s sample code as a simple way of
      outputting results.
          The getElementById() and getElementsByName() methods allow us to quickly search a DOM for
      specific elements. This is a better approach than manually searching up and down the DOM tree for
      what we need, since these functions are optimized to return quickly.
CHAPTER 11: Interact with the Web Browser                   249

    Should we wish to navigate the contents of the HTML document without the convenience of
the various arrays (like the forms array) or the built-in search functionality (like getElementById),
we can access the body property of the document object directly. The body property allows us to
access all the HTML objects below the document object, starting from the HTML <body> element.
This property is not typically used in JavaScript programming, as searching the DOM using the
document arrays or using the built-in search functions is generally quicker and easier.

Dynamically Modify the Contents of a Web Page
One of the more interesting ways to use JavaScript and the DOM together is for creating web
pages that can change themselves according to the user’s behavior. This can be done without
having to get the web server itself involved.
    Let’s start by looking at a very basic web page.
<html>
    <head><title>Basic Web Page</title></head>
    <body>

         <h2>The time now is: <span id="time">00:00:00</span></h2>

    </body>
</html>

    As you can see in Figure 11-3, this HTML code creates a static web page. No matter what
time of day, it will always report the time as 00:00:00 (midnight).
                                                                                                          11




 FIGURE 11-3      A simple web page, before adding JavaScript
250      How to Do Everything with JavaScript


           But what if we wanted to add a small JavaScript script to the page that will constantly keep
      the time updated to the correct time? We can use the DOM document object to modify the contents
      of the web page.
      <script language="JavaScript" type="text/javascript">
          function update_time() {
              // The current date and time
              var rightnow = new Date();

               // Capture the hours as a string, "00" thru "23"
               var hours = rightnow.getHours();
               if (hours < 10)
                    var hourstring = "0" + hours.toString();
               else
                    var hourstring = hours.toString();

               // Capture the minutes as a string, "00" thru "59"
               var minutes = rightnow.getMinutes();
               if (minutes < 10)
                    var minutestring = "0" + minutes.toString();
               else
                    var minutestring = minutes.toString();

               // Capture the seconds as a string, "00" thru "59"
               var seconds = rightnow.getSeconds();
               if (seconds < 10)
                    var secondstring = "0" + seconds.toString();
               else
                    var secondstring = seconds.toString();

               // Put it all together, "00:00:00"
               var timestring = hourstring + ":" +
                                minutestring + ":" +
                                secondstring;

               // Manipulate the DOM, display it to the screen!
               var timeplace = document.getElementById("time");
               timeplace.childNodes[0].nodeValue = timestring;
          }
      </script>

          By calling the update_time() function when the document first loads, we can get the browser
      to update the string "00:00:00" with the current time.
           <body onload="update_time()">

          The screenshot in Figure 11-4 shows how the browser has replaced the original HTML string
      with the correct time.
CHAPTER 11: Interact with the Web Browser               251




 FIGURE 11-4      Using the document object to update the web page with the correct time


    Using browser timers, we can even get our web page to update with the correct time every         11
second. All we need to do is add the following code to the end of our update_time() function.
     setTimeout('update_time()', 1000);

     The setTimeout() function tells JavaScript that we would like to execute certain JavaScript
code at a certain time in the future. In the preceding code, we are saying that we would like to
call the function update_time() 1,000 milliseconds (1 second) from now. This will cause the
update_time() function to be called once per second until the user leaves the web page.

Change the Items in a Drop-Down List Box
Not only can developers modify the contents of an HTML web page, even the items in a drop-down
list box can change after the web page has loaded.
How many calories does a cheeseburger contain?<br>
<select id="listbox1">
<option>-- Please Select One --</option>
</select>

<script language="JavaScript" type="text/javascript">
252      How to Do Everything with JavaScript

      var counter;
      var listbox = document.getElementById("listbox1");
      for (counter = 100; counter < 500; counter += 50) {
          listbox.options[listbox.length] =
              new Option(counter + " - " + (counter+49));
      }
      </script>

          The preceding code creates an HTML drop-down list box with one item in it—“Please Select
      One.” Using JavaScript, it then adds eight more items to the list. Our JavaScript code starts by
      getting a reference to the list box and storing it in the variable named listbox. Using a for loop,
      we then create several new Option objects and add them to the end of the options array.
          You can see how the browser displays our dynamic list box here. (I do not, however, care to
      know how many calories a cheeseburger actually does contain.)




 Examine the Entire Browser Window
      The window object is not technically an official DOM Level 1 object. It provides access to other
      frames or open browser windows.
          In the last chapter, we discovered that there are four types of window objects in JavaScript.
      Table 11-2 summarizes those objects.
CHAPTER 11: Interact with the Web Browser                 253

 Object Name        Description
 window             Current frame or window
 top                Topmost window
 parent             Frameset that contains the current frame (not always the topmost window)
 self               Current frame or window; same as the window object
 TABLE 11-2     JavaScript Window Objects



   The four window objects may (or may not) point to different windows in the browser.
Typically, for a web page that does not contain framesets, all four objects refer to the same
underlying window.
   The window object provides access to three underlying DOM objects:

    ■ document
    ■ history
    ■ location
    We discussed document in the last section, and we will have a chance to look at history and
location in the sections that follow this one.
    The window object also provides access to the browser status bar, using the status property.
The status bar is the thin area below the main browser window that usually reports on the
progress of a page load and shows the URL of a hypertext link when the mouse pointer moves              11
over it. The following JavaScript code modifies the browser status bar to a custom value:
window.status = "Welcome to my web site!";

    The following screenshot shows how this affects the status bar after our web page has loaded.




    In the last chapter you also learned that the window object contains an array named frames
that enumerates all the frames in a frameset. It is through the frames array that we can access the
HTML and JavaScript code located in another frame.
    The window object also provides several methods that can be used to communicate with the
user or to open and close new browser windows. Table 11-3 lists some of the more interesting
window methods.
254      How to Do Everything with JavaScript


       Method                              Description
       alert()                             Creates an alert dialog box
       blur()                              Causes the window to lose focus
       close()                             Attempts to close the browser window
       focus()                             Causes the window to gain focus
       moveBy(), moveTo()                  Repositions the browser window
       navigate()                          Loads a specific URL into the browser
       open()                              Opens a new browser window
       print()                             Attempts to print the browser contents to a printer
       resizeBy(), resizeTo()              Resizes the browser window
       scroll(), scrollBy(), scrollTo()    Causes the window to scroll
       setTimeout(), clearTimeout()        Causes JavaScript code to be executed after a specified delay
       TABLE 11-3        Useful window Methods


          One interesting window method is open(). This method is used to create a new browser window
      when you do not wish to interrupt the current web page. Sadly, this is the technique used for most
      pop-up web advertisements. It is still quite useful, however, when you want to direct the user at
      their request to some online help, such as a user manual or online glossary.
      window.open("userhelp.htm", "_blank",
          "height=300,width=200,toolbar=no," +
          "status=no,menubar=no,location=no");

          The preceding code will open a new browser window and direct it to the HTML file
      userhelp.htm. The code specifies a specific height and width for the window (300 by 200)
      and removes all toolbars, menu bars, and the status bar, leaving a sparse window.
          Figure 11-5 shows how this new HTML window will look in a typical web browser.

 Retrieve Properties of the Web Browser Software
      The programmers at Netscape probably still get some joy over the fact that the standard object
      for retrieving browser information is called navigator, named after what used to be the most
      widely used browser in the early days of the Web. You might recall that we talked about some
      of the properties of the navigator object in Chapter 7, when it was used to retrieve the name and
      version information from the user’s browser.
           The navigator object contains one array, called plugins. This array contains a list of browser
      plug-ins (although the contents of the list vary by browser maker). A browser plug-in is an
      application that runs inside the browser, usually to provide support for embedded multimedia.
      Shockwave Flash and RealNetworks RealPlayer are two popular plug-ins.
           In Netscape and Mozilla web browsers, the plugins array can be used to determine which
      browser plug-ins have been installed on the client PC. In Internet Explorer, the only plug-ins
      listed in the plugins array are the ones currently in use on the web page.
CHAPTER 11: Interact with the Web Browser               255




 FIGURE 11-5     A pop-up window can be used to provide quick online help.


    For example, the following code, for Netscape web browsers, checks to see if the Macromedia
Flash plug-in is installed on the user’s computer.
var flashinstalled = false;
for (var i=0; i < navigator.plugins.length; i++) {
                                                                                                    11
    if (navigator.plugins[i].name == "Shockwave Flash") {
        flashinstalled = true;
        break;
    }
}

if (flashinstalled) {
    document.write ("I see you have Macromedia Flash installed!");
} else {
    document.write ("If you want to see the multimedia installed ");
    document.write ("on this web site, you will need to install ");
    document.write ("Macromedia Flash.");
}

   The navigator object also supports several properties, such as the following.

   ■ appCodeName
   ■ appName
   ■ appVersion
256      How to Do Everything with JavaScript


          ■ userAgent
          ■ userLanguage
          These properties provide JavaScript with some important information about the exact
      browser type running on the client machine. For instance, you may wish to provide content
      formatted in a simpler manner for older browsers (version 4) and content that relies on style
      sheets for visitors using a newer browser.


 Examine the Operating System’s Display Settings
      Web programmers often develop web pages with a specific screen size in mind. For instance,
      some sites are developed for screens that are 800 pixels wide by 600 pixels high (often called
      800 by 600 resolution). If a user’s resolution is smaller, say 640 by 480, they will be unable to
      see parts of the page. If a user’s resolution is bigger, say 1024 by 768, the web page will have
      a lot of blank space.
          The best-designed sites are frequently developed to expand or contract based on available
      space. We have seen this with frames using relative sizing, and it can also be done with HTML
      tables. Both these solutions allow the browser to automatically resize components based on the
      amount of available screen space. (You may sometimes hear available screen space referred to
      as real estate.)
          But when dealing with Dynamic HTML, where elements are frequently placed in specific X
      and Y coordinates on the screen, it is helpful to have some information about the screen resolution.
      The DOM provides the screen object to give JavaScript a little more information about the
      technical properties of the user’s display.
          The screen object was not part of the original release of JavaScript. It was added in version 4
      of the IE and Netscape browsers. The following table lists some of the properties of this object.

       Property Name           Purpose
       availHeight             Returns the height of the working area of the system screen, excluding the
                               Windows taskbar
       availWidth              Returns the width of the working area of the system screen, excluding the
                               Windows taskbar
       colorDepth              Returns the number of bits per pixel used for colors
       height                  Returns the vertical resolution of the screen
       width                   Returns the horizontal resolution of the screen


         For example, the following JavaScript code will allow you to resize and then center the
      browser window on the user’s monitor.
      var newTopLeftX = (screen.availWidth - 640) / 2.0;
      var newTopLeftY = (screen.availHeight - 480) / 2.0;
      window.resizeTo (640, 480);
      window.moveTo (newTopLeftX, newTopLeftY);
CHAPTER 11: Interact with the Web Browser                  257

       The code uses the window.resize() function to resize the browser to 640 pixels wide by
   480 pixels tall. It then uses a common centering technique to place the window perfectly in
   the center of the screen, regardless of the resolution setting of the user’s monitor.


Access the Web Browser History List
   JavaScript has limited access to the browser history list through the history object. The browser
   history list is an ordered list of web pages you recently visited, and it is stored internally by your
   web browser. You access the browser history list every time you use the back and forward
   buttons of your web browser.
       Through the history object, JavaScript has the ability to send a browser back to the previous
   web page—or back by an arbitrary number of web pages. For example, the following JavaScript
   code will send the browser to the web page most recently visited before the current one.
   history.back();

       Programmers can also tell the browser to go back by any number of pages, by specifying
   an integer to the history object’s go() method. The following code will send the browser back
   five pages.
   history.go(-5);

        The history object only has one property, length. The length property will return the number
   of items in the history list.
        The history object has three methods.
                                                                                                              11
    Method Name         Purpose
    back()              Go back one item in the history list; simulates the Back browser button.
    forward()           Go forward one item in the history list; simulates the Forward browser button.
    go()                Go back or forward the specified number of items in the history list; a positive
                        number goes forward and a negative one goes back.


       The history object is often used as an easy way to direct the user back to the previous page.
   <html>
       <head><tile>User Login Script</title></head>
       <body>

           <h1>Error: Unable to Log In</h1>

           I'm sorry, the password you supplied was incorrect.
           Please use the Back button on your browser to try again,
           or <a href="javascript:history.back()">click here</a> to
258      How to Do Everything with JavaScript

              be automatically sent there.

          </body>
      </html>

                  For security reasons, the history object does not provide JavaScript access to the names
                  or URLs of the web pages you have visited.


 Send the Browser to a New Location
      The location object gives JavaScript access to the browser address bar. Specifically, programmers can
      determine the URL of the current page, reload the current page, or send the browser to a new URL.
          The location object has eight properties.

       Property Name          Purpose
       href                   Gets or sets the entire URL as a string
       hash                   Gets or sets the portion of the URL after the hash sign (#)
       host                   Gets or sets the hostname and port number portion of the URL
       hostname               Gets or sets the hostname portion of the URL
       pathname               Gets or sets the filename or path of the web page
       port                   Gets or sets the port number portion of the URL
       protocol               Gets or sets the web protocol name of the URL (e.g., HTTP)
       search                 Gets or sets the portion of the URL after the question mark (?)


          The location object also has three methods.

       Method Name            Purpose
       assign                 Loads a new web page
       reload                 Reloads the existing web page
       replace                Replaces the existing web page by loading a new web page


          The location object is commonly used to redirect the browser to a new web page.
      location.href = "http://www.example.com/another/page.html";

      But it can also be used just to reload the current page, similar to a browser refresh action.
      location.reload();

          In the next chapter, we will examine how to perform some simple animation using JavaScript,
      CSS, and Dynamic HTML. Using a technique known as absolute positioning, we will be able to
      place text and images anywhere we wish inside a web page.
Perform Simple
Chapter 12   Animation
260      How to Do Everything with JavaScript


      How to…
          ■   Format a web page using style sheets
          ■   Control text and image positioning
          ■   Modify styles using JavaScript
          ■   Perform basic animation using JavaScript

      In Chapter 11, you saw how the browser DOM can be manipulated using JavaScript to modify
      the HTML in a web page after it has already been loaded into the browser. This technique is
      often used for allowing JavaScript to respond to user events or input without having to go back
      to the web server to re-create the page.
           As you’ll see in this chapter, Cascading Style Sheets (CSS) allow developers to specify
      the exact layout and positioning of elements on the web page. Style sheets can be dynamically
      modified in JavaScript as well, allowing elements to be given a different appearance or even
      moved to a different position on the screen.
           Animation is often nothing more than the repeated manipulation of the DOM and/or style
      sheets using JavaScript. An animated butterfly can appear to flutter across the screen with
      nothing more than the repeated swapping of a small number of images combined with the slow
      repositioning of those images across the page. In this chapter, we will examine how style sheets
      can be dynamically modified using JavaScript and how that technique can be used to create
      some simple animation effects.


 Learn the Basics of Cascading Style Sheets
      We have touched briefly on the topic of style sheets before, but in this section we will examine it
      in more detail to gain a better understanding of what style sheets can do for web developers and
      how JavaScript can be used to dynamically affect style.
          The style of a web page is the manner in which the contents of the web page, such as the text
      and graphics, are formatted and arranged. Style encompasses everything from how fonts and colors
      are used to the sizes and positioning of objects inside the browser window.
          When the Web was first developed in 1991, very little consideration was given to style—
      the emphasis was on content. The Web was used for the presentation and linking of related text
      documents. In fact, one of the overriding philosophies of its design was that web clients (generally
      browsers) should be responsible for rendering the web page in the manner they best saw fit.
          For instance, the <h1> tag simply defined a first level heading, and it was up to the browser
      to define the exact font type and size used for displaying the heading text. The content of <h1>
      tags could theoretically look completely different depending on the brand of browser you were
      using or the operating system you were running.
          Of course, many developers needed more precise methods to format the contents of a web
      page, so some pretty elaborate schemes were sometimes used to provide a complex page layout,
      such as the use of invisible images to help solve spacing problems.
CHAPTER 12: Perform Simple Animation              261


                       Why CSS Are “Cascading”

  We say that style sheets cascade because, aside from a few exceptions, HTML elements
  inherit the style attributes of the elements they’re contained in. For example, assume you
  have an HTML <b> element that is inside a <u> element:

      <u>This is <b>some</b> text.</u>

      If you were to set the CSS font attribute of the <u> element, the <b> element would
  inherit that font setting as well. You can, however, override the cascading effect by assigning
  a different font setting to the <b> element.


    The W3C introduced the CSS Level 1 standard in late 1996. IE 3 was the first browser to
include partial support for this new standard, and Netscape 4 soon followed with some partial
(albeit extremely buggy) support for CSS as well.
    A style sheet is a group of definitions that describe the style for a set of HTML elements.
Using style sheets, you can completely redefine the way a certain element is rendered inside
the web browser, as each element exposes a number of attributes whose value can be changed.
         The W3C has a very good web site for learning more about style sheets;
         go to http://www.w3.org/Style.

Assign Style to Web Pages Using HTML Elements                                                         12
The original method of formatting the contents of a web page was by using HTML style-related
elements and attributes. For instance, the <font> tag could be used to set the typeface, size, or
color for text inside a document. The <b> tag could be used to make text bold, <i> would create
italics, and so on.
     However, this was a very inefficient method for styling a web page, for a number of reasons:

    ■ The style and layout of a web page could not be easily reused between two or more
        HTML files, which created extra development work for web page authors.
    ■ Frames, nested tables, invisible images, and other complex and messy techniques
        needed to be used to place text or graphics in a particular spot.
    ■ Duplicate HTML style tags, such as the <font> tag, needed to be repeated many times
        on the same web page.
    ■ It was a lot of work to change the style of a web page or of an entire site.
    ■ Web pages were larger, which meant it took longer for them to download to browsers.
262     How to Do Everything with JavaScript



                             How to Specify Colors in HTML

        There are several places in HTML, CSS, and JavaScript that require a programmer to specify
        a color. For instance, the HTML <font> tag has a color attribute with which you can specify
        the font’s color.
            Colors can be specified by name or by RGB (red-green-blue) value. Several colors
        have predefined names in HTML, such as black, white, yellow, and blue. There are dozens
        of predefined colors.
            If you would like to use a color that does not already have a name, you can specify an
        exact RGB value. RGB values start with the pound symbol (#) followed by three pairs of
        hexadecimal digits, such as #FF33C0.
            The first pair of hexadecimal digits represents the amount of red in a color, ranging from
        a value of 00 (darkest) to FF (brightest)— that’s 256 unique settings for red. The second pair
        represents the amount of green, while the third pair represents the amount of blue.
            So the color #FF33C0 represents a combination of bright red, dark green, and medium
        blue, which comes out looking a lot like fuchsia (a bright purplish-pink color). #FFFFFF
        represents pure white, and #000000 represents pure black.


          For example, the following HTML code defines a page with a moderately complex style.
      The HTML code is messy and difficult to read due to all the extra HTML tags and attributes
      that are required.
      <html>
          <head><title>Style sheets example</title></head>
          <body bgcolor="white" link="purple" vlink="green">

           <center>
              <h1>
                 <font color="#333399" face="Arial">
                     Introduction to XML
                 </font>
              </h1>
           </center>

           <p><font color="#993333" face="Arial" size="3">
           &nbsp;&nbsp;&nbsp;&nbsp;<b>XML is one of the most
           important new standards to come out of the W3C<br>
           &nbsp;&nbsp;&nbsp;&nbsp;since HTML.</b> All developers
CHAPTER 12: Perform Simple Animation              263

     should be aware of what XML is and how it<br>
     &nbsp;&nbsp;&nbsp;&nbsp;should be used. In this article,
     we introduce the basics of XML, including a<br>
     &nbsp;&nbsp;&nbsp;&nbsp;discussion on DTDs.</font></p>

    </body>
</html>

    The preceding code includes a number of formatting tags such as <center>, <font>, and <b>.
There are also a number of nonbreaking spaces (&nbsp;) to help indent the paragraph, and the
<body> tag contains three style-related attributes. I also had to add manual line breaks (<br>)
to artificially set the spot where the text wraps to the next line.
    Figure 12-1 shows how the browser is able to render a well-styled page from our sample
HTML code.




                                                                                                    12




 FIGURE 12-1     The traditional method of formatting a page using HTML style tags
264      How to Do Everything with JavaScript


      Assign Style to Web Pages Using Style Sheets
      Of course, we can create the same effect shown in Figure 12-1 using style sheets. The style sheet
      solution, however, will be neater, easier to develop, and simpler to maintain in the future. We can
      even share this style definition with any number of other web pages, saving us valuable development
      time. We can also do some pretty cool things this way that HTML style tags just cannot do.
          First, we will take our web page example and remove the HTML style tags and attributes
      from it. We will use HTML <div> tags instead to mark the text that needs to be styled.
      <html>
          <head><title>Style sheets example</title></head>
          <body>

           <div id="heading">
              Introduction to XML
           </div>

           <div id="summary">
           <span id="boldintro">
           XML is one of the most important new standards to come
           out of the W3C since HTML.
           </span>

           All developers should be aware of what XML is and how it
           should be used. In this article, we introduce the basics
           of XML, including a discussion on DTDs.
           </div>

          </body>
      </html>

          We can create a simple style sheet for this document, and insert it into the web page
      using the HTML <style> element. The <style> element belongs inside the <head> section
      of the document.
      <style type="text/css">
      #heading {
          font: 24pt Arial;
          color: #333399;
          text-align: center;
          margin-bottom: 20pt;
      }

      #summary {
          font: 12pt Arial;
          color: #993333;
CHAPTER 12: Perform Simple Animation                 265

     margin-left: 20pt;
}

#boldintro {
    font-weight: bold;
}
</style>

     We will examine the syntax of the style sheet itself later in the chapter. But even without
knowing exactly what the style sheet means, you can see what it does. The resulting web page
is almost identical to the one displayed in Figure 12-1, which was styled with traditional HTML,
but the style sheet method is many times more flexible and powerful.

Use <div> and <span> to Mark Dynamic Text
HTML 4.01 provides two special elements to support the integration of CSS and HTML:
<div> and <span>.
    The <div> element is a marker for text blocks. A text block is one or more complete paragraphs
that must start and end on a new line. The <div> element makes it easier for a document to be
styled using style sheets.
<div id="FirstError">Error! You have entered an incorrect user ID
and/or password. Please try again, and if you continue to have
difficulty, please contact a system administrator for help.</div>

   The <span> element is very similar, except it deals with inline text. Inline text does not
have to start or end on a new line, so <span> can be used for applying style to single characters,
words, or sentences.                                                                                     12
<span style="font-size:14pt">H</span>is main goal in life was
<span style="font-weight:bold">world domination</span>, although
tonight he was willing to settle for a nice steak and a cold beer.

     The primary attributes of <div> and <span> are id, style, and class. id allows you to specify
a name for the enclosed text. This makes it easy to access the text using JavaScript or CSS. The
style attribute allows you to specify CSS directly inside the HTML. The class attribute is similar
to the id attribute, except several tags can have the same class attribute while the id attribute is
unique to a single tag.

Define Inline Styles
The HTML standard allows CSS style syntax to be defined inside the body of the document
using a technique called inline styles. Most HTML elements have an attribute called style that
can accept CSS definitions, like so:
<p style="font:Arial;font-weight:bold">
     This is some text
</p>
266      How to Do Everything with JavaScript


          Using this technique is quick and convenient, but you lose some of the benefits of using style
      sheets. Specifically, the body of the document remains complex, messy, and hard to maintain.
      The style sheet code is impossible to easily reuse. In fact, since the style is not separated from the
      content at all, this technique is equivalent to using HTML style tags and attributes.
          The one benefit you do get is the ability to use complex styles not available using the HTML
      style tag method. For small web pages or those with unique style requirements this might be an
      acceptable method.

      Define Embedded Style Sheets
      The next step up from inline styles is the use of embedded style sheets. An embedded style sheet
      is one defined using the HTML <style> tag inside the header section of the document. Styles
      defined in this manner are available to the entire web page, so it is entirely possible to define
      only one or two style definitions for a large and complex document.
          A style sheet is made up of one or more rules. A rule is a single definition for a style, in the
      following format:
      selector {
          attribute1 : value;
          attribute2 : value;
          …
          attributeN : value;
      }

         For example, in the previous section we had a style sheet with three rules. One of the rules
      was defined with the following code:
      #summary {
          font: 12pt Arial;
          color: #993333;
          margin-left: 20pt;
      }

          The rule has a selector (#summary) and defines values for three attributes (font, color, and
      margin-left). The selector determines which HTML tags have their attributes set to the specified
      values. By the way, the rule does not have to be spaced over several lines as I have been doing.
      You can place the rule all on one line, or break it up over several more lines to improve readability,
      if you wish.
          The following table shows how selectors work in CSS.

       Selector           HTML Code Affected
       h1                 Affects all <h1> tags in the document.
       #heading           Affects the tag with an id attribute set to heading.
       .blue              Affects all tags with a class attribute set to blue.
CHAPTER 12: Perform Simple Animation                    267

 Selector           HTML Code Affected
 p#heading          Affects all <p> tags in the document with an id attribute set to heading.
 p.blue             Affects all <p> tags in the document with a class attribute set to blue.
 h1, h2, h3         Affects all <h1>, <h2>, and <h3> tags in the document.
 pb                 Affects all <p> tags that are contained inside <p> tags; <b> tags not inside <p> tags
                    are not affected.
 ul ul li           Affects all <li> tags that are inside at least two <ul> tags.
 div .red           Affects all tags with a class attribute set to red that are also inside a div attribute.


     As you can see, there are ways to set the style for the entire document all at once and ways to
set the style of very specific elements within the document. You can ultimately create some very
complex and comprehensive style sheets using sophisticated selectors.

Import External Styles
There are two ways to import a style sheet from an external file into an HTML document:

    ■ The HTML <link> element
    ■ The style sheet @import command
    This means that you can create a single style sheet file that can be applied to all the pages on
a web site. And with a few simple keystrokes in a text editor, you can radically change the style
of all the pages on your site at once.
    To use the <link> element, place the following HTML code in the <head> section of your
web page:                                                                                                        12
<link rel="STYLESHEET" type="text/css"
      href="http://www.example.com/mystyle.css">

    The preceding code will cause the style sheet which is located at http://www.example.com/
mystyle.css to be imported into the web page. The file extension .css is often used for style sheets.
    To import the same style sheet using the @import command, we actually need to add
a <style> section to the document header.

<style type="text/css">
   @import url(http://www.example.com/mystyle.css);
</style>

    All three types of style sheets (inline, embedded, and external) can be combined in a single
document. If styles conflict, the inline styles have precedence, followed by the embedded styles,
and lastly the external styles.
268      How to Do Everything with JavaScript


      Use Basic Style Attributes
      As mentioned in the “Define Embedded Style Sheets” section, a style sheet is made up one or
      more of rules, and rules are made up of a selector plus one or more attributes. In this section, we
      will look at the different types of attributes that can be used to set styles.
          There are literally dozens of attributes defined in the official CSS 1 specification—so many
      that I won’t even attempt to cover them all in this book. For more information on the available
      CSS attributes, I suggest the following two excellent sources:

          ■ The official W3C CSS 1 specification can be found at http://www.w3.org/TR/REC-CSS1.
          ■ The Microsoft MSDN web site has an excellent reference guide at
              http://msdn.microsoft.com/workshop/author/css/reference/css_ref_entry.asp.

          The MSDN reference guide is particularly well organized; CSS attributes are cross-
      referenced with their related HTML elements. In fact, I believe this web site to be the most
      complete web programming reference available on the Internet—not just for CSS, but for all
      web-related programming topics.
          Table 12-1 describes some of the most frequently used CSS attributes.
          Several of the attributes listed in Table 12-1 are compound attributes; that is, they allow you
      to set many properties of an element at once. For instance, the font attribute allows you to set up
      to 14 font-related properties in one string:

      BODY {
          font: italic normal bold 12pt Arial;
      }

          This convenient shortcut is equivalent to the following code:

      BODY {
          font-style: italic;
          font-variant: normal;
          font-weight: bold;
          font-size: 12pt;
          font-family: Arial;
      }

           So as you can see, compound attributes save time and effort but add additional complexity,
      in that they are more difficult to construct.


      Position Elements on a Web Page
      Some CSS attributes have nothing to do with text style and deal instead with layout and positioning.
      Setting the positioning of an element allows you to specify the exact size (height and width) of
      the object as well as its exact physical location (x and y coordinates) on the screen.
CHAPTER 12: Perform Simple Animation                 269

 Attribute Name    Purpose
 font              Allows you to set up to a dozen font-related properties, including size and style
 color             Allows you to set the foreground color of an element
 background        Allows you to set up to five background-related properties, including color and image
 text-align        Allows you to set left, center, or right alignment for text
 margin            Allows you to set the size of the empty space around an element
 border            Allows you to set the size, style, and color of the border around an element
 TABLE 12-1       Common CSS Attributes



    For example, let’s assume we have the following HTML code:
<html>
    <head>
        <title>Style sheets example</title>
        <link rel="STYLESHEET" type="text/css"
            href="example.css">
    </head>
    <body>

        <div id="special">This is a great example of separating
        content from layout. From an HTML perspective, this text
        is a pretty simple paragraph, with no formatting requirements.
        Browsers that do not support style sheets will render                                                12
        this text to the screen in a plain and simple manner.
        </div>

    </body>
</html>

This HTML code contains no formatting instructions. All we have done is provide a paragraph
of text surrounded by a <div> tag. The <div> tag does not do anything other than provide a way
to name a block of text. (We examined the difference between <div> and <span> earlier in the
chapter, in the “Use <div> and <span> to Mark Dynamic Text” section.)
     Our HTML code does, however, contain a <link> reference to a style sheet file. The file,
example.css, will contain the formatting instructions we wish to use. In our case, it will define
CSS positioning attributes.
     The example.css file will contain the following code:
#special {
    position: absolute;
    top: 50px;
270       How to Do Everything with JavaScript

            left: 100px;
            width: 3in;

            background-color: #CCCCCC;
            padding: 15px;
            font: 12pt Arial;
            border: solid 2pt black;
      }

          The preceding style sheet contains four of the CSS size and positioning attributes:

          ■   position     Tells the browser we wish to position the content ourselves
          ■   top    Sets the position of the top edge of the element
          ■   left Sets the position of the left edge of the element
          ■   width      Sets the width of the element

           In our case, the element is the <div> tag that surrounds our text. The <div> tag has an id
      attribute of special, which matches the #special selector assigned to the rule.
           There are a couple of additional positioning attributes that were not used, most notably height,
      which can be used to set the height of the element. In our case, we are allowing the browser to
      calculate the proper height for the element based on the size of the text contents. There is also an
      attribute named visibility, which can make an element invisible.
           Figure 12-2 shows how the text inside our HTML document has been positioned and sized
      exactly as specified in our style sheet.

      Modify Styles Using JavaScript
      Now that we have examined what style sheets are and how they can be used to format a web
      page, we can take a look at how JavaScript can be used to modify styles dynamically.
          The DOM provides JavaScript access to the style-related properties of almost any object
      on the page. For instance, assume we have a web form defined as follows:
      <form action="#" method="get">

            <div style="position:absolute;top:50px;left:100px;">

            Full Name:<br>
            <input type="text" name="fullname" id="fullname"><br><br>

            Email Address:<br>
            <input type="text" name="email" id="email">

            </div>

      </form>
CHAPTER 12: Perform Simple Animation                271




 FIGURE 12-2      The browser has successfully interpreted our style sheet.
                                                                                                       12
   Our JavaScript program can access the text box control named fullname using the DOM and
manipulate its style.
     var TextBoxes = document.getElementsByTagName("input");

     for (var counter=0; counter < TextBoxes.length; counter++) {

          var myTextBox = TextBoxes[counter];
          myTextBox.style.backgroundColor = "black";
          myTextBox.style.color = "white";
          myTextBox.style.font = "22pt Arial";

     }

    The preceding JavaScript code will locate all the <input> elements on the page and alter their
style properties. What we will end up with are two text boxes that have black backgrounds, white
text, and a large, 22-point Arial font. You can see the results of this code in Figure 12-3.
272      How to Do Everything with JavaScript




       FIGURE 12-3      The styles have been altered dynamically using JavaScript.


               The names of the JavaScript properties are often different than the names of the
               corresponding CSS attributes. For instance, the CSS attribute background-color
               is set using the JavaScript property backgroundColor.

          Table 12-2 lists some of the CSS attribute names we have been using and the corresponding
      DOM style property names.
          As you can see, there is some consistency between the naming of CSS style attributes and
      the corresponding JavaScript DOM property, but occasionally the two names differ, so it is best
      to check whenever you are uncertain of the correct name.

      Understand Cross-Platform Issues
      CSS support used to be extremely inconsistent between the top two or three browser manufacturers.
      Today, the vast majority of browsers in use fully support CSS 1. Most browsers have at least partial
      support for the CSS 2 specification, and CSS 3 is currently under development.
CHAPTER 12: Perform Simple Animation              273

 CSS Attribute                       Corresponding DOM Property
 background                          background
 background-color                    backgroundColor
 border                              border
 border-bottom                       borderBottom
 border-left                         borderLeft
 border-right                        borderRight
 border-top                          borderTop
 color                               color
 font                                font
 font-family                         fontFamily
 font-size                           fontSize
 font-weight                         fontWeight
 margin                              margin
 margin-bottom                       marginBottom
 margin-left                         marginLeft
 margin-right                        marginRight
 margin-top                          marginTop
 text-align                          textAlign
 TABLE 12-2       The Relationship Between CSS and JavaScript DOM Styles

                                                                                                        12
    Internet Explorer was the first browser to contain support for style sheets, and Microsoft
added several of their own attributes that were not part of the standard and do not work in other
browsers. Obviously, if you want your style sheets to work in all browsers, stick to attributes
and commands that are part of the official standard and avoid proprietary extensions.
    Netscape 4 contains a buggy, partial implementation of the CSS standard. It is quite difficult
to get style sheets to work for that browser beyond a few basic attributes, so understand that a
web page that relies heavily on style sheets might not look as intended in the Netscape 4 web
browser. Fortunately, the market share for that browser has dipped below 3 percent, so the problem
will eventually go away on its own.
          The W3C provides a CSS validator service. The CSS validator, located at
          http://jigsaw.w3.org/css-validator, will examine any HTML web page (or individual
          style sheet) you specify to ensure the style sheet is completely valid. The tool provides
          helpful feedback for finding out where problems lie, and so is very useful when
          developing CSS-enabled web pages.
274      How to Do Everything with JavaScript


 Perform Basic Animation Using JavaScript
      We have discussed how JavaScript can be used to change elements within the DOM as well as
      CSS style and positioning attributes. In this section, we will examine two of the most common
      techniques for creating animation on a web page using JavaScript.

      Dynamically Load Images
      The simplest type of animation in JavaScript is accomplished by just switching images. You see
      something similar to this all the time on the Web, where a graphical menu or button changes
      when your mouse moves over it. In fact, you saw an example of that effect in Chapter 9, in the
      discussion on mouse events:
      <script type="text/javascript" language="javascript">
      function changeimage(num) {
          var img = document.getElementById("SampleImage");
          if (num == 1) {
              img.src = "NewImg.gif";
          } else {
              img.src = "OriginalImg.gif";
          }
      }
      </script>

      <img src="OriginalImg.gif"
          id="SampleImage"
          alt="Sample image"
          onmouseover="changeimage(1)"
          onmouseout="changeimage(2)" >

           In the JavaScript function changeimage(), we used the document.getElementById() function
      to retrieve the image object defined in the body of the HTML document. Depending on the type
      of event (onmouseover or onmouseout), the src property of the image is pointed to a different file.
           Mouseover events are the shortest form of animation—sort of like a half-second movie. In
      order to create a longer effect, we need to do several rapid image switches in a row. For instance,
      let’s build a fairly simple animation effect that uses timer events:
          1. Start with a set of related images that make up the animation.
CHAPTER 12: Perform Simple Animation            275

2. Place the first image on a web page using the HTML <img> tag. Be sure to assign the
   <img> an id attribute.
    <img src="image1.gif" id="anim">

3. Then create a JavaScript function called animate() that alternates between each of the
   three images at regular intervals, say every ¼ second.
    // The counter variable controls the animation
    var counter = 0;

    function animate() {
        var img = document.getElementById("anim");

         // Proceed to the next image
         counter ++;
         // There are only four images, so restart when we're done
         if (counter > 3) counter = 0;

         if (counter == 0) {
             // Display the first image
             img.src = "image1.gif";
         } else if (counter == 1) {
             // Display the second image
             img.src = "image2.gif";
         } else if (counter == 2) {
             // Display the third image
             img.src = "image3.gif";
                                                                                              12
         } else {
             // Display the fourth image
             img.src = "image4.gif";
         }

         // We need to call the animate function again in 0.10 seconds
         // Pause for 1 second between the fourth and first image
         if (counter == 3) {
             setTimeout("animate()", 1000);
         } else {
             setTimeout("animate()", 100);
         }
    }
276      How to Do Everything with JavaScript


          4. We can start the animation by calling the function from within the <body> element’s
             onload event handler.
              <body onload = "animate()">

          5. The net result is that our graphic appears to be animated inside the browser window.

           Rapidly switching sequentially through the different graphics creates an animation that draws
      a circle in the browser window.


      Make Content Move Around the Screen
      The other way to perform basic animation is by moving an object around on the screen. We have
      already seen that JavaScript can access the CSS positioning attributes of any object on a page. It
      would be fairly easy, then, to use that same technique to create JavaScript animation.
          Let’s start with the image of a ball.




      The image is placed on a web page using the HTML <img> tag:
      <img src="ball.gif"
           id="ball"
           class="ballstyle">
      <div class="boxstyle">&nbsp;</div>

          We should also create a style sheet for this page, so that the ball and box will start off with
      the correct style and positioning.
      <style type="text/css">

      .ballstyle {
          position: absolute;
          top: 50px;
          left: 100px;
      }

      .boxstyle {
          position: absolute;
CHAPTER 12: Perform Simple Animation               277

     top: 50px;
     left: 100px;
     height: 250px;
     width: 400px;
     border: solid 1pt black;
}

</style>

    We will need a function, called moveball(), to animate the image by altering its top and left
style attributes.
// Set the starting coordinates
var mytop, myleft;
mytop = 50;
myleft = 100;

function moveball() {
    img = document.getElementById("ball");
    mytop += 10;
    myleft += 2;

     if (mytop > 230) mytop = 50;
     if (myleft > 430) myleft = 100;

     img.style.top = mytop;
     img.style.left = myleft;                                                                         12
     setTimeout("moveball()", 100);
}

    We must start the ball moving by calling the moveball() function from within the onload
event handler of the <body> element.
    As you can see in Figure 12-4, we have created a rather interesting effect. The image of the
ball continues to move slowly down and to the right of the screen until it reaches the edge of
the box. Once there, it switches back to the other side of the box and continues its motion.
    Text can also be animated using this same technique. Instead of moving the position of
an image, we could surround some text with a <div> tag and move it around. Obviously, more
complicated animations, such as animated objects that move in a random manner or change
direction when they reach the edge of the window, require a longer and more complicated script.
278      How to Do Everything with JavaScript




       FIGURE 12-4     By modifying the CSS position attributes, we are able to make a ball move.


          In the next chapter, we will discuss the fundamentals of debugging JavaScript code. A bug is
      a software flaw, and debugging is the process of finding and repairing the bugs in a program. We
      will take a look at some of the tools available to developers who are looking to discover these
      errors, as well as some of the programming techniques for making bugs easier to find.
Take JavaScript
Part III   to the Next
           Level
This page intentionally left blank
Debug JavaScript
Chapter 13   Programs
282      How to Do Everything with JavaScript


      How to…
          ■ Understand JavaScript error messages
          ■ Add debugging code to your programs
          ■ Use the JavaScript console
          ■ Use a JavaScript debugger

      There is nothing more frustrating for a web surfer than to arrive at a web page and immediately
      be presented with error messages. The visitor will likely be wary of proceeding any further into
      the site and is less likely to want to return.
           Ensuring that the JavaScript scripts on your web page help your visitors rather than annoying
      them could be as simple as testing your web page using a variety of browser types, operating systems,
      and version numbers. Yes, it does sound like a lot of work, but there is no substitute for actual
      testing if you want to make sure your viewers will be happy with what you’ve done on the site.
           But what would you do if a web page you were working on displayed an error message? Or
      perhaps your code wasn’t working the way you had expected—or wasn’t working at all. How
      would you go about finding the source of the problem and fixing it? Several tools are available
      to help JavaScript developers with this task, and in this chapter we will discuss how to debug
      JavaScript programs.


 Understand the Possible Causes of Errors
      Finding an error message while you are testing a web page is like finding a $5 bill on the sidewalk—
      it’s worth the time to stop and pick it up. Not only does the error message tell you that there
      was a problem, it also shows you the first place you should look for the problem and even gives
      a brief description of what went wrong.
           Of course, the browser is only giving you its best guess about what the error might be. When
      you actually look at the code and figure out the problem, you might find that the error message
      hadn’t pinpointed the problem exactly. That’s understandable, since some errors have so many
      possible causes that it would be impossible for a computer to choose the correct one.
           Different browsers have different ways of reporting errors, and it is even possible to turn error
      reporting off. For instance, in IE, with error reporting turned on, a JavaScript error will cause the
      following message box to appear:
CHAPTER 13: Debug JavaScript Programs                283

    Even with error reporting turned off, IE still gives you a visual hint that the page did not
load successfully. An error icon will be placed in the lower left-hand corner of the browser
window, like so:




   Netscape always hides JavaScript errors from end users—it won’t even tell you that one
occurred. You’ll need to load the JavaScript Console, which is discussed later, in the section
“Use the JavaScript Console,” to see what if anything went wrong.
   There are three basic types of errors in JavaScript:
    ■ Syntax errors Errors in the basic programming syntax of the language, such as
        mismatched quotes or brackets
    ■ Run-time errors Errors that can be detected only at run time, such as attempting to
        use variables that do not exist
    ■ Logic errors Errors in your programming logic or algorithms that cause an incorrect
        result, such as a loop that exits one iteration too early
    Any of these types of errors can cause JavaScript to either stop running or return an incorrect
result. There are dozens of possible reasons why an error would occur inside a JavaScript 1.5
program, including:
    ■   Calling a function or using a variable that is undefined
    ■   Attempting to modify the value of a constant
    ■   Passing a string to a function or operator that expects a number
    ■   Passing an incorrect number of parameters to a function
    ■   Using an unescaped quotation mark inside a string                                                13
    ■   Using statements such as the for loop incorrectly
    Although JavaScript 2.0 attempts to retain the flexibility of previous versions, some of the
new features have the potential to introduce new problems. In addition, JavaScript 2.0 gives
programmers the option to enforce a stricter level of error checking (called strict mode). Potential
errors for JavaScript 2.0 programs include:
    ■   Assigning an incorrect data type to a variable that’s expecting another data type
    ■   Trying to access variables or functions defined as private
    ■   Namespace issues
    ■   Running JavaScript 2.0 in a browser that only supports JavaScript 1.5
    I have always felt that finding and fixing errors is like unraveling a mystery. You start with
only a few clues and, with good detective work and perhaps a little luck, you eventually figure
out exactly what went wrong.
284      How to Do Everything with JavaScript



                             Turn on Error Reporting in IE

        Internet Explorer has two advanced options that affect the way JavaScript errors are reported
        and handled. The Advanced Options menu can be found by selecting Internet Options from
        the Tools menu and selecting the Advanced tab.
            On this tab, the first option setting we are concerned with is called “Display a notification
        about every script error.” This should be enabled in order to see the JavaScript error messages
        we are talking about in this chapter.
            The other option that may affect us is called “Disable script debugging.” Depending on
        the software installed on your computer, IE may give you the option of loading the web page
        into a tool called a debugger to find out more about the problem.
            Generally, this option should be enabled; that is, you do not want to be given the option
        to view the code in a debugger. (However, if you really do want to go into a debugger for
        every error and you have some experience in that software, then by all means disable the
        debugging option.)



      Find the Source of an Error Message
      When JavaScript encounters an error inside a script and the program does not handle it, then the
      user is notified of the error by an error message box. In IE, the details of the error are usually
      hidden, since they can be overly technical to the novice user. Instead, a somewhat friendlier
      message like the following is displayed.




          By clicking the Show Details button we can see some of the technical details about the
      particular error.
CHAPTER 13: Debug JavaScript Programs                   285




    IE gives programmers a number of important details regarding the source of the error:

    ■ Line       The line number where JavaScript first noticed the problem. This is not always
        the line that contains the problem, although it usually is. Having a text editor that shows
        line numbers will save you from having to manually count them out. Windows Notepad
        on XP can view line numbers by turning on the status bar (View | Status Bar).
    ■   Char      The character number on the line where the problem might lie.
    ■   Error A string that tries to describe what JavaScript believes went wrong.
    ■   Code Some errors have an error code attached to them.
    ■   URL The web address of the HTML file that had the problem, in case there was
        any doubt.
         The line number listed in an error message includes any HTML lines that precede the                  13
         script, unless the script exists in a file by itself (an external script) in which case it is
         the actual line number of the script file.

    The line number referenced in the details of the error message is usually the best place to start
looking for an error. You also want to read the description of the error provided by the message
box, since that gives you the second clue needed to solve this mystery.

Interpret Error Messages
Perhaps the best way to see how closely (or not) the JavaScript error message relates to the actual
source of the error is to look at an example. In this section, we will examine a piece of JavaScript code
that has a serious bug in it and see how the two major browsers (Netscape and IE) report the error.
286      How to Do Everything with JavaScript


          To start the exercise, let’s take a look at the following HTML and JavaScript code.
      <html>
          <head><title>Interpreting error messages</title></head>
          <body>
          <script language="JavaScript" type="text/javascript">
          function add (input1, input2) {
              return input1 + input2;
          }

          var result = ad (1, 2);
          </script>
          </body>
      </html>

          When we first run this code, we expect that after the add() function is called with the values
      1 and 2, the result returned would be 3. Instead, we encounter a JavaScript error. IE gives the
      rather cryptic message “Object expected.”




      But it does give us a line number. Remember, the line number includes all the HTML code before
      the script on the web page. The ninth line of code points to a problem with the following line:
           var result = ad (1, 2);

          The Netscape JavaScript console does a better job of describing the error—although, as
      discussed earlier in this chapter, you have to open the console window in order to know that
      one exists. The console reports, more usefully, “ad is not defined.”
CHAPTER 13: Debug JavaScript Programs                  287




      With careful examination, we can see that we have mistyped the name of the function; it
   should be add(), instead of ad(). Correcting the typo makes the error go away in both browsers.


Use a JavaScript Validator
   One way to check your JavaScript code for strange bugs is to run it through a program that checks
   it to make sure it is valid—that it follows the official syntax rules of the language. These programs
   are called validating parsers, or just validators for short, and often come with commercial HTML
   and JavaScript editors.
            One limitation some validating parsers have is that they can only understand JavaScript
            language components that are part of the official ECMAScript specification. Some of these
            tools do not understand DOM function calls or some of the extensions to the language
            added by browser manufacturers that are not part of the ECMAScript specification.

       Perhaps the most convenient validator for JavaScript is Douglas Crockford’s JavaScript Lint,
   which is available free online at http://www.crockford.com/javascript/jslint.html. Simply visit
   that web page, paste your JavaScript code into the text area provided, and click the jslint button.
                                                                                                              13
   Voilà! The results appear onscreen in seconds.
       JavaScript Lint will parse through your JavaScript code, ensuring that any variable and
   function definitions follow the correct syntax. It will also check JavaScript statements, such as if
   and while, to ensure they too follow the correct format. This program will not catch all the errors
   in your JavaScript programs, but it will catch the obvious ones, such as missing brackets or undefined
   variables and functions.


Add Debugging Code to Your Programs
   Often when a JavaScript script is not producing the desired results it’s not obvious why the
   problem exists. For instance, you may be expecting that after a series of mathematical operations
   a variable is going to come back with a specific value—but it doesn’t. There won’t be any JavaScript
288       How to Do Everything with JavaScript


      error messages to help you find the line that is causing the problem, and even a JavaScript validator
      may not be of any use.
          One thing programmers can do to help themselves is to add some debugging code to the
      program. Debugging code is code that exists purely to help the developer figure out what is going
      on behind the scenes while code is being modified. You would usually remove or comment out
      the debugging code once regular visitors to your page are using the script.
          Programmers commonly use the alert() or document.write() methods when adding debugging
      code to a program. For instance, the following script has a number of additional alert() message
      boxes that will give the developer an idea of what is going on inside the program.
      // Converts a number from "9999999" to "9,999,999"
      function convert_number(input) {
          var counter, output;

            alert("input = " + input);
            alert("input length = " + input.length);

            // Not long enough to get commas
            if (input.length < 4) return input;
            alert("length larger than 3");

            // Empty output
            output = "";

            // Loop through input string, three chars at a time
            for (counter = input.length-3; counter > 0; counter -= 3) {
                output = "," + input.substr(counter, counter+2) + output;
                alert("counter = " + counter + ", output = " + output);
            }

            // Final set of numbers
            output = input.substr(0, counter+3) + output;
            alert("counter = " + counter + ", output = " + output);

            return output;
      }

           In the preceding code, all the calls to the alert() message box are used for debugging purposes
      only. Their sole purpose is to provide the programmer with some clues about what is going on
      inside the function: what the original value is, what happens after each iteration of the loop, and
      the final result.
CHAPTER 13: Debug JavaScript Programs                 289




   Again, once we are satisfied this function is working properly, we should remove or
comment out those alert boxes to save our visitors from a lot of unnecessary mouse clicks.
   A similar debugging technique involves the careful and incremental use of comments.
   Let’s say you have a JavaScript function that does not appear to be working correctly.
You have looked over the source code, and cannot figure out the source of the problem.
// Converts a number from "9999999" to "9,999,999"
function convert_number(input) {
    var counter, output;

     if (input.length < 4) return input;
     output = "";

     for (counter = input.length-3; counter > 0; counter -= 3) {
         output = "," + input.substr(counter, counter+3) + output;
     }
     output = input.substr(0, counter+3) + output;
     return output;
}

    1. Start by commenting out the contents of the entire function. If the function is supposed
       to return a value, force it to return a hard-coded value that simulates what you are expecting.     13
       Test the script to make sure it is now working correctly with the hard-coded value.
        // Converts a number from "9999999" to "9,999,999"
        function convert_number(input) {
        //    var counter, output;
        //
        //    if (input.length < 4) return input;
        //    output = "";
        //
        //    for (counter = input.length-3; counter > 0; counter -= 3) {
        //        output = "," + input.substr(counter, counter+3) + output;
        //    }
290      How to Do Everything with JavaScript

              //      output = input.substr(0, counter+3) + output;
              //      return output;

                   // ** Hard-coded return value **
                   return "1,234,567";
              }

         2. Next, uncomment a few of those lines. For instance, make the function return its input
            string instead of the hard-coded value. Again, test that this expected result (the input
            string) is working correctly.
              // Converts a number from "9999999" to "9,999,999"
              function convert_number(input) {
                  var counter, output;

                   if (input.length < 4) return input;
                   output = "";

              //      for (counter = input.length-3; counter > 0; counter -= 3) {
              //          output = "," + input.substr(counter, counter+3) + output;
              //      }
              //      output = input.substr(0, counter+3) + output;
              //      return output;

                   // ** Return the input value **
                   return input;
              }

         3. Carefully uncomment more lines from the script. Know in advance what you expect the
            return value to be after each set of comments is removed, and then retest.
         4. Repeat step 3 as necessary. At some point, you will discover that the return value is not
            the value you expected. The most recently uncommented lines are the most likely source
            of the problem!

         Adding debugging code and using comments are two of the most useful techniques for
      manually figuring out the source of errors inside scripts.


 Use the JavaScript Console
      The Netscape and Mozilla browsers include a useful utility called the JavaScript console. The
      JavaScript console opens in its own window, and this is the place where Netscape outputs
      any JavaScript errors it encounters. The console will continue to accumulate error messages
      from web pages until the browser is closed or the console is cleared manually.
CHAPTER 13: Debug JavaScript Programs                   291




    FIGURE 13-1       The Netscape console shows JavaScript errors.


       To access the console in Netscape 7, go to Tools | Web Development, and choose JavaScript
   Console. (In Netscape 6, the JavaScript Console option is located in Tasks | Tools.) The console
   is empty when the browser is first opened, but will accumulate error messages as they occur for
   many different pages and sites as you surf.
       The console also allows developers to input JavaScript code for the browser to execute.
   Simply type the variable name into the console, click Evaluate, and the console will tell you
   the last value for that variable. Or you can have JavaScript manually call a function by typing
   in the function name along with any parameters.                                                             13
       Figure 13-1 shows what the console looks like in the Netscape 7 web browser.


Use a JavaScript Debugger
   The final weapon in the programmer’s arsenal against bugs is to use debugging software. A
   debugger is a program that gives you complete access to the internal workings of the application.
   A JavaScript debugger will typically include a user-friendly interface and will allow a developer
   to step through the script one line at a time. The developer can see the current value of any variables
   and get more detailed feedback in order to help them find the true source of a bug.
        Debuggers are typically shipped inside HTML and JavaScript editors. For example, Microsoft
   FrontPage 2002 contains a JavaScript editor and debugger called Microsoft Script Editor. Macromedia
   Dreamweaver also contains a JavaScript debugger in its Dreamweaver MX product. There are
   also a number of third-party editors that contain debuggers, such as C Point’s JavaScript Editor
   (http://www.c-point.com).
292      How to Do Everything with JavaScript


          For those who don’t use a professional HTML editor, a number of free JavaScript debuggers
      are also available. Most prominent among them is the JavaScript Debugger available from the
      open-source Mozilla project.
          As you may know, the Netscape and Mozilla web browsers are based on the same core set of
      source code. Netscape, however, does not include the JavaScript Debugger with its version, while
      Mozilla does. So developers who use the Netscape 7 (and later) browsers will need to download
      and install the debugger as a separate tool.
              The latest Netscape web browser is available for download from http://
              www.netscape.com. The latest version of the Mozilla JavaScript Debugger
              (code-named Venkman) for both Mozilla and Netscape browsers can be
              downloaded at http://www.hacksrus.com/~ginda/venkman.

          The Mozilla JavaScript Debugger is available on multiple operating systems (specifically
      Windows, Mac OS, and Unix), and does a great job helping developers step through their
      JavaScript programs. We can see a screenshot of this debugger in Figure 13-2.




       FIGURE 13-2     Stepping through a JavaScript program using the Mozilla debugger
CHAPTER 13: Debug JavaScript Programs                293

         To access the JavaScript Debugger in Mozilla 1 or Netscape 7, go to the Tools |
         Web Development menu, and choose JavaScript Debugger.

     Microsoft also provides a free debugger, the Microsoft Script Debugger. It is available for
download at http://www.microsoft.com/script/debugger. Script Debugger supports many of the
key debugger features, such as the ability to view and step through code, set breakpoints, and
view and change variable values.
     No matter which browser you use, you are bound to find the ability to step through complex
JavaScript programs very useful. For small scripts, adding debugging code may be all you need
to find problems. But when your program contains a lot of functions and you need some of
the advanced debugging features such as breakpoints, a good JavaScript debugger can be the
programmer’s best friend.
     The next chapter deals with some of the important concepts around using try-catch statements
to intercept system errors before the browser does. You will also see how to use exceptions in your
own programs.




                       What a Breakpoint Is

  In debugging, a breakpoint is a line of code designated by the programmer as the point where
  the debugger will pause (or break) the program. The programmer can perform a number of
  tasks inside the debugger before letting the program continue executing.
       The benefit of having a debugger that supports breakpoints is that instead of having to
  step through every single line of code in a script manually, you can let the debugger execute
  all lines automatically until it reaches its first breakpoint. Once you have checked the contents
  of some data variables, you can either step through the program manually or let it run
                                                                                                        13
  automatically until it reaches the next breakpoint.
This page intentionally left blank
Make Your
Chapter 14   Program
             Errorproof
296      How to Do Everything with JavaScript


      How to…
          ■   Understand exceptions and how they are caused
          ■   Catch exceptions using the try and catch statements
          ■   Create exceptions using the throw statement
          ■   Design programs that are easy to debug from the start

      Designing and developing programs that are immune to errors is a difficult task when using
      programming languages such as Visual Basic and Java. But it is in some ways even more
      difficult when working with JavaScript.
           One of the reasons this is true is that, as a scripting language, JavaScript is generally
      distributed as source code. In normal circumstances, there is no compiler to catch syntax errors
      before users see the final program in action. With other languages, the compilation step provides
      a layer of protection against certain types of errors.
           Another reason for the difficulty is that JavaScript is often developed using nothing more
      than a basic text editor. Languages such as Visual Basic are created using integrated development
      environments (IDEs) that help developers create better code and include built-in debuggers.
           And yet another reason is that the number of target environments (browsers and operating
      systems) is so diverse—literally dozens of combinations—that it becomes practically impossible
      to test the program in all the possible environments.
           But there are some techniques developers can use to make sure the JavaScript programs they
      create will work properly in as many environments as possible. In this chapter, we will examine
      some of the most practical ways to ensure programming success.


 Learn the Basics of Exceptions
      In the early days of web programming, when JavaScript encountered a error while executing a
      program the result was always fatal: the browser would stop executing the code and report the
      error to the user. In effect, errors were always reported directly to the browser—the application
      had no opportunity to try and handle the error itself. You can imagine how impossible it was to
      create an errorproof program when you couldn’t even detect when an error occurred.
          In addition, JavaScript developers had to invent their own ways of returning errors back to
      the program. Take the following example:
      function simple_addition(a, b) {
          // This function will add two numbers,
          //    but only if they both are between 0 and 9
          if (a < 0 || a > 9) {
              return "First number is not between 0 and 9.";

           } else if (b < 0 || b > 9) {
CHAPTER 14: Make Your Program Errorproof                297

              return "Second number is not between 0 and 9.";

        } else {
            return a + b;

        }
   }

       Every place inside the program that made a call to this function had to have several extra
   lines of code (more if statements) to check the return value to see whether an error occurred
   before using the number. Other programmers might solve the same problem differently, with
   special return codes (like using the value –1) to return an error.
       JavaScript uses exceptions to pass system errors back to the program for handling. In
   addition, JavaScript programmers can use the same system of exceptions inside their code to
   return application-specific errors back from functions. For example, we can rewrite the source
   code from the previous example to use exceptions instead, by using the throw statement.
   function simple_addition(a, b) {
       // This function will add two numbers, but only if they are less than 10
        if (a < 0 || a > 9) {
           throw "First number is not between 0 and 9.";

        } else if (b < 0 || b > 9) {
            throw "Second number is not between 0 and 9.";

        } else {
            return a + b;

        }
   }

       You will learn more about the statements that deal with creating and capturing exceptions in      14
   the next two sections.


Catch Exceptions Using the try and catch Statements
   The try-catch statement was introduced in JavaScript 1.4; it is modeled on similar statements
   in Java and C++. When JavaScript encounters a try-catch statement in code, it will begin to
   execute the block of code contained inside the try clause. If any of the statements inside that
   block cause an exception to occur, JavaScript will not execute any of the remaining statements
   inside that block and will jump immediately to the code contained inside the catch clause. Of
   course, if no exceptions occur inside the try clause, the code inside the catch clause will never
   be executed.
298      How to Do Everything with JavaScript


          The following code shows how the try-catch statement can be used to protect the code from
      exceptions.
      var isIE = (navigator.userAgent.indexOf("MSIE")) > -1;

      try {
          var a = 1;
          var c = a / b;
          alert("The result of a / b is " + c);
      }
      catch (e) {
          var msg = "JavaScript encountered the following error:nn";
          // IE and Netscape pass errors differently to the catch clause
          if (isIE) {
              msg += e.description;
          } else {
              msg += e;
          }
          alert (msg);
      }

               IE and Netscape each has its own way of passing errors to the catch clause. IE passes
               the error as an Error object—in order to get the actual error message you have to
               access one of the properties of that object. Netscape passes the error as a string, which
               can be used like any other string.

          The preceding code attempts to use an undefined variable, b, inside the try block. As soon
      as our code attempts to use that variable in an expression, an exception occurs, and the rest of the
      code inside the block does not execute. The error message generated by the catch clause for IE
      looks like this.




         Netscape encounters the same error when executing the code inside the try block. Its error
      message is worded slightly differently, however:
CHAPTER 14: Make Your Program Errorproof                     299




Understand Exception Bubbling
The try-catch statement can also capture errors generated inside function calls within the try
clause. For instance, say we were to move some of the code from the previous example into
a function of its own.
var isIE = (navigator.userAgent.indexOf("MSIE")) > -1;

function calculate() {
    var a = 1;
    return a / b;
}

try {
    var c = calculate();
    alert("The result of a / b is " + c);
}
catch (e) {
    var msg = "JavaScript encountered the following error:nn";
    // IE and Netscape pass errors differently to the catch clause
    if (isIE) {
        msg += e.description;
    } else {
        msg += e;
    }
    alert (msg);
                                                                                                             14
}

    The try-catch statement will still receive notification of the error, even though it occurs inside
the calculate() function. This is because exceptions, like events, bubble. Exception bubbling is the
term that is used to describe the process of how an exception will seek out the first try-catch
statement eligible to handle it. If there is no try-catch statement immediately surrounding the
line of code with the error, control will jump back to the code that called the function containing
the error. If there is no try-catch there, control will jump back to the code that called it, and so on,
until either a try-catch is found or the browser handles the exception by displaying it to the user.
300      How to Do Everything with JavaScript


          For example, the following code generates an error after several levels of function calls
      have been made. The exception still manages to make its way back to the try-catch statement
      surrounding the first function call.
      var isIE = (navigator.userAgent.indexOf("MSIE")) > -1;

      function fn1 () {
          // The first function (fn1) calls the second (fn2)
          fn2();
      }

      function fn2 () {
          // The second function (fn2) calls the third (fn3)
          fn3();
      }

      function fn3 () {
          // The third function (fn3) calls the fourth (fn4)
          fn4();
      }

      function fn4 () {
          // The fourth function (fn4) calls the fifth (fn5)
          fn5();
      }

      function fn5 () {
          // The fifth function (fn5) contains an error
          return some_undefined_variable;
      }

      // MAIN program
      try {
          fn1();
      } catch (e) {
          var msg = "JavaScript encountered the following error:nn";
          // IE and Netscape pass errors differently to the catch clause
          if (isIE) {
              msg += e.description;
          } else {
              msg += e;
          }
          alert (msg);
      }
CHAPTER 14: Make Your Program Errorproof                 301

    As you can see from the following screenshot, both Netscape and IE are able to pass the
exception properly to our catch clause.




        You do not always have to respond to an exception by displaying a message to the user.
        You could always ignore the error and continue.

Use the IE Error Object
As we observed in the previous section, Internet Explorer passes an Error object to the parameter
of the catch clause. The Error object contains two properties:

   ■ number A numeric value related to the error
   ■ description A string describing the error
        The code in this section will work only in Internet Explorer.


    IE automatically creates an Error object whenever an exception occurs, but you are also free
to create your own error using the following new statement syntax:
var myerr = new Error (1000,
            "Value falls outside acceptable range of 0-81.");

   Using this object allows your program to easily distinguish between different types of errors
while also retaining the plain-English description to display to the user.                            14
// Error 1000: Ignore, set return code to 0
if (e.number == 1000) {
    var returncode = 0;

// Error 1001: Exit loop, set return code to 9999
} else if (e.number == 1001) {
    var returncode = 9999;

// Other error code: Can't handle this, report to user
} else {
     alert(e.description);
}
302      How to Do Everything with JavaScript


         The only real problem with this method is that Netscape uses a different approach, which
      means you have to have browser-sniffing code in order to create cross-platform-compatible code.

      Use Netscape-Only catch Clauses
      Netscape has a special syntax for catch clauses that allows for more than one of them to exist in
      a try-catch statement. Netscape calls them conditional catch blocks.
               IE does not support this syntax, and it is not part of the official ECMA standard.


          Basically, Netscape allows developers to insert an if keyword to determine which catch
      block is called after an exception is thrown:
      try {
          var input = get_user_input();
          edit_check (input);
      }
      catch (e if e == "Value too high") {
          // What do we do when the user enters a value that is too high?
          // ...
      }
      catch (e if e == "Value too low") {
          // What do we do when the user enters a value that is too low?
          // ...
      }
      catch (e if e == "No value entered") {
          // What do we do when the user does not enter a value?
          // ...
      }
      catch (e) {
          // Some other error occurred
          // ...
      }

           I recommend that this proprietary method be avoided if at all possible. Since adding an
      if-else statement into a single catch clause can generate the same effect, there is no benefit to
      coding it like this.

      Use Nonstandard finally Clauses
      Java and C++ programmers will recognize the optional finally clause in the try-catch statement,
      although those familiar with the official ECMAScript specification will not. Both Netscape and
CHAPTER 14: Make Your Program Errorproof                  303

IE web browsers support this clause, even though it does not exist in the official standard and
therefore is not supported by all JavaScript environments.
    Basically, the finally clause contains code that will always be executed, regardless of whether
an exception occurs in the try block or not. Even if there are return statements inside the try or
catch clauses (which triggers an exit from the function), the finally clause is guaranteed to run.
         The only time the finally clause will not be executed is if an unhandled exception occurs
         inside the catch clause. An unhandled exception is an exception that has to be handled
         by the browser, since there are no remaining try-catch statements to handle it.

    For example, the following code triggers an exception inside the try clause, and both the
code inside the catch clause and the code inside the finally clause are executed before the control
is passed back outside the function.
function function_that_will_fail() {
    var a = 1;
    var b = 2;
    this_function_does_not_exist(a, b);
}

function capture_error() {

     try {
         document.write("<b>try</b>: ");
         document.write("Calling the function.<br><br>");
         function_that_will_fail();
     }
     catch (err) {
         document.write("<b>catch</b>: ");
         document.write("An error has occurred.<br><br>");
         return;
     }                                                                                                  14
     finally {
         document.write("<b>finally</b>: ");
         document.write("This code is guaranteed to execute.<br>");
     }
}

capture_error();

    As you can see from Figure 14-1, even though there is a return statement inside the catch
clause, the finally clause does indeed execute.
304      How to Do Everything with JavaScript




       FIGURE 14-1     The finally clause gets the last say: exception or no exception.



 Create Exceptions Using the throw Statement
      One thing that makes the try-catch statement more useful is the throw statement. The throw
      statement allows developers to create their own exceptions. This means that you can have a
      single set of try-catch statements to capture all system and application errors, which certainly
      saves a lot of coding effort.
          It also allows you to leverage the exception bubbling mechanism in order to pass an error
      message from deep inside a function up to the try-catch statement waiting several function calls
      back. Without this exception bubbling, we would have to write a lot of extra code in order to
      capture errors inside each function and then remember to diligently pass them back up to the
      next level.
          For example, the following code causes an exception to occur. By definition, processing
      inside the function stops immediately, and the exception is passed to the waiting try-catch
      statement one level back.
      function throw_an_error() {
          throw "Ouch! I stubbed my toe!";
CHAPTER 14: Make Your Program Errorproof                    305

}

try {
    throw_an_error();
    document.write("This line will never be executed.");
} catch (myerr1) {
    document.write("The following error occurred: <br>");
    document.write(myerr1);
}

     Notice that I was able to use the myerr1 variable as a string and did not have to include
browser-sniffing code to determine whether or not we need to use the IE Error object. The reason
is that since we used the throw statement to pass a string literal, the catch clause receives only
the string. IE does not automatically create an Error object for you if you choose to throw a string.
     You can, however, create your own Error object and throw it.




                        How to Re-throw an Exception

    When the try-catch statement encounters an exception that it does not want to handle, it can
    use the throw statement to send the exception back to another try-catch defined elsewhere
    in the program. This is called re-throwing it.
         For example, the following code re-throws an error that it is not prepared to handle:
    function calculate_total() {
        try {
            var subtotal = get_item_amount();
        } catch (e) {                                                                                     14
            if (e = "No items remaining") {
                return 0;
            } else {
                // must have been a system error,
                // let JavaScript handle it
                throw e;
            }
        }
    }
306      How to Do Everything with JavaScript

      function throw_an_error() {
          var eobj = new Error ( 0, "Ouch! I stubbed my toe!" );
          throw eobj;
      }

      However, this code works only in Internet Explorer, since there is no Error object in Netscape.
      So with this approach we would need to introduce browser-sniffing code as well.
         The best approach is to throw a string, as you would expect. In the catch clause, test to see
      whether the parameter passed is a string or an object.
      catch (myerr1) {
          if (myerr1 instanceof Error) {
              var errstring = myerr1.description;
          } else {
              var errstring = myerr1;
          }
          document.write("The following error occurred: <br>");
          document.write(errstring);
      }

          The preceding catch clause works in both IE and Netscape and will properly detect whether
      the parameter passed is an Error object or just a string.


 Design Programs That Are Easy to Debug from the Start
      Certain programming styles lead to less bugs (and less debugging hassles), while others have
      the opposite effect. Whenever your JavaScript program looks like it is going to be long and
      complicated, you may save yourself some time and headaches later if you take the right design
      approach from the start.
          We discussed the four programming styles in some detail in Chapter 3:

          ■   Unstructured     Sequence of statements acting on global data
          ■   Procedural     Main program that calls functions to perform certain tasks
          ■   Modular Main program that uses modules to group related functionality
          ■   Object-oriented Main program that uses objects to group related data and
              functionality

          Each of these methodologies has its pros and cons when it comes to writing errorproof
      programs. The unstructured technique is good for small scripts but terrible for large ones.
      Object-oriented is the opposite—good for large programs and poor for short scripts. Having
      a rough idea of the complexity of your program beforehand will help you decide on the best
      approach.
CHAPTER 14: Make Your Program Errorproof                    307

Avoid Unstructured Programming
Unstructured methodology is usually best for short, simple scripts. Essentially, this program consists
of a set of JavaScript statements that do not define or use any functions, modules, or objects.
     In some ways the unstructured technique is the simplest of them all, but when your program
exceeds more than a page or two of code, you should think about breaking it up into more
manageable pieces.
     The biggest problem you’ll encounter with a large program of this type is the complexity
and number of interdependencies in the code. Statements later on in the program will rely on
variables set several hundred lines earlier. Making a change to one part of the program might
break the code in another area.
     Building a program in such a fashion is similar to building a house out of one large piece of
wood. One small adjustment, such as relocating a window, becomes next to impossible without
starting over completely. That is OK only if your house is very small.

Break Code into Manageable Chunks
There’s a reason houses aren’t made in one big piece, but one wall, roof, floor, and staircase at
a time. That way, relocating a window does not affect other walls or other structural elements,
and the worst thing that such an adjustment can do is cause you to have to rebuild a single wall.
Houses are built of separate components, and computer programs generally should be as well.
     The easiest way to “componentize” a program is to organize it into several functions. It
is best if these functions fall into separate areas of responsibility, if at all possible, so that two
or more functions are not working at cross-purposes or doing the same task. For example, the
following code snippet shows how using functions improve program organization and readability:
function groceries () {
    var grocerylist = get_grocery_list();
    drive_to_store();
    for (var item in grocerylist) {
        get_item(item):
    }                                                                                                      14
    pay_cashier();
    drive_home();
    put_food_away();

     return;
}

We could have alternatively used an unstructured program that attempted to do all those tasks in
order. But that program would have been harder to read, test, and make changes to.
308       How to Do Everything with JavaScript


          To test a function, we only need to make sure that it performs the tasks and returns the value
      that is expected of it. Most functions rely on the way the rest of the program is structured, so you
      can never be 100 percent sure that nothing will go wrong. Because functions are easier to test,
      you will find that procedural programming offers a higher sense of reliability than unstructured
      programming does.


      Reuse Code Using Classes and Objects
      The other way to componentize your code would be to break it into a number of classes and
      objects. Classes allow you to separate all related functions and variables into a single module.
      This allows you to create classes that can be easily reused in other applications.
          For instance, you can create a class that represents an item in the user’s online shopping
      cart. Since this item code is generic, the exact same code can be reused in other applications
      that need access to an item, say, an inventory program.

      class Item {
          var SKU : String;
          var productName : String;
          var size : String;
          var color : String;
          var retailPrice : Number;
          var wholesalePrice : Number;

            function Item(inSKU : String, inName : String,
                          inSize : String, inColor : String,
                          inPrice1 : Number, inPrice2 : Number) {
                this.SKU = inSKU;
                this.productName = inName;
                this.size = inSize;
                this.color = inColor;
                this.retailPrice = inPrice1;
                this.wholesalePrice = inPrice2;
            }

            // More methods would follow...
      }

          Classes and objects are much easier to test as well. You would only need to check once to
      make sure the object behaves the way it is expected to. As long as there are no code changes in
      the class, the object can be considered completely tested.
CHAPTER 14: Make Your Program Errorproof                   309

Test Your JavaScript Code Thoroughly
   The final key to ensuring that your program is immune from errors is to perform thorough testing
   on it. Testing involves running the program many different times under many different scenarios
   to make sure it operates as expected.
       For short scripts, testing does not have to be complicated. For instance, testing mouse rollover
   effects may just entail rolling the mouse across an image several times to make sure that it
   toggles as expected. For more complicated scripts, such as those involving DHTML or interframe
   communication, more rigorous testing may be required.

   Create a Testing Harness
   A testing harness is a program whose job it is to help test other programs. In JavaScript
   programming, a testing harness generally takes the form of a custom web page that exposes
   buttons and form fields used for testing the behind-the-scenes scripts.
        Figure 14-2 shows an example of a good testing harness. The web page allows a developer
   or tester to manually trigger certain events or to force-feed certain values to functions embedded
   on the page.




                                                                                                            14




    FIGURE 14-2      Use a testing harness to help test JavaScript programs.
310       How to Do Everything with JavaScript


          To see a testing harness in action, let’s start with a small JavaScript script that we wish to test.
      // This script will validate an e-mail address
      function validate_email (inputstr) {
          // The following complex regular expression pattern checks
          // for a valid e-mail address: user.name@domain-name.com
          var pattern =
              /^[a-zA-Z0-9_-.]+@([a-zA-Z0-9-]+.)+[a-zA-Z]{2,3}$/;

            if (inputstr.search(pattern) > -1) {
                return true;
            } else {
                return false;
            }
      }

           Now we could just choose to use this straight in our program, but it would be a good idea
      to verify that it is completely working before doing so. By creating the following HTML testing
      harness that includes our script, we can test dozens of different e-mail addresses in an easy and
      straightforward fashion.
      <html>
        <head>
          <title>HTML Testing Harness</title>
          <script language="JavaScript" type="text/javascript">

      // This script will validate an e-mail address
      function validate_email (inputstr) {
          // The following complex regular expression pattern checks
          // for a valid e-mail address: user.name@domain-name.com
          var pattern =
              /^[a-zA-Z0-9_-.]+@([a-zA-Z0-9-]+.)+[a-zA-Z]{2,3}$/;

            if (inputstr.search(pattern) > -1) {
                return true;
            } else {
                return false;
            }
      }
            </script>
          </head>
          <body>
          <center>
          <h1>HTML Testing Harness</h1>
CHAPTER 14: Make Your Program Errorproof                 311

    <h2>for E-mail Checker</h2>
    </center>

  <form action="#" method="get">
    E-mail address: <br>
    <input type="text" name="email">
    <input type="button" value="Test"
        onclick="alert(validate_email(document.forms[0].email.value))">
  </form>
  </body>
</html>

    The preceding HTML code exists only to test the JavaScript function validate_email(). It
consists of a simple HTML form that contains a text box and a push button. Using this form,
testers and developers can type in dozens of different test e-mail addresses to verify that our
script is working as expected.
    If this process is repeated with each complex function in a program, you will reduce the
likelihood of users discovering strange behavior when using your web page.

Force Errors to Test Error-Handling Code
One thing that occurs when developers test their own programs is what I call “Sunny Day Syndrome.”
We tend to use only valid dates when functions are expecting a date in a parameter field or use
only numbers when functions expect numeric values.
     But it’s important to see what happens when you send an invalid date (such as “02/29/2005”
or “12/33/2005”) to such a field—or even to try sending something that’s not a date (such as the
string “Boo”). How does your function respond to invalid inputs? How is your error-handling code?
     You might even have to modify the code to force such errors. For example, in the following
code, I have hard-coded an array to be empty in order to see how the code handles empty arrays.
This is only to test the error-handling capabilities of the code that called this function.
function print_listing() {                                                                             14
      var itemarray = get_product_list();

      // BEGIN TESTING:: Empty array added just for testing
      //     Forcing an error
      itemarray = new Array();
      // END TESTING

      for (var item in itemarray) {
          // Rest of code ...
      }
}
312      How to Do Everything with JavaScript


          We only modify the code to see what would happen were something to go wrong. This is
      a very easy way to test for things that rarely happen in real life.

      Try Your Program in Many Different Environments
      After you have used the try-catch statement to capture and handle errors and have designed
      your program in a modular, easy-to-test manner, there is only one thing left to do: system testing.
      System testing is the process of trying a program on all the different software environments it
      could possibly run on.
          JavaScript programs embedded in web pages still need to be checked in several different
      browsers and operating systems in order to be considered errorproof. You might not have that
      many operating systems at your disposal, but it isn’t difficult to download and install two or
      more web browsers so you can at least test your program in those environments.
          It is fairly difficult to get multiple versions of IE running on the same machine, but it can
      be done. It has always been much easier to get several versions of Netscape— all you have to
      do is install them in different directories.
               The web site http://browsers.evolt.org contains a copy of almost every browser ever
               produced. It’s a pretty impressive site. If you ever want to see what the Internet of
               today looks like in Netscape 0.9 , you can download and install it to find out.

          You probably don’t have to test every browser ever produced, but at a minimum you should
      check your scripts using IE 5, Netscape 4 and 7, and Mozilla 1.
          The next chapter is the final chapter of the book. It explores how JavaScript can be used to
      interact with multimedia objects on the page. JavaScript was originally developed to interact
      with Java, but it can also deal with movies and music embedded in web pages.
Use JavaScript to
Chapter 15   Manage Browser
             Plug-Ins
314      How to Do Everything with JavaScript


      How to…
         ■    Insert scriptable objects into HTML web pages
         ■    Include Sun Java applets
         ■    Embed movies and music in web pages
         ■    Use the Microsoft Calendar Control in web pages

      Since its initial release in December 1995, JavaScript has been primarily used for web site
      automation. Tens of thousands of useful scripts have been created for everything from handling
      web site navigation to running online shopping carts. The widespread adoption of JavaScript has
      meant that web pages now display information in a more interesting and dynamic manner.
          Over the years, many companies have created their own technologies to enhance the web
      experience for users even further. These companies have developed and distributed their own
      applications, called browser plug-ins, so that users of the various web browsers can view these
      enhancements.
          There are two standards for creating these browser enhancements: the Netscape Plug-In API
      and Microsoft ActiveX. These two standards are not compatible, so developers must create versions
      of their plug-ins for both. Throughout this chapter, I will refer to components developed under
      either architecture as “plug-ins,” for the sake of convenience.
          As you may have guessed from the way the two standards are named, browsers based on the
      Mozilla engine (including Netscape browsers) only support the Netscape Plug-In API standard,
      and Microsoft Internet Explorer only supports the ActiveX standard. Plug-in developers often
      need to support both types of plug-ins, since the browser companies do not appear to be settling
      on any one standard.
              You can download many ActiveX controls for IE from http://activex.microsoft.com.
              At http://home.netscape.com/ plugins Netscape also provides a place to download
              plug-ins.

          There are literally dozens of plug-ins available for download, and some browsers ship with
      several of the popular ones already loaded. The following list contains some of the most popular
      plug-ins and the URLs where they can be downloaded:

         ■    Macromedia Flash, http://www.macromedia.com/software/flash
         ■    Macromedia Shockwave, http://www.macromedia.com/software/shockwaveplayer
         ■    Sun Java, http://sun.java.com
         ■    RealNetworks RealOne Player, http://www.real.com
         ■    Apple QuickTime, http://www.apple.com/quicktime
         ■    Microsoft Windows Media Player, http://www.microsoft.com/windows/windowsmedia
CHAPTER 15: Use JavaScript to Manage Browser Plug-Ins                   315

       Users are required to install plug-ins in order to view some content because browsers only
   know how to display two types of content without help: text and images. For web pages that
   include other types of content, such as movies, music, and 3-D virtual reality models, browsers
   must rely on external plug-ins to handle the content.
       In this chapter, we will examine how to add these different types of content to a web page
   and how to use JavaScript to control them. From Java applets to ActiveX controls, we’ll see
   how JavaScript can call the methods and functions that those objects provide.


Insert Scriptable Objects into HTML Web Pages
   Web browsers treat content managed by plug-ins as they would any other content on the web
   page—like an object. The movies, music, and Java applets embedded on a page become one
   more node in the Document Object Model hierarchy. Since they often also provide properties
   and methods that can be manipulated by JavaScript, we call them scriptable objects.
       There are three HTML tags that are able to add these scriptable objects to a web page:

       ■ <applet>
       ■ <embed>
       ■ <object>
       Of the three, only <object> is part of the official HTML standard. Both <applet> and
   <embed> have been available in web browsers since Netscape 2, but the Internet standards body
   had decided that those tags were ill conceived, and instead encourages web developers to use the
   alternative <object> element.


Include Sun Java Applets
   Java is an easy-to-use programming language that is used by many different types of developers—
   from serious corporate types to the home user. The Java Virtual Machine (JVM) was one of the
   first plug-ins ever released, and it was actually included with the Netscape Navigator 2 web
   browser. A version of the JVM is available for dozens of platforms, including:

       ■   Cell phones                                                                                      15
       ■   Personal digital assistants (PDAs)
       ■   Web browsers
       ■   Personal computers that run Microsoft Windows XP, Apple Mac OS, Linux
       ■   Business computers that run Sun Solaris, Microsoft Windows 2000, Unix

       Applets are small Java programs that are designed to run inside a web browser. On the
   Internet today, applets are frequently used to provide stock tickers, interactive charts and graphs,
   crossword puzzles, and chat rooms.
316      How to Do Everything with JavaScript


         To see how easy it is to include Java applets in a web page, let’s look at a simple example of
      some Java code. The following code needs to be saved in a text file named HelloWorld.java:
      /* My first Java program */

      import java.applet.Applet;
      import java.awt.Graphics;

      public class HelloWorld extends Applet {
        public void paint(Graphics g) {
          g.drawString("Hello world!", 75, 75);
        }
      }

          Since Java programs are compiled, we first need to run this code through a compiler before it
      can be used inside a web browser. The process of compiling turns a plain-text .java code file into
      a binary .class file. This .class file can be executed on any computer with a JVM, since binary
      Java files are platform-independent code that does not rely on a specific operating system.




          In HTML, Java programs are added to a web page using the <applet> tag. Although <applet>
      is not part of the official HTML 4.01 specification, both Netscape and IE support it. For example,
      the following HTML embeds a Java applet into a web page:
      <applet code="HelloWorld.class"
              width="250"
              height="150"
              id="myapplet">
      </applet>
CHAPTER 15: Use JavaScript to Manage Browser Plug-Ins             317


                       Download the Java SDK

  Sun Microsystems provides several pieces of its Java platform free to anyone who wants to
  download them, including the JVM (which is part of the Java Runtime Environment, or JRE)
  and the Java compiler (which is part of the Java Software Development Kit, or SDK).
      In order to ensure you have the latest JVM, head over to the Sun Java web site at
  http:// java.sun.com/getjava/index.html. That page will make sure your web browser has
  the latest version of Java installed and ready to go.
      If you would like to download a compiler so that you can try your hand at creating
  Java applets, you can download your own SDK for free from http://java.sun.com/j2se/
  downloads.html. There are several good tutorials available on the Sun Java web site
  to help you create your first Java program.



    Using this HTML code, the web browser will attempt to load the Java applet called
HelloWorld.class and will reserve an area on the screen for it that is 250 pixels wide by
150 pixels tall.
    You can see how this Java applet will look in the web browser in Figure 15-1.
    The HTML <applet> tag has a number of optional attributes that can be used to further
define the applet’s properties inside the browser. Table 15-1 lists these attributes.



 Attribute        Purpose
 code             The class file name
 codebase         The class file subdirectory
 archive          The name of the .zip file containing the class file
 alt              Text that should be displayed by browsers that don’t support the <applet> tag
 align            How the applet should be aligned with text and images placed beside it            15
 height           The height of the applet in pixels or as a percentage
 width            The width of the applet in pixels or as a percentage
 hspace           The amount of horizontal space to reserve around the applet in pixels
 vspace           The amount of vertical space to reserve around the applet in pixels
 mayscript        Permits the applet to access JavaScript
 name             The name of the applet to be used in the DOM
 TABLE 15-1     Attributes of the HTML <applet> Tag
318      How to Do Everything with JavaScript




       FIGURE 15-1     A simple Java applet inserted into a web page


          Web page developers also have the option of passing in several parameters to the Java applet
      to help customize it using the HTML <param> tag. For instance, we can modify our Hello World
      Java applet to accept one parameter:
      /* My first Java program */

      import java.applet.Applet;
      import java.awt.Graphics;

      public class HelloWorld extends Applet {
        String displayString;

        public void init() {
          // We are expecting a <param> named "display"
          displayString = getParameter("display");
CHAPTER 15: Use JavaScript to Manage Browser Plug-Ins                  319

    }

    public void paint(Graphics g) {
      g.drawString(displayString, 75, 75);
    }
}

    We can then use the HTML <param> tag inside the <applet> tag to pass a customized string
to display to the applet, like so:
<applet code="HelloWorld.class"
        width="250"
        height="150"
        id="myapplet">
    <param name="display" value="This is my applet!">
</applet>

     Using this new parameter, we can change the string our Java applet displays without having
to recompile the code. An applet can accept multiple parameters, so your Java applet can be
designed to be completely configurable from outside the compiled code.

Connect to Java Applets Using JavaScript
As you would expect, JavaScript is able to call the public methods and set the public properties
of any Java applet. The Java applet we created in the last section already has a number of public
properties and methods, some of which are automatically provided by HelloWorld’s parent
class—Applet.
    We can create a small JavaScript function that will modify the string being displayed and
force the applet to refresh by calling the appropriate public properties and methods, as follows:
<script language="JavaScript" type="text/javascript">
function displayString() {
    var applet = document.getElementById("myapplet");
    applet.displayString = "String is set here";
    applet.repaint();                                                                                    15
}
</script>

    This JavaScript function starts by creating a variable that will point to the Java applet on our
HTML web page using the familiar document.getElementById() function.
    We then modify the displayString property, which was defined inside the HelloWorld Java
applet. In order to get Java to display our new string to the screen, we have to call the applet’s
repaint() method.
320      How to Do Everything with JavaScript


          Of course, it would also be helpful to display a small button or other user control in order to
      trigger this JavaScript function with an onclick event.
      <applet code="HelloWorld.class"
              width="250"
              height="150"
              id="myapplet">
          <param name="display" value="This is my applet!">
      </applet><br><br>

      <form action="#">
      <input type="button" value="Modify Applet"
          onclick="displayString()">
      </form>

          This HTML code will add a small push-button control underneath the applet window.
      Clicking the button will cause the string displayed by our applet to be altered, as you can see
      in Figure 15-2.




       FIGURE 15-2      The applet has been modified as a result of our JavaScript function.
CHAPTER 15: Use JavaScript to Manage Browser Plug-Ins                 321

Embed Movies and Music in Web Pages
   Embedding movies and music in web pages is handled quite differently from embedding Java
   applets. First, the <applet> tag cannot be used to embed these types of files into a web page
   (unless you use a Java applet to display them, of course).
       The first way to insert a multimedia file into a web page is by using the <embed> tag. Using
   the <embed> tag is certainly easier than using the <object> tag, but when using it, remember
   that <embed> is not part of the official standard.
   <embed src="myMovie.avi" autostart="true" loop="true"
       width="160" height="120"></embed>

        With the <embed> tag, you pass all the parameters to the plug-in using attributes inside the
   tag itself. There is no <param> tag for <embed>. The <embed> tag supports three parameters
   for itself—src, width, and height. The source URL for the embedded content is passed using
   the src attribute. The amount of space reserved inside the browser is passed using the width
   and height attributes.
            Your computer would need a browser plug-in that could handle Windows AVI files in
            order to see the movie in our example. Most of the popular video players can, however,
            including Windows Media Player, Apple Quicktime, and RealNetworks RealOne Player.

       In the preceding example, the plug-in that is responsible for playing the movie is being
   passed the autostart parameter, as well as the loop parameter. It is up to the plug-in software,
   of course, to interpret what they mean and what to do with them.
            IE is currently the only browser that supports ActiveX controls such as Windows
            Media Player.

       We can also use the official <object> tag to embed the movie in our web page. The <object>
   tag is slightly more complex, particularly since plug-ins are referred to using an extremely long
   hexadecimal number.
   <object id="ActiveMovie1"
    classid="CLSID:05589FA1-C356-11CE-BF01-00AA0055595A"
    width="320" height="240">
                                                                                                          15
       <param name="ShowDisplay" value="1">
       <param name="ShowControls" value="1">
       <param name="AutoStart" value="1">
       <param name="PlayCount" value="10">
       <param name="FileName" value="myMovie.avi">
   </object>

        The preceding HTML code inserts an object using the Microsoft ActiveMovie control, which
   is identified using that long classid attribute. ActiveMovie is the ActiveX control installed with
322      How to Do Everything with JavaScript



                             Embed a Windows Media Player 9
                             Object in a Web Page
        With the release of Windows Media Player 9, Microsoft has further enhanced the capabilities
        of its video and music playback application. Windows Media Player 9 also includes an
        ActiveX control that allows developers to embed music and movies in web pages.
             However, since not everyone has had an opportunity to upgrade to this new player yet,
        it might be better not to force your visitors to download it in order to see your content. But
        if you can be reasonably sure that your audience already has this software installed, you can
        easily include this new <object> tag in your web pages.
             Notice in the following HTML code that the classid value is different, as is the name of
        the parameter used to specify the name of the media file.
        <object id="Player" height="0" width="0"
         classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6"
         width="160" height="120">
            <param name="URL" value="myMovie.avi">
        </object>



      Microsoft Windows Media Player 6.4 that manages the details of the display and playback
      of movies. Developers can pass the ActiveMovie control several properties to control the size,
      volume, balance, and position. You can see an example of the ActiveMovie control in Figure 15-3.
           If we do not want to rely on Windows Media Player to play our movie, we can use the classid
      attribute belonging to the Apple Quicktime Player, as follows:
      <object id="QuicktimeMovie1"
          classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
          width="320" height="240"
          codebase="http://www.apple.com/qtactivex/qtplugin.cab">
          <param name="src" value="myMovie.avi">
          <param name="autoplay" value="true">
          <param name="controller" value="false">
      </object>

         The preceding code will use the Apple Quicktime Player plug-in instead to display our
      movie. Again, this will only work in web browsers that support ActiveX controls.

      Connect to Music and Media Objects Using JavaScript
      Just as we could use JavaScript to reset the properties and call the method of Java applets, we can
      also use that same principle when handling other embedded objects. For instance, the following
CHAPTER 15: Use JavaScript to Manage Browser Plug-Ins              323




 FIGURE 15-3     Embedding a movie in an HTML page


JavaScript functions can be used to stop and start the movie displayed in our ActiveMovie
control.
<script language="JavaScript" type="text/javascript">
var movie = document.getElementById("ActiveMovie1");
function startMovie() {
    movie.Run();
}                                                                                                  15
function stopMovie() {
    movie.Stop();
}
</script>

    The preceding JavaScript code gets a variable reference to the element named ActiveMovie1,
which happens to be our embedded movie control. We can then call the Run() and Stop() methods
of that control to start and stop the movie.
    We can take advantage of these functions by adding two HTML push-button controls to the
web page, allowing users to stop and start the movie themselves.
324      How to Do Everything with JavaScript

      <form action="#">
          <input type="button" value="Start Movie" onclick="startMovie()">
          <input type="button" value="Stop Movie" onclick="stopMovie()">
      </form>



 Use the Microsoft Calendar Control in Your Web Pages
      Microsoft provides some interesting ActiveX controls that you can use in your HTML web
      pages. One such control is the Microsoft Calendar Control, which can be used to display a
      calendar and allows your users to choose a date. For choosing dates in the near past or future,
      this tool can be a valuable time-saver.
               IE is currently the only browser that supports ActiveX controls such as the
               Calendar Control.

          Figure 15-4 gives an idea of how the calendar control looks in a web browser. Of course,
      knowing the class ID of the calendar control makes adding it to a web page fairly easy, using
      the <object> tag.




       FIGURE 15-4      The predefined calendar control can be used to select a date.
CHAPTER 15: Use JavaScript to Manage Browser Plug-Ins                 325

<object id="myCalendar" width="480" height="190"
 classid="CLSID:8E27C92B-1264-101C-8A2F-040224009C02">
    <param name="Year" value="2004">
    <param name="Month" value="7">
    <param name="Day" value="17">
</object>

    We can pass the current year, month, and date to be displayed using the familiar <param>
syntax.
    Of course, the calendar control is scriptable, like most other objects embedded in the web
page. So all we need is a variable that contains a reference to the object and then we are free
to modify its properties and settings using JavaScript.
    The basic principles introduced in this chapter can be extended to almost any type of content
you can imagine. Macromedia Flash animations, virtual reality 3-D models, and Adobe Acrobat
PDF documents can all be handled inside the browser window using plug-ins. And most of those
objects can be scripted using JavaScript.
    JavaScript has firmly implanted itself as a core technology in web site development. As the
Internet moves into the age of XML and XHTML, and away from the age of HTML, we can
trust that JavaScript will remain a popular standard, since there is no better technology to bring
automation and interactivity to web pages.




                                                                                                       15
This page intentionally left blank
Appendix A   HTML 4.01 Tags
328      How to Do Everything with JavaScript


      The following table lists each of the HTML 4.01 tags and gives a brief description of its use. But
      note that Microsoft and Netscape have in some cases added their own tags, so their lists might
      not match this.



       <a>                  Creates a hyperlink, or defines a bookmark inside a page
       <abbr>               Denotes an abbreviated form
       <acronym>            Denotes an acronym
       <address>            Denotes a mailing address
       <applet>             Officially deprecated; embeds a Java applet
       <area>               Part of the client-side image map syntax
       <b>                  Defines the enclosed text as bold print
       <base>               Defines the base URI for the document
       <basefont>           Officially deprecated; defines the base font size for the document
       <bdo>                Internationalization (i18n BiDi override)
       <big>                Defines the enclosed text as extra large print
       <blockquote>         Defines the enclosed text as a block quotation
       <body>               Indicates the body of the web page
       <br>                 Inserts a new line
       <button>             Adds a command button to a form
       <caption>            Adds a caption to a table
       <center>             Officially deprecated; centers text horizontally
       <cite>               Citation
       <code>               Defines the enclosed text as code
       <col>                Defines a table column’s properties
       <colgroup>           Groups columns in a table
       <dd>                 Definition description for a definition list
       <del>                Defines the enclosed text as deleted text
       <dfn>                Instance definition
       <dir>                Officially deprecated; creates a directory list
       <div>                Defines a block of text as an entity
       <dl>                 Creates a definition list
       <dt>                 Definition term for a definition list
       <em>                 Defines the enclosed text as emphasis print
       <fieldset>           Form control group
       <font>               Officially deprecated; sets the font type for the enclosed text
Appendix A: HTML 4.01 Tags   329


<form>       Defines an HTML web form
<frame>      Defines framed content
<frameset>   Defines a group of frames
<h1>         Defines heading text, level 1 (largest)
<h2>         Defines heading text, level 2
<h3>         Defines heading text, level 3
<h4>         Defines heading text, level 4
<h5>         Defines heading text, level 5
<h6>         Defines heading text, level 6 (smallest)
<head>       Indicates the head section of the web page
<hr>         Inserts a horizontal rule
<html>       The parent tag of every other element
<i>          Defines the enclosed text as italic print
<iframe>     Defines a floating frame
<img>        Inserts an image
<input>      Adds a form control to a form
<ins>        Defines the enclosed text as inserted text
<isindex>    Officially deprecated; single line prompt
<kbd>        Defines the enclosed text as text to be entered by the user
<label>      Inserts a label into a form
<legend>     The legend for a fieldset
<li>         A list item for a list
<link>       A media independent link
<map>        Defines a client-side image map
<menu>       Officially deprecated; defines a menu list
<meta>       Inserts data related to the HTML document (called meta data)
<noframes>   Alternate content for browsers that do not support frames
<noscript>   Alternate content for browsers that do not support scripting
                                                                                         A
<object>     Inserts an object into the document
<ol>         Defines an ordered list
<optgroup>   Defines a group of options
<option>     Defines an option for a select list
<p>          Indicates a paragraph
<param>      Provides a property to be passed to embedded content
330     How to Do Everything with JavaScript



      <pre>             Defines the enclosed text as preformatted
      <q>               Defines the enclosed text as a short inline quotation
      <s>               Officially deprecated; defines the enclosed text as strikethrough
      <samp>            Defines the enclosed text as sample program output
      <script>          Defines an embedded script
      <select>          Inserts a list box control into a web form
      <small>           Defines the enclosed text as small text
      <span>            Defines inline text as an entity
      <strike>          Officially deprecated; defines the enclosed text as strikethrough
      <strong>          Defines the enclosed text as strong text
      <style>           Defines an embedded style sheet (CSS)
      <sub>             Defines the enclosed text as subscript
      <sup>             Defines the enclosed text as superscript
      <table>           Creates a table
      <tbody>           Defines the table body
      <td>              Inserts a new cell into a table
      <textarea>        Inserts a multiline text form control into a web form
      <tfoot>           Defines the table foot
      <th>              Inserts a new header cell into a table
      <thead>           Defines the table head
      <title>           Gives the document a title
      <tr>              Inserts a new row into a table
      <tt>              Defines the enclosed text as monospace (fixed-width) text
      <u>               Officially deprecated; defines the enclosed text as underlined
      <ul>              Creates an unordered list (bullet points)
      <var>             Defines the enclosed text as a program variable
JavaScript
Appendix B   Quick Reference
332         How to Do Everything with JavaScript


      This appendix lists the statements and system objects available for use in JavaScript. Table B-1
      shows all the statements available for use in JavaScript 1.5. No new statements have been added
      to the list for JavaScript 2.0. Tables B-2 and B-3 list the system objects for JavaScript 1.5 and 2.0,
      respectively.



       Statement      Description
       //             Creates a single line of comments
       /* … */        Creates a block of comments
       break          Jumps out of a loop or switch statement
       continue       Starts a loop over at the next iteration
       do-while       Creates a loop that executes one or more statements as long as the specified condition
                      is true, but always executes it at least once
       for            Creates a loop that executes one or more statements until a counter reaches a set value
       for-in         Creates a loop that iterates over the properties of an object or the contents of an array
       if-else        Only executes code if the specified condition is true
       label          Allows break or continue statements to jump out of nested loops
       return         Causes a function to exit, optionally returning a value
       switch         Chooses to execute only one of several cases based on the value of the specified
                      expression
       throw          Causes an exception to be raised
       try-catch      Intercepts an exception and handles it
       while          Creates a loop that executes one or more statements as long as the specified condition
                      is true
       with           Allows access to the properties and methods of an object without having to use that object
       TABLE B-1       Statements Available in JavaScript 1.5 and 2.0
Appendix B: JavaScript Quick Reference                  333

Class Name             Description
Array                  Allows lists of data to be stored in a single variable
Boolean                A wrapper for Boolean values
Date                   Lets you work with dates and times
Function               Allows you to define a function programmatically
Math                   Contains convenient mathematical constants and functions
Number                 A wrapper for primitive numeric values
Object                 All objects derive from this data type
RegExp                 Provides support for regular expressions in JavaScript
String                 A wrapper for string values
TABLE B-2      Built-in System Objects Available in JavaScript 1.5




Class Name             Description
Array                  Allows lists of data of type Object to be stored in a single variable; equivalent to
                       the Array[Object] data type
Array[type]            Allows lists of data of type type to be stored in a single variable
Boolean                Supports variables that can store only the values true and false
char                   Supports variables that can store only a single character
ConstArray             Allows lists of data of type Object to be stored in a single constant; is equivalent
                       to the ConstArray[Object] data type
ConstArray[type]       Allows lists of data of type type to be stored in a single constant
DynamicArray[type]     Allows resizable lists of data of type type to be stored in a single variable
Function               The “data type” of functions
Integer                Supports variables that can only store integers
Never                  Supports variables that cannot contain any value
Null                   Supports variables that can only store the value null
Number                 Supports variables that can only store numbers
Object                 Supports variables that can contain any value
                                                                                                                B
Prototype              Supports variables that contain prototype-based objects (JavaScript 1.5’s way of
                       handling objects)
StaticArray[type]      Allows writable lists of data of type type to be stored in a single variable
String                 Supports variables that can only store strings
Type                   The “data type” of data types
Void                   Supports variables that can only store the value undefined
TABLE B-3      Built-in System Objects Available in JavaScript 2.0
This page intentionally left blank
Index
Symbols                                            <!DOCTYPE> tag, 146-147
" (double quotes), for string literals, 74         <?xml?> declaration, 145
"" (empty string), 34, 73, 87                      <applet> tag, 315-317, 319
# (pound sign)                                     <applet> tag attributes, 317
         as a valid URL, 186                       <b> tag, 261, 263
         for RGB values, 262                       <body> tag/element, 19, 276-277
#special selector, 270                             <br> tag, 263
$ (dollar sign), in regular expressions, 87        <button> element, 194
% (modulus) operator, 42                           <center> tag, 263
' (single quotes), for string literals, 74         <div> tag/element, 174-176, 198, 264-265,
() (parentheses), for parameter lists, 52            269, 277
(...) rest parameter, 61                                 attributes, 265
* (asterisk multiplier), 229-230                         with id attribute of special, 270
*/ (asterisk slash), block comment ending, 44      <embed> tag, 315, 321-324
++ operator, 35                                          attributes, 321
. (dot) operator, 73, 77-78                              height attribute, 321
.class file (Java), 316                                  src attribute, 321
.css files, 267, 269-270                                 width attribute, 321
.java code file, 316                               <font> tag, 261-263
.js file extension, 157                            <font> tag color attribute, 262
.NET Framework (Microsoft), 14                     <form> tag/element, 184-186
. (dot) operator, 73, 77-78                              action attribute, 185-186, 195
.class file (java), 316                                  attributes, 184-185
.java code file, 316                                     event handlers, 195
.js file extension, 157                                  method attribute, 195
.NET Framework (Microsoft), 14                           onsubmit attribute, 195-197, 220
/ (forward slash)                                        submit() method, 219-220
         in HTML, 143                              <frame> tag, 225-226
         in regular expressions, 87, 89                  attributes, 233-234
/* (slash asterisk), block comment beginning, 44         frameborder attribute, 235
// (double forward slashes), as comment markers,         name attribute, 235
    19, 44                                               noresize attribute, 235
: (colon)                                                src attribute, 234
         label ending, 43                          <frameset> tag/element, 225, 229
         separating properties and values, 122           attributes, 225
; (semicolon)                                            onload and onunload event handlers, 226
         for appending JavaScript commands, 159          rows and cols attributes, 227-232
         statement ending, 100                     <head> tag, 18, 226
< and > (angle brackets), in HTML, 142             <h1> header tag, 19
<!-- and --> HTML comment markers, 19, 144, 156    <html> tag, 18, 145


                                                                                                   335
336       How to Do Everything with JavaScript

      <i> tag, 261                                     Access key, key combination to activate, 189
      <img> tag/element, 211, 276                      Accesskey parameter, 189
             attributes, 218                           Activate event, 209
             id attribute, 275                         ActiveMovie control (Microsoft), 321-323
             src attribute, 211                        ActiveScript, 142
      <input> element, 187, 194, 271                   ActiveX controls, 321, 324
             default type, 186                         ActiveX (Microsoft), 314
             maxlength attribute, 189                  Address bar (browser), 258
             size attribute, 189                       Adobe Acrobat PDF documents, 142
             value attribute, 189, 194                 Adobe GoLive, 12-13
      <layer> tag, 172-175                             Alert box, 20-21, 197
      <link> element, 267, 269                         Alert message, displaying, 20-21, 288-289
      <meta> tag, 147-148                              Alert (message) box, 288-289
      <meta> tag attributes, 147                       Alert() method, 288
      <noframes> tag, 226-227                          Allaire Corporation, 11
      <noscript> tag, 154-156                          Ancestor, class as, 130
      <object> tag/element, 315, 321-322, 324          Angle brackets (< and >), in HTML, 142
      <object> tag classid attribute, 321-322          Animate() function, creating, 275
      <option> element, 189, 193                       Animating text, 277
      <option> element attributes, 193                 Animation, 259-278
      <param> tag, 318-319                                    explained, 260
      <script> tag/element, 16, 153-154, 158, 198             using JavaScript for, 274-278
             attributes, 19, 153-154                          using timer events, 274
             in an HTML page, 17-18                    API (application programming interface), 244
             language attribute, 153                   Apple Quicktime Player, 322
             src attribute, 157                        Applets (Java), 5, 315-320
             type attribute, 154                       Application error, defined, 46
      <select> element, 189                            Array of arrays, 110, 112
             attributes, 192                           Array class, 102
             for a list box, 217                       Array class subclasses, 111
             multiple attribute, 191                   Array elements
             size attribute, 191-192                          accessing, 104-106
      <span> element, 265                                     restricting to type, 113
      <span> element attributes, 265                   Array index, 96, 104-105
      <style> tag/element, 151, 264, 266-267           Array literals, 100-101
      <textarea> element, 193, 198                     Array object, 96
      <textarea> element attributes, 193                      creating, 97-104
      <title> tag, 147                                        index property, 101
      ? (question mark), in expression matching, 34           input property, 101
      [] (square brackets operator), 73, 96, 104-106          length property, 99, 101
      ^ (caret), in regular expressions, 87                   methods, 102-104
      { and }, for enclosing statements, 32                   properties and methods, 101-104
      {} (curly brackets), for object literals, 122    Array of zero length, 97
       (backslash), in regular expressions, 88-89     Arrays, 95-115
       double backslash (escaped backslash), 89             creating empty, 97-99
      d tokens, in regular expressions, 87-88                creating and initializing in one code line, 100
      , (comma)                                               creating using the Array class, 102
             separating parameters, 52                        JavaScript 2.0 enhanced, 111-112
             separating property-value pairs, 122             of long lists, 100
                                                              multidimensional, 107-115
                                                              with numerical indexes, 106
      A                                                       parallel, 109-110
      Abort event, 216                                        setting and retrieving values in, 104-106
      Absolute positioning, 258                               specifying an initial length for, 99
Index   337

As operator, 51                                     Browsers
ASCII codes, 214                                           checking your code on, 312
ASP .NET platform, 14                                      detecting, 174
ASP (Application Server Page), 142                         detecting the type running, 164-169
ASP web page, form that submits itself to, 195             DOMs of, 14, 162
Asterisk (*) multiplier, 229-230                           first JavaScript-enabled, 6
Asterisk and slash (*/), block comment ending, 44          getting for testing your code, 312
Attributes, explained, 184                                 interacting with, 243-258
AVI files, 321                                             with no support for frames, 226-227
                                                           redirecting to a new web page, 258
                                                           reliance of on external plug-ins, 315
B                                                          sending back to previous page(s), 257
Backslash (), in regular expressions, 88-89               testing on all, 312
Block comments, 44                                         that don't support scripting, 154-156
Blur event, 209-210                                        using the latest release, 163
Blur event firing order, 210                               web surfer use of, 162-163, 169
Blur() method, 220                                  Bug, defined, 278
Body section (HTML document), 18-19, 145            Button caption, 194
Boolean data type, 27, 91                           Button controls (form), 193-194, 220, 320, 323
       converting other data types to, 31           Buttons (form), 193
       expressions that return, 50                  Byte, 91
       for loaded frames, 239-240
Boolean literals, 91
Break statement, 34, 40-41, 58                      C
Breakpoints, in debugging, 293                      Calculators (online), 182-183
Browser address bar, 258                            Calendar Control (Microsoft), 324-325
Browser compatibility issues, 162-170               Call stack, 102
       of code, 171-177                             Calling a function, 53
       of DHTML, 171                                Captions for push buttons, 194
       of events, 220-221                           Capturing an event, explained, 208
       of styles, 272-273                           Caret (^), in regular expressions, 87
Browser DOMs, 14, 162                               Case clauses, 33-34
Browser error messages, interpreting, 282           Catch blocks, Netscape conditional, 302
Browser events, 158                                 Catch clause, 297-304
       handling, 207-221                            Catching, explained, 195
       supported by Internet Explorer, 199          Change event, 216
Browser frames. See Frames (browser)                Changeimage() function, 211-212, 274
Browser history list, 257-258                       Char data type, 91-92
Browser market features competition, 170            Checkform() function, 200-202
Browser plug-ins, 254, 313-325                      Checkkey() function, 214
Browser refresh, 258                                Child classes, 131
Browser sniffing code, 221                          Child nodes, 246
Browser software properties, 254-256                Class attribute of HTML elements, 265
Browser status bar, 253                             Class inheritance, benefits of, 132-133
Browser support for methods, 169-170                Class members, 68
Browser timers, 251                                        public vs. private, 136
Browser type, detecting, 164, 167, 256                     static vs. instance, 135-136
Browser usage statistics, 163                       Class properties, 78. See also Properties
Browser version                                            accessing, 120, 128
       detecting, 164                                      creating by assigning a value, 126
       knowing the minimum needed, 15                      defining in JavaScript 2.0, 127
Browser window, 252-254                                    inherited, 131, 134
       resizing and centering, 256-257              Classes
       writing text to, 21-22                              adding constructor functions to, 127
338      How to Do Everything with JavaScript

             adding methods and properties to, 123-125      Confirm box, 21
             as ancestors, 130                              Console (JavaScript), 283, 286-287, 290-291
             attaching functions to, 124                    Const keyword, 28
             built-in, 63-93                                Constants, 27-29, 67, 114-115
             and code reuse, 308                            ConstArray, creating, 114-115
             containing multiple constructors, 131          ConstArray class, 114-115
             creating, 117-137                              Constructors (constructor functions), 72
             creating methods using, 128                          adding to classes, 127
             defining functions in, 128                           calling, 119-121
             defining in JavaScript 2.0, 127-129                  class containing multiple, 131
             extending, 123-125                                   creating, 119
             inheriting properties and methods, 131, 134          creating objects from, 121
             instantiating using the new keyword, 128       Continue statement, 40-41
             JavaScript 1.5, 70                             Control focus, explained, 188
             organizing using inheritance, 130-135          Control name, accessing a control by, 200
             for shopping cart items, 308                   Cookies, explained, 248
             testing, 308                                   Copy and paste, code reuse by, 122
             turning properties and functions into, 68-69   Counter variable, 28, 55-56
             using as data types, 71                        Cross-browser compatibility issues, 162-170
      Classid attribute (<object> tag), 321-322                   of code, 171-177
      Click() method, 220                                         of DHTML, 171
      Clickme() function, 220                                     of events, 220-221
      Client, defined, 8                                          of styles, 272-273
      Client-server analogy, 8                              Cross-frame scripting, security risks of, 239
      Client-server communication, 184                      CSS attributes, 268
      Client-side forms, 182-183                                  vs. JavaScript property names, 272-273
      Client-side JavaScript                                      list of, 269
             defined, 8                                           reference guide to, 268
             processing form input, 182-183                 CSS (Cascading Style Sheets), 150-153. See also
      Client-side language, JavaScript as, 14                 Style sheets
      Closing tags (HTML), 142-143                                basics of, 260-273
      Code reuse                                                  benefits of, 150
             by class inheritance, 132                            vs. frames, 224
             by copy and paste, 122                               selectors in, 266-267
             using classes and objects, 308                       sizing and positioning, 269-270, 276-277
      Colon (:)                                                   why they are cascading, 261
             label ending, 43                               CSS Level 1 standard (W3C), 261
             separating properties and values, 122          CSS positioning attributes, 270
      Colors, specifying in HTML, 262                             animation using, 276-277
      Cols attribute (<frameset> tag), 227-232                    defining, 269
      Commas                                                CSS validator service (W3C), 273
             for separating parameters, 52                  Curly brackets ({})
             for separating property-value pairs, 122             for enclosing statements, 32
      Comment markers, HTML vs. JavaScript, 19, 44                for object literals, 122
      Commenting out a function (in debugging),             Current date and time, retrieving, 64
        289-290
      Comments
             HTML, 19, 144, 156                             D
             JavaScript, 19, 43-44                          Data integrity, private class members for, 136
             uses for, 44, 289-290                          Data lists. See Array object; Arrays
      Compiler, defined, 9                                  Data storage, 26-29
      Componentizing a program, 307                         Data types (JavaScript 2.0), 28, 59, 69-71, 91-93
      Compound attributes, explained, 268                          converting to Boolean, 31
      Conditional catch blocks (Netscape), 302                     using classes as, 71
      Conditional statements, 30-34
Index        339

Date class, 64, 79-80                           DOS/Windows environment, JavaScript in, 9
Date class constructor formats, 82              Dot operator (.), 73, 77-78
Date constructor, 80, 82                        Dothis() function, 194
Date object, 79-80, 124                         Double backslash (), 89
Date object getMonth() function, 99             Double forward slashes (//), for comment markers,
Date object methods, list of, 80-82               19, 44
Date-handling functions, 79-82                  Double quotation marks ("), for string literals, 74
Debuggers, 291-293                              Douglas Crockford's JavaScript Lint validator, 287
Debugging code                                  Do-while loop, 37
      adding to programs, 287-290               Dreamweaver MX, 10-12, 291
      explained, 288                            Drop-down list box control, 189-190, 217, 251-252
Debugging (of JavaScript programs), 281-293     Dynamic list box, 251-252
      defined, 278                              Dynamic style modifications, 270-272
      designing for easy, 306-308               Dynamic text, marking, 265
      use of breakpoints, 293                   Dynamically loading images, 274-276
      using commenting for, 289-290             DynamicArray, creating, 114
Debugging software, 291-293                     DynamicArray class, 114
Default clause (switch statement), 34
Default object, setting, 44-46
Deprecated HTML tags, 145-146                   E
Developers testing their own programs, 311      ECMA (European Computer Manufacturers
Development environments, 7-13                    Association), 5, 59
DHTML (Dynamic HTML), 151, 171-177              ECMAScript, 6
DHTML menu, 172                                 ECMAScript Edition 4 standard, 6
Display settings (operating system), 256-257    ECMAScript specification, 287
Document model, querying, 169-170               800 by 600 resolution, 256
Document object, 248-252                        Elements array, for accessing form values, 202-203
      arrays, 248                               Else clause, 32
      body property, 249                        Else-if clause, 32
      forms array, 200-202                      E-mail, form contents in, 185
      in Internet Explorer 6.0, 74              Embedded multimedia, plug-ins for, 254
      methods, 248                              Embedded style sheets, defining, 266-267
      using to update the time, 251             Empty arrays
Documentation, using comments for, 144                 creating, 97-99
Document.write() function, 21-22, 42, 54, 58,          testing for potential use of, 311
  248, 288                                      Empty function, defining, 119
Dollar sign ($), in regular expressions, 87     Empty string (""), 34, 73, 87
DOM (browser), 14, 162                          Environments, JavaScript versions in different, 142
DOM (Document Object Model), 5, 8, 244          Error checking, stricter level of, 283
      basics of, 245-248                        Error details in IE, 285
      document parts considered nodes, 246      Error event, 216
      explained, 244                            Error handling, 46-49
      objects in, 245                           Error icon, 283
DOM (JavaScript), 7                             Error message box (in IE), 284
DOM Level 1 (DOM 1), 169, 246                   Error messages, 47
DOM Level 3, 247                                       finding the source of, 284-285
DOM Level 2, 246, 247                                  interpreting, 282, 285-287
DOM Level 2 Events specification, 208                  in JavaScript console, 286-287
DOM Level 0, 245                                       line numbers listed in, 285-286
DOM methods, checking before using, 169-170     Error object (IE), 298, 301
DOM 1 hierarchy (DOM tree), 246                        creating, 301
DOM standard (W3C), 8, 244                             properties, 301
DOM traversal, 247                              Error reporting, turning off and on, 282-284
DOM tree, 246-247                               Error string (Netscape), 298
340      How to Do Everything with JavaScript

      Error types in JavaScript, 283                       External JavaScript file, loading, 157-158
      Error-handling code, testing, 311                    External styles, importing, 267
      Errorproofing a program, 295-312
      Errors, 46
             causes of, 282-287                            F
             detecting programmatically, 48                F (float) suffix, 71
             forcing to test error-handling code, 311      FactorString variable, 57
             returning back to the program, 296            FIFO (first in first out) order, 102
             sources of, 163                               File, escaping, 85
             things that can go wrong, 46                  Finally clause in try-catch statement, 302-304
      Escape() function, 85                                Finally clauses (nonstandard), 302-304
      Escaped character sequence, 85                       FireEvent() method, 220
      Escaping a file, explained, 85                       Firing of events, order of, 209-210, 212-213
      Event attributes, setting, 218                       Flash files (Macromedia), 142
      Event bubbling, 219                                  Float number (F) suffix, 71
      Event firing test, 210, 212-213                      Focus (control), explained, 188
      Event handlers, 185, 208                             Focus event, 209-210
             <form> element, 195                           Focus event firing order, 210
             returning false, 213                          Focus() method, 220
             setting for HTML tags, 218                    Font attribute, 268
             using the event property, 218                 Font style elements (HTML 4.01), 148-149
             viewing, 218                                  For loop, 37-38, 252
             writing, 208-217                              For-in loop, 38-40, 61, 73, 105-106
      Event handling (browser events), 207-221                    iterating over an array, 106
      Event names, capturing, 199                                 iterating over a hash table, 105
      Event property, 218                                  Form control values, 200-205
      Event triggering in JavaScript, 219-220                     accessing with getElementById(), 204
      Events specification (DOM Level 2), 208                     accessing with getElementsByName(), 204
      Events (web form), 185-186, 188, 192, 208                   accessing with getElementsByTagName(), 205
             and browser incompatibility, 220-221                 accessing using an elements array, 202-203
             cancelling, 213-214                                  accessing using a forms array, 200-202
             capturing, 208                                Form controls
             catching on form controls, 197-199                   catching events on, 197-199
             categories of, 209                                   currently active, 188
             first handled by innermost element, 219              list of, 187
             form control programmable, 197-199                   programmable events, 197
             intercepting, 208                                    testing for existence of before accessing, 241
             invoking JavaScript in response to, 158       Form-handling programs, technologies to create, 183
             order of firing, 209-210, 212-213             Forms array, 200-202, 248
             that are not specified by standards, 221      Forms (web), 179-206
      Exception bubbling, 299-301, 304                            adding controls to, 186-195
      Exceptions, 296-297                                         getting in e-mail, 185
             catching using try-catch, 297-304                    handling user input, 180
             creating using the throw statement, 304-306          initializing, 217
             re-throwing, 305                                     onfocus/onblur/onchange events, 188, 192
             unhandled, 303                                       onsubmit and onreset events, 186
      Expandable tree menu using DHTML, 173                       processing with client-side JavaScript,
      Expressions, 27, 31-32, 38, 49-50                              182-183
             as parameters to function, 50                        processing input on a web server, 183-184
             list of types of, 49                                 requesting user input, 181-182
             that return Boolean values, 50                       submissions with onsubmit, 195-197
      Extends keyword, 130
Index        341

Fortran, 64                                        Functions (JavaScript), 27, 51-59, 68, 277
Forward slash (/)                                        attaching to classes, 124
      in HTML, 143                                       attaching to objects, 124-125
      in regular expressions, 87, 89                     calling, 53
Frame borders, making invisible, 235                     calling from frames, 235-238
Frame size values                                        in classes, 68-69
      absolute, 228-230                                  commenting out (in debugging), 289-290
      relative, 229-230                                  debugging, 289-290
      setting, 227-230                                   defined, 27, 68
Frames array, 237, 253                                   defining, 52-55, 119, 128
Frames (browser), 223-241                                defining inside classes, 128
      absolute size of, 228-230                          to detect browser type, 167
      accessed by name, 237                              empty, 54, 119
      accessing in a different domain, 239               for error-checking, 297
      accessing using JavaScript, 236-237                forcing to return hard-coded values, 289-290
      assigning names to, 235                            hyperlinks calling, 158-159
      benefits of, 224                                   to improve organization and readability, 307
      Boolean variable for loaded, 239-240               specific to version 2.0, 59-61
      and browsers that do not support, 226-227          syntax of, 52
      calling JavaScript functions from, 235-238         testing, 308
      cascading effect between, 239                      testing for existence of before
      vs. CSS, 224                                          accessing, 241
      defined, 224                                       that cause the program to exit, 93
      defining and naming, 233-235                       that do not return a value, 92-93
      horizontal, 230-231                                triggering with onclick event, 320
      limiting the number of, 228
      problems of, 224
      relative size of, 229-230                    G
      synchronization between, 239-241             GetElementById() method, 169-170, 175, 204, 248,
      testing for existence of, 241                  274, 319
      vertical, 230-231                            GetElementsByName() method, 204, 248
Frameset document HTML code, 226                   GetElementsByTagName() method, 205
Frameset HTML, explained, 146                      GetMonth() function, 99
Frameset layout, 226                               GoLive (Adobe), 12-13
Framesets, 224                                     GUI (graphical user interface), 4
      with both rows and columns, 232
      creating in HTML, 225-233
      defining and naming frames in, 233-235       H
      and frame size, 228
      nested, 233-234                              Hash tables, 104-105
FrontPage Explorer, 10-11                          Header section (HTML document), 18-19, 145
FrontPage Server Extensions, 10                    Height attribute, 270
FrontPage 2002, 10                                 Hexadecimal color values, 262
Function keyword, 52                               Hierarchical tree, 130
Function parameters, 52, 54-56                     History object, 257-258
      expressions as, 50                           History object go() method, 257
      named, 60-61                                 History object length property, 257
      passed by value, 56                          History object methods, 257
      unlimited number of, 61                      HomeSite 5, 11-12
      unnamed, 61                                  Horizontal frames, defining, 230-231
Function syntax, 52                                HTML comments, 19, 144, 156
342      How to Do Everything with JavaScript

      HTML document                                         for formatting a page, 261-263
          body section, 145                                 for formatting text, 148-150
          building, 145-146                                 proprietary, 170-171
          in a DOM tree, 247                                setting an event handler for, 218
          head section, 145                                 start tag, 145
          keywords in, 147-148                        HTML testing harness, 310
          parts of, 18-19                             HTML validation service, 170
          title for, 147                              HTTPS protocol, 190
      HTML editors, 10-13                             Hyperlink
      HTML elements                                         to simulate a submit button, 219
          ID attributes of, 204                             using to call JavaScript, 158-159
          inheritance of style attributes, 261
          style attributes, 261, 266
          style/class/id attributes, 265              I
          using to assign style, 261-263              Id attribute of HTML elements, 204, 265
      HTML event handling, 215-217                    IDEs (integrated development environments),
      HTML events, 209, 215-217                          7, 296
      HTML files for frames and frameset, 235         IE (Microsoft Internet Explorer), 8, 162
      HTML form controls, list of, 187                        ActiveX controls for, 314
      HTML forms, 180-199                                     browser events supported by, 199
          adding controls to, 186-195                         calling the submit() method, 220
          client-server communication when                    error details, 285
              submitted, 184                                  error message box, 284
          with client-side JavaScript, 182-183                Error object, 298, 301
          inserting on a web page, 184-199                    JavaScript in, 5
          onfocus/onblur/onchange events, 188, 192            navigator.appName property, 165
          onsubmit and onreset events, 186                    navigator.appVersion property, 166
          processing input on a web server, 183-184           Object expected message, 286
          requesting user input, 181-182                      turning error reporting off and on, 282-284
      HTML 4.01                                       IE 6.0
          font style elements, 148-149                        document object in, 74
          phrase elements, 148-149                            interpreting the <div> tag, 176
      HTML 4.01 tags, complete list of, 328-330       IE web site, 16
      HTML frames, 224-235                            If keyword, 302
      HTML (Hypertext Markup Language), 4. See also   If statement, 31-32, 170, 240, 297
       HTML elements; HTML tags                               checking the format of, 287
          basic structure of, 142-153                         forms of, 32
          creating framesets in, 225-233              If-else statement, 32
          testing JavaScript programs with, 16-19     If-else-if statement, 33
          text formatting, 148-153                    IIS web servers, 142
          user controls in, 180-181                   Image rollover effects, 212
          viewing underlying, 144                     Images
      HTML markup tags. See HTML tags                         dynamically loading, 274-276
      HTML tag names, lowercasing, 146                        inserting, 211
      HTML tags, 142                                          switching to animate, 274-276
          <A HREF>, 158                               Images array, 248
          <noscript>, 154-156                         Incrementor section (for loop), 38
          <script>, 153-154, 157                      Index (array), 96, 104-105
          <style>, 151                                IndexOf() method, 78
          to add scriptable objects, 315              Infinite loop, 35, 38
          closing tags, 142-143                       Inheritance, 130-135
          complete list of, 328-330                           benefits of, 132-133
          deprecated, 145-146                                 of web page style attributes, 261
          end tag, 145                                Initialize() function, 217
Index       343

Initializer section (for loop), 38                            what it can and cannot do, 13-15
Inline styles, defining, 265-266                              what it is, 4
Inline text, 265                                              what not to use it for, 15
Input-output functionality, 244                               where it is today, 6-7
Instance members, 135-136                                     which version to use, 15
        defined, 78                                    JavaScript Console, 283, 286-287, 290-291
        vs. static members, 78                         JavaScript debugger, 291-293
Instantiating an object, 72                            JavaScript DOM, 5, 7
Integer data type, 91                                  JavaScript Editor (C Points), 291
Integers, range of values for, 28                      JavaScript environments and object models, 244
Interfaces, 132                                        JavaScript file, loading external, 157-158
Internet, privacy and, 190                             JavaScript Lint validator, 287
Internet search engines, specifying keywords for,      JavaScript 1.5
   147-148                                                    complete list of statements, 332
Invalid date, testing for potential use of, 311               core classes, 70
Invalid inputs, testing for potential use of, 311             creating objects in, 118-126
IPlanet Web Server, 14, 142                                   list of system objects, 333
Is operator, 51                                               reasons for errors, 283
                                                       JavaScript releases, chronology of, 7
                                                       JavaScript templates, 16-19
J                                                      JavaScript 2.0
Java applets, 5, 315-320                                      added features, 13-14
Java compiler, 316-317                                        breaking code into manageable chunks, 307
Java language, 315                                            breaking long lines of code, 100
Java SDK (Software Development Kit), 317                      browsers that don't support, 15
JavaScript (see also JavaScript 1.5; JavaScript 2.0)          complete list of statements, 332
       adding to a Web page, 153-154                          creating objects in, 126-137
       appending, 159                                         data types, 28, 59, 69-71
       as a client-side language, 14                          defining classes, 127-129
       as a scripting language, 4                             enhanced arrays, 111-112
       as a server-side language, 14-15                       extra spaces in code, 100
       as an official standard, 5                             functions, 59-61
       calling using hyperlinks, 158-159                      interfaces and, 132
       comments, 19                                           list of system objects, 333
       debugging, 281-293                                     new data types, 91-93
       designing for easy debugging, 306-308                  new operators, 51
       developed using a text editor, 296                     newline character in code, 100
       development tools, 9-13                         JavaScript versions, 7
       distributed as source code, 296                        in different environments, 142
       errorproofing, 295-312                                 specifying version numbers, 164
       for form control values, 200-205                Javascript: prefix (in HREF URL), 159
       fundamentals of, 25-61                          JavaScript-enabled web browser, the first, 6
       history of, 4-7                                 JavaScript-enabled web pages, developing, 7
       in DOS/Windows environment, 9                   JRE (Java Runtime Environment), 317
       in Internet Explorer, 5                         JScript (Microsoft), 5-6, 9
       managing browser plug-ins with, 313-325         JSP (Java Server Page), 5
       origin of, 5                                    JVM (Java Virtual Machine), 315, 317
       vs. other languages, 13
       programming terms, 27
       quick reference to, 331-333                     K
       reasons for errors in, 283                      Key event firing order, 213
       replacing with HTML text, 156                   Key event handlers, 212-214
       testing using HTML, 16-19                       Key events, 209, 212-214
       types of errors in, 283                         Key (index), 105
344       How to Do Everything with JavaScript

      KeyCode property of window.event object, 214          embedding a Media Player 9 object, 322
      Keydown event, 213-214                                Media Player 6.4, 322
      Keypress event, 213                             Members (class), 68
      Keyup event, 213                                Methods, 44-45
      Keyword, defined, 27                                  adding to classes, 123-125
      Keywords in HTML documents, 147-148                   attaching to objects, 125-126
                                                            browser support for, 169-170
                                                            calling, 129, 137
      L                                                     calling public, 137
      L (long) suffix, 71                                   checking before using, 169-170
      Label names, 43                                       of a class, 78, 123-125
      Labeling a loop, 43                                   creating using classes, 128
      Labels (named lines of code), 42-43                   defined, 67
      Language attribute (<script> tag), 19                 inherited, 131, 134
      Layers (in Netscape 4), 169, 172-174                  private, 73
      LIFO (last in first out) order, 102             Microsoft ActiveMovie control, 321-323
      Line numbers in error messages, 285-286         Microsoft ActiveX, 314
      List box controls (form), 189-193               Microsoft ASP .NET platform, 14
      Lists, storing, 96                              Microsoft Calendar Control, 324-325
      Literal, defined, 27                            Microsoft FrontPage, 10
      LiveWire server-side language, 14               Microsoft IE web site, 16
      Load event, 215-216                             Microsoft IIS web server, 142
      Location object, 258                            Microsoft JScript, 5-6
      Location object methods, 258                    Microsoft .NET Framework, 14
      Location object properties, 258                 Microsoft Script Debugger, 293
      Logic errors, 283                               Microsoft Script Editor, 291
      Long integer, 71                                MIME standard, 154
      Long lines of code, breaking, 100               MIME type, 154
      Loops, 34-43                                    Modifylayer() function, 198-199
              labeling, 43                            Modular programming, 66
              nested, 42                              Modules, 66
              uses for, 34                            Modulus (%) operator, 42
      Low-level data types, 71                        Months, converting numeric to string, 99
                                                      Mouse event handling, 211
                                                      Mouse events, 209
      M                                                     list of, 211
                                                            tracking, 211
      Machine type suffixes, 71                       Mouseout events, 211-212
      Machine types in JavaScript 2.0, 71-72          Mouseover events, 211-212, 274
      Macromedia Dreamweaver MX, 10-12, 291           Moveball() function, creating, 277
      Macromedia Flash files, 142                     Movies, embedding in web pages, 321-324
      Macromedia Flash plug-in, checking for, 255     Mozilla JavaScript Debugger, 292
      Macromedia HomeSite 5, 11-12                    Mozilla web browser, 8
      Mailto: protocol, 185                           MSDN CSS attributes reference guide, 268
      Main frame, 224                                 Multidimensional arrays, 107-115
      Manual line breaks (<br>), 263                  Music, embedding in web pages, 321-324
      Master array, 110-111                           Music objects, connecting to with JavaScript,
      Math class, 78                                   322-324
      Math class static constants, list of, 79
      Math object, 78
      Math object static methods, list of, 79-80      N
      Mathematical functions, 78
      Media objects, connecting to with JavaScript,   Named keyword, 60-61
       322-324                                        Named parameters, 60-61
      Media Player (Windows), 321                     NaN (Not a Number) constant, 71
Index       345

Navigator 4.0 (Communicator), 8                          accessing with [] operator, 73
Navigator object, 164, 254-256                           attaching functions to, 124-125
      appName property, 165                              attaching properties and methods to, 125-126
      appVersion property, 166, 168-169                  and code reuse, 308
      properties, 164-169, 255-256                       creating, 117-137
      userAgent property, 166, 168, 175                  creating as object literals, 122
Navigator 6, 8                                           creating in JavaScript 1.x, 118-126
Navigator 2.0 browser, 5-6                               creating in JavaScript 2.0, 126-137
Nested framesets, creating, 233-234                      creating from one constructor, 121
Nested loop, 42                                          creating using the new keyword, 129
NetObjects Fusion 7, 13                                  creating using an object literal, 123
Netscape Browser Central, 16                             defined, 67
Netscape Communications, 5                               extending, 125-126
Netscape Enterprise Server, 14                           setting default, 44-46
Netscape 4 web browser                                   testing, 308
      layers in, 169, 172-174                     Officially deprecated, explained, 145
      style sheets in, 273                        Onblur event (form), 188, 192
Netscape Navigator 4.0 (Communicator), 8          Onchange event (form), 188, 192
Netscape Navigator 6, 8                           Onclick event (button), 220, 320
Netscape Navigator 2.0 browser, 5-6               One-dimensional arrays, 107
Netscape Plug-In API, 314                         Onfocus event (form), 188, 192
Netscape 7.0, interpreting the <div> tag, 177     Onload event handler, 215-217, 226, 276-277
Netscape web browsers                             Onmouseout <img> tag attribute, 218
      error string, 298                           Onmouseover <img> tag attribute, 218
      navigator.appName property, 165             Onmouseover event handler, 211
      navigator.appVersion property, 166          Onpaste event handler, 221
      original DOM, 245                           Onpaste event (text box control), 221
      syntax for catch clauses, 302               Onreset event (form), 186
Netscape/iPlanet web servers, 142                 Onsubmit event (form), 186, 195-197
Never data type, 93                               Onunload event handler, 226
New keyword/operator, 69, 72, 78, 97,             Operands,defined, 27
  128-129, 301                                    Operating systems
Nodes (hierarchies of data), 246                         display settings, 256-257
Nonbreaking spaces (&nbsp), 263                          testing on all, 312
Nonstandard coding practices, 170                 Operators, 27, 50-51
Null data type, 93                                       JavaScript 2.0 new, 51
Number data type, 91                                     types of, 50
Number primitive, 91                              Outer frameset, 233
Numbers, converting strings into, 82-84
Numeric literals, assigning to a variable, 71
Numeric to string conversion, 99                  P
Numerical indexes, arrays with, 106               Parallel arrays, 109-110
                                                  Parameter lists in parentheses, 52
                                                  Parameters (to functions), 52, 54-56
O                                                        expressions as, 50
Object arrays, 113                                       named, 60-61
Object data type, 92                                     passed by value, 56
Object instantiation with the new operator, 72           unlimited number of, 61
Object literal, 122-123                                  unnamed, 61
Object methods. See Methods                       Parent class, defining, 130
Object models, JavaScript environments and, 244   Parent object (window), 253
Object properties. See Properties                 Parent-child relationship, 130
Object-oriented programming, 66-69, 118           Parentheses (), for function parameter lists, 52, 54
Objects, 44, 64-69                                ParseFloat() function, 82, 84
346      How to Do Everything with JavaScript

      ParseInt() function, 82-83
      Password box with asterisks displayed, 190
                                                            Q
      Pattern matching (regular expressions), 86-87         Question mark (?), in expression matching, 34
      PDF documents (Adobe Acrobat), 12, 142                Queue, 102
      PDF (Portable Document Format), 12, 142
      Perl language, 9
      Phrase elements (HTML 4.01), 148-149                  R
      Plug-ins                                              Real estate, 256
             defined, 314                                   RegExp object
             explained, 254                                       creating patterns with, 89-90
             list of URLs for, 314                                methods of, 89
             managing with JavaScript, 313-325              Regular expression language, 87-88
      Plugins array, 254                                    Regular expression literal, 89
      Polymorphism, 92, 133                                 Regular expressions, 86-90
      Pop-up dialog boxes, types of, 20                           pattern matching, 86-87
      Pop-up web advertisements, 254                              special tokens, 88-89
      Pop-up window, 254-255                                      syntax of, 88-89
      Position attributes (CSS), animation using, 276-277         uses for, 87
      Positioning elements on a Web page, 268-270           Reset event, 215
      Pound sign (#)                                        Resize event, 216
             for <form> action attribute, 186               Rest parameter (...), 61
             for RGB values, 262                            Re-throwing an exception, 305
      Practical Browser Sniffing Script, 168                Return statement, 53, 58-59
      Primitives, 91                                        Return values (function), 58, 297
      Privacy and the Internet, 190                         RGB (red-green-blue) values, 262
      Private class members, 136                            Rows attribute (<frameset> tag), 227-232
      Private keyword, 136                                  Rule selectors, 266-267
      Private properties and methods, 73                    Run-time errors, 283
      Procedural programming, 65-66, 308
      Procedures, 65
      Program errors, catching, 48-49
      Program flow, 29-30
                                                            S
      Programming methodologies, 65-68, 306                 Screen object, 256
      Programming terms, 27                                 Screen object properties, 256
      Properties, 44, 67                                    Screen size, 256
             accessing, 120, 128                            Screen space, resizing components based on, 256
             accessing with [] operator, 73                 Script, defined, 4
             adding to classes, 123-125                     Script Debugger (Microsoft), 293
             attaching to objects, 125-126                  Script debugging, disabling in IE, 284
             of a class, 68-69, 78                          Script Editor (Microsoft), 291
             creating by assigning a value, 126             Scriptable objects, inserting into web pages, 315
             inherited, 131, 134                            Scripting language, 14
             private, 73, 136                               Scroll bar (vertical), multiline text box with, 191
      Property names (JavaScript)                           Scroll event, 216
             case-sensitivity of, 122                       Scrollable pop-up window of multiple choices, 190
             vs. CSS attribute names, 272-273               Scrolled list box control, 189, 191
      Proprietary events, 221                               Search-and-replace, with regular expressions,
      Proprietary extensions, avoiding, 273                   86-90
      Proprietary markup tags, 170-171                      Security, private class members for, 136
      Prototype property, 123                               Select event, 216
      Prototyping, 123                                      Self object (window), 253
      Public class members, 136                             Semicolon (;)
      Public keyword, 136                                          for appending JavaScript commands, 159
      Public methods, calling, 137                                 statement ending, 100
      Push button control (form), 193-194, 220, 320, 323
Index      347

Server, defined, 8                                  Style sheet @import command, 267
Server-based web applications, creating, 8-9        Style sheet rules, 266
Server-side JavaScript (SSJS), 8, 14-15, 142        Style sheets, 150-153, 261
SetTimeout() function, 251                                 advantages of, 264
Show Details button (IE error message box), 284            creating, 276
Sibling nodes, 246                                         defining embedded, 266-267
Signed scripts, 8                                          vs. frames, 224
Single quotation mark ('), for string literal, 74          in Netscape 4 web browser, 273
Slash and asterisk (/*), for block comment, 44      Styles, 260
Special data types, 92-93                                  assigning using HTML elements, 261-263
Square brackets ([]) operator, 73, 96, 104-106             browser platform issues of, 272-273
Src attribute                                              changing for all pages at once, 267
       of <embed> tag, 321                                 importing external, 267
       of <frame> tag, 234                                 modifying using JavaScript, 270-272
       of <img> tag, 211                                   precedence of, 267
       of <script> tag, 157                                for text boxes, 271
SSL (Secure Sockets Layer), 190                            using style sheets for, 264-267
Standards. See W3C                                  Submit button, 193, 195-196
Starting tags (HTML), 142                                  disabling, 205
Statement block, 32                                        hyperlink to simulate, 219
Statements, 27, 30-49                               Submit event, 215
       categories of, 30                            Submit() method (<form> object), 219-220
       lists of JavaScript 1.5 and 2.0, 332         Sun Microsystems, 14, 317
Static (class) members, 68, 135                     Sunny Day Syndrome, 311
       defined, 78                                  Switch keyword, 33
       vs. instance members, 78                     Switch statement, 33-34
Static keyword, 135                                 Syntax errors, 283
StaticArray, creating, 112-113                      System classes, 63-93. See also Classes
StaticArray class, 112-113                          System errors, 46, 48
Status bar (browser), 253                           System objects (see also Objects)
Storing data, 26-29                                        in JavaScript 1.5, 333
Storing lists, 96                                          in JavaScript 2.0, 333
Strict HTML, explained, 146                         System testing, 312
Strict mode (error checking), 283
String class constructor, 76
String data type, 76, 91                            T
String literal, 74-75                               Tags (HTML). See HTML tags
       defined, 74                                  Templates (JavaScript), 16-19
       throw statement passing, 305-306                    body section, 19
String object                                              creating in Notepad, 16-17
       creating, 73-78                              Testing harness, creating, 309-311
       creating using string data type, 76          Testing your code, 282, 309-312
       creating using a string literal, 74-75       Text
       indexOf() method, 169                               animating, 277
       length property, 75                                 marking dynamic, 265
       methods, 76-77                                      preparing for sending to web server, 84-85
Strings, 27                                                writing to the browser window, 21-22
       converting into numbers, 82-84               Text area control, 193
       converting numbers to, 99                    Text block
       with invalid characters, 85                         explained, 265
       using as array indexes, 104                         naming, 269
       valid, 73                                    Text box control events, capturing, 197
       ways to create, 74
Style attribute of HTML elements, 265-266, 268
348       How to Do Everything with JavaScript

      Text box controls (form), 186-189                 Variables, 27, 67
             attributes, 187-188                               assigning numeric literals to, 71
             onpaste event, 221                                in classes, 68
             style of, 271                                     defined as machine types, 71
      Text editor, 9-10                                        defining, 27-29, 55
      Text formatting                                          number of defined by a program, 96
             HTML elements for, 148-150                        scope of, 56-58
             with style sheets, 150-153                        testing for existence of before accessing, 241
      This object, 119                                  VBScript (Visual Basic Script), 5, 9
      Three-dimensional arrays, 107                     Versions of JavaScript in different environments, 142
      Throw statement, 48-49, 297, 304-306              Vertical frames, defining, 230-231
      Time, keeping correctly updated, 250              Vertical scroll bar, multiline text box with, 191
      Timer events, animation effect using, 274         Visibility attribute, 270
      Today variable, 64                                Visual Studio .NET, 14
      Top object (window), 253                          Void data type, 92-93
      Transitional HTML, explained, 146
      Triggering events, 219-220
      Try clause, 297-304                               W
      Try-catch statement finally clause, 302-304       Web advertisements (pop-ups), 254
      Try-catch statements, 47-48, 297-304              Web browser address bar, 258
      Two-dimensional arrays, 107-110, 112              Web browser compatibility issues, 162-170
      Type attribute (<script> tag), 19                      of code, 171-177
                                                             of DHTML, 171
                                                             of events, 220-221
      U                                                      of styles, 272-273
      UL (ulong) suffix, 71                             Web browser DOMs, 162
      Unhandled exceptions, 303                         Web browser error messages, interpreting, 282
      Unicode character set, 214                        Web browser events
      Unload event, 215                                      explained, 158
      Unnamed parameters, 61                                 handling, 207-221
      Unsigned long (ulong/UL), 71                           supported by IE, 199
      Unstructured programming, 65, 307                 Web browser frames. See Frames (browser)
      Update_time() function, 250-251                   Web browser history list, 257-258
      URL format, 84                                    Web browser market features competition, 170
      URL string, characters in, 84                     Web browser plug-ins, managing, 313-325
      URLs (Uniform Resource Locators), 84              Web browser refresh, 258
      U.S. Postal Service change of address form, 181   Web browser sniffing code, 221
      User controls, in HTML, 180-181                   Web browser software properties, 254-256
      User ID and password, 190                         Web browser status bar, 253
      User information, gathering and processing, 180   Web browser timers, 251
      User input, requesting using HTML forms, 181      Web browser type, detecting, 164-169, 256
      User interface event handling, 209-210            Web browser usage statistics, 163
      User-friendly message, 48                         Web browser version
      User-input prompt box, 21                              detecting, 164
      Users, communicating with, 19-22                       knowing the minimum needed, 15
                                                        Web browser window, 252-254, 256-257
                                                        Web browsers
      V                                                      checking your code on, 312
      Valid JavaScript code, 287                             detecting, 164-169, 174, 256
      Validating parsers (validators), 287                   DOMs of, 14
      Value, defined, 27                                     first JavaScript-enabled, 6
      Var keyword, 27                                        getting for testing your code, 312
      Variable scope, 56-58                                  interacting with, 243-258
                                                             with no support for frames, 226-227
Index   349

      with no support for scripting, 154-156               resize() method, 257
      redirecting to a new web page, 258                   status property, 253
      reliance on external plug-ins, 315                   underlying DOM objects of, 253
      sending back to previous page(s), 257          Window objects (JavaScript), 236
      testing on all, 312                            Window.event keyCode attribute, 214
      using the latest release, 163                  Windows AVI files, 321
      web surfer use of, 162-163, 169                Windows environment, JavaScript in, 9
Web forms. See Forms (web)                           Windows Media Player, 321-322
Web page                                             Windows Script, 9
      adding JavaScript to, 153-154                  With statement, 44-46
      inserting HTML forms on, 184-199               WSH (Windows Scripting Host), 9
      JavaScript-enabled, 7                          W3C (World Wide Web Consortium), 8, 170
      positioning elements on, 268-270                     CSS Level 1 standard, 261
Web page content                                           CSS standard, 150, 261
      dynamically modifying, 249-251                       CSS validator service, 273
      manipulating, 248-252                                deprecated HTML tags, 145-146
      moving to animate, 276-278                           DOM Level 2 Events specification, 208
Web page elements                                          DOM standard, 8, 244
      making invisible, 270                                HTML validation service, 170
      positioning, 268-270                                 XHTML standard, 144
      sizing, 270
Web page style. See CSS; Style sheets; Styles
Web server                                           X
      preparing text for sending to, 84-85           XHTML, 144, 146, 235
      processing form input on, 183-184              XML document, addressing parts of, 247
Web server programming language, JavaScript as, 14   XML (Extensible Markup Language), 144
Web site framing, 235                                XPath, uses of, 247
Web standards. See W3C
Web surfers, browsers used by, 162-163, 169
Website Pros, 13                                     Z
While loop, 35-36, 287
While statements, checking the format of, 287        Zero length array, 97
Window object, 252-253                               ZVON.org web site, 225
      methods of, 254
      open() method, 254
INTERNATIONAL CONTACT INFORMATION

AUSTRALIA                                          SOUTH AFRICA
McGraw-Hill Book Company Australia Pty. Ltd.       McGraw-Hill South Africa
TEL +61-2-9900-1800                                TEL +27-11-622-7512
FAX +61-2-9878-8881                                FAX +27-11-622-9045
http://www.mcgraw-hill.com.au                      robyn_swanepoel@mcgraw-hill.com
books-it_sydney@mcgraw-hill.com
                                                   SPAIN
CANADA                                             McGraw-Hill/Interamericana de España, S.A.U.
McGraw-Hill Ryerson Ltd.                           TEL +34-91-180-3000
TEL +905-430-5000                                  FAX +34-91-372-8513
FAX +905-430-5020                                  http://www.mcgraw-hill.es
http://www.mcgraw-hill.ca                          professional@mcgraw-hill.es

GREECE, MIDDLE EAST, & AFRICA                      UNITED KINGDOM, NORTHERN,
(Excluding South Africa)                           EASTERN, & CENTRAL EUROPE
McGraw-Hill Hellas                                 McGraw-Hill Education Europe
TEL +30-210-6560-990                               TEL +44-1-628-502500
TEL +30-210-6560-993                               FAX +44-1-628-770224
TEL +30-210-6560-994                               http://www.mcgraw-hill.co.uk
FAX +30-210-6545-525                               computing_neurope@mcgraw-hill.com

MEXICO (Also serving Latin America)                ALL OTHER INQUIRIES Contact:
McGraw-Hill Interamericana Editores S.A. de C.V.   Osborne/McGraw-Hill
TEL +525-117-1583                                  TEL +1-510-549-6600
FAX +525-117-1589                                  FAX +1-510-883-7600
http://www.mcgraw-hill.com.mx                      http://www.osborne.com
fernando_castellanos@mcgraw-hill.com               omg_international@mcgraw-hill.com

SINGAPORE (Serving Asia)
McGraw-Hill Book Company
TEL +65-863-1580
FAX +65-862-3354
http://www.mcgraw-hill.com.sg
mghasia@mcgraw-hill.com

More Related Content

Similar to How To Do Everything With JavaScript (20)

Visual Studio 2008 Beginning Asp Net 3 5 In C# 2008 From Novice To Professi...
Visual Studio 2008   Beginning Asp Net 3 5 In C# 2008 From Novice To Professi...Visual Studio 2008   Beginning Asp Net 3 5 In C# 2008 From Novice To Professi...
Visual Studio 2008 Beginning Asp Net 3 5 In C# 2008 From Novice To Professi...
guest4c5b8c4
 
Java Complete Reference Fifth Edition
Java Complete Reference Fifth EditionJava Complete Reference Fifth Edition
Java Complete Reference Fifth Edition
umavanth
 
www.webre24h.com - [Wordware] advanced javascript, 3rd ed. - [easttom]
www.webre24h.com - [Wordware]   advanced javascript, 3rd ed. - [easttom]www.webre24h.com - [Wordware]   advanced javascript, 3rd ed. - [easttom]
www.webre24h.com - [Wordware] advanced javascript, 3rd ed. - [easttom]
webre24h
 
High Performance JavaScript Build Faster Web Application Interfaces 1st Editi...
High Performance JavaScript Build Faster Web Application Interfaces 1st Editi...High Performance JavaScript Build Faster Web Application Interfaces 1st Editi...
High Performance JavaScript Build Faster Web Application Interfaces 1st Editi...
yarecofuxxa58
 
Perceptive nolij web installation and upgrade guide 6.8.x
Perceptive nolij web installation and upgrade guide 6.8.xPerceptive nolij web installation and upgrade guide 6.8.x
Perceptive nolij web installation and upgrade guide 6.8.x
Kumaran Balachandran
 
Extending sap solutions to the mobile enterprise with ibm mobile first platfo...
Extending sap solutions to the mobile enterprise with ibm mobile first platfo...Extending sap solutions to the mobile enterprise with ibm mobile first platfo...
Extending sap solutions to the mobile enterprise with ibm mobile first platfo...
bupbechanhgmail
 
w_wile445.pdf
w_wile445.pdfw_wile445.pdf
w_wile445.pdf
ssuser5b2c3f
 
irmpg_3.7_python_202301.pdf
irmpg_3.7_python_202301.pdfirmpg_3.7_python_202301.pdf
irmpg_3.7_python_202301.pdf
FernandoBello39
 
The Total Book Developing Solutions With EPiServer 4
The Total Book Developing Solutions With EPiServer 4The Total Book Developing Solutions With EPiServer 4
The Total Book Developing Solutions With EPiServer 4
Martin Edenström MKSE.com
 
Modelsim Tuttranslate
Modelsim TuttranslateModelsim Tuttranslate
Modelsim Tuttranslate
guest2d20022
 
Plesk 8.3 for Linux/Unix Domain Administrator's Guide
Plesk 8.3 for Linux/Unix Domain Administrator's GuidePlesk 8.3 for Linux/Unix Domain Administrator's Guide
Plesk 8.3 for Linux/Unix Domain Administrator's Guide
webhostingguy
 
Plesk 8.3 for Linux/Unix Domain Administrator's Guide
Plesk 8.3 for Linux/Unix Domain Administrator's GuidePlesk 8.3 for Linux/Unix Domain Administrator's Guide
Plesk 8.3 for Linux/Unix Domain Administrator's Guide
webhostingguy
 
Plesk 8.3 for Linux/Unix Domain Administrator's Guide
Plesk 8.3 for Linux/Unix Domain Administrator's GuidePlesk 8.3 for Linux/Unix Domain Administrator's Guide
Plesk 8.3 for Linux/Unix Domain Administrator's Guide
webhostingguy
 
Plesk 8.3 for Linux/Unix Domain Administrator's Guide
Plesk 8.3 for Linux/Unix Domain Administrator's GuidePlesk 8.3 for Linux/Unix Domain Administrator's Guide
Plesk 8.3 for Linux/Unix Domain Administrator's Guide
webhostingguy
 
Programming.clojure
Programming.clojureProgramming.clojure
Programming.clojure
Kwanzoo Dev
 
[Web开发Css系列].Apress.Pro.Css.Techniques.Nov.2006
[Web开发Css系列].Apress.Pro.Css.Techniques.Nov.2006[Web开发Css系列].Apress.Pro.Css.Techniques.Nov.2006
[Web开发Css系列].Apress.Pro.Css.Techniques.Nov.2006
bmchaoshi
 
JavaScript 设计模式
JavaScript 设计模式JavaScript 设计模式
JavaScript 设计模式
guest97dcac3
 
Vba uk
Vba ukVba uk
Vba uk
Radio_56
 
full javascript Book by Abhishek singh.pdf
full javascript  Book by Abhishek singh.pdffull javascript  Book by Abhishek singh.pdf
full javascript Book by Abhishek singh.pdf
AbhishekSingh961152
 
Acro6 js guide
Acro6 js guideAcro6 js guide
Acro6 js guide
Faina Fridman
 
Visual Studio 2008 Beginning Asp Net 3 5 In C# 2008 From Novice To Professi...
Visual Studio 2008   Beginning Asp Net 3 5 In C# 2008 From Novice To Professi...Visual Studio 2008   Beginning Asp Net 3 5 In C# 2008 From Novice To Professi...
Visual Studio 2008 Beginning Asp Net 3 5 In C# 2008 From Novice To Professi...
guest4c5b8c4
 
Java Complete Reference Fifth Edition
Java Complete Reference Fifth EditionJava Complete Reference Fifth Edition
Java Complete Reference Fifth Edition
umavanth
 
www.webre24h.com - [Wordware] advanced javascript, 3rd ed. - [easttom]
www.webre24h.com - [Wordware]   advanced javascript, 3rd ed. - [easttom]www.webre24h.com - [Wordware]   advanced javascript, 3rd ed. - [easttom]
www.webre24h.com - [Wordware] advanced javascript, 3rd ed. - [easttom]
webre24h
 
High Performance JavaScript Build Faster Web Application Interfaces 1st Editi...
High Performance JavaScript Build Faster Web Application Interfaces 1st Editi...High Performance JavaScript Build Faster Web Application Interfaces 1st Editi...
High Performance JavaScript Build Faster Web Application Interfaces 1st Editi...
yarecofuxxa58
 
Perceptive nolij web installation and upgrade guide 6.8.x
Perceptive nolij web installation and upgrade guide 6.8.xPerceptive nolij web installation and upgrade guide 6.8.x
Perceptive nolij web installation and upgrade guide 6.8.x
Kumaran Balachandran
 
Extending sap solutions to the mobile enterprise with ibm mobile first platfo...
Extending sap solutions to the mobile enterprise with ibm mobile first platfo...Extending sap solutions to the mobile enterprise with ibm mobile first platfo...
Extending sap solutions to the mobile enterprise with ibm mobile first platfo...
bupbechanhgmail
 
irmpg_3.7_python_202301.pdf
irmpg_3.7_python_202301.pdfirmpg_3.7_python_202301.pdf
irmpg_3.7_python_202301.pdf
FernandoBello39
 
The Total Book Developing Solutions With EPiServer 4
The Total Book Developing Solutions With EPiServer 4The Total Book Developing Solutions With EPiServer 4
The Total Book Developing Solutions With EPiServer 4
Martin Edenström MKSE.com
 
Modelsim Tuttranslate
Modelsim TuttranslateModelsim Tuttranslate
Modelsim Tuttranslate
guest2d20022
 
Plesk 8.3 for Linux/Unix Domain Administrator's Guide
Plesk 8.3 for Linux/Unix Domain Administrator's GuidePlesk 8.3 for Linux/Unix Domain Administrator's Guide
Plesk 8.3 for Linux/Unix Domain Administrator's Guide
webhostingguy
 
Plesk 8.3 for Linux/Unix Domain Administrator's Guide
Plesk 8.3 for Linux/Unix Domain Administrator's GuidePlesk 8.3 for Linux/Unix Domain Administrator's Guide
Plesk 8.3 for Linux/Unix Domain Administrator's Guide
webhostingguy
 
Plesk 8.3 for Linux/Unix Domain Administrator's Guide
Plesk 8.3 for Linux/Unix Domain Administrator's GuidePlesk 8.3 for Linux/Unix Domain Administrator's Guide
Plesk 8.3 for Linux/Unix Domain Administrator's Guide
webhostingguy
 
Plesk 8.3 for Linux/Unix Domain Administrator's Guide
Plesk 8.3 for Linux/Unix Domain Administrator's GuidePlesk 8.3 for Linux/Unix Domain Administrator's Guide
Plesk 8.3 for Linux/Unix Domain Administrator's Guide
webhostingguy
 
Programming.clojure
Programming.clojureProgramming.clojure
Programming.clojure
Kwanzoo Dev
 
[Web开发Css系列].Apress.Pro.Css.Techniques.Nov.2006
[Web开发Css系列].Apress.Pro.Css.Techniques.Nov.2006[Web开发Css系列].Apress.Pro.Css.Techniques.Nov.2006
[Web开发Css系列].Apress.Pro.Css.Techniques.Nov.2006
bmchaoshi
 
JavaScript 设计模式
JavaScript 设计模式JavaScript 设计模式
JavaScript 设计模式
guest97dcac3
 
full javascript Book by Abhishek singh.pdf
full javascript  Book by Abhishek singh.pdffull javascript  Book by Abhishek singh.pdf
full javascript Book by Abhishek singh.pdf
AbhishekSingh961152
 

How To Do Everything With JavaScript

  • 1. www.GetPedia.com *More than 150,000 articles in the search database *Learn how almost everything works
  • 5. JavaScript Scott Duffy McGraw-Hill/Osborne New York Chicago San Francisco Lisbon London Madrid Mexico City Milan New Delhi San Juan Seoul Singapore Sydney Toronto
  • 6. McGraw-Hill/Osborne 2600 Tenth Street Berkeley, California 94710 U.S.A. To arrange bulk purchase discounts for sales promotions, premiums, or fund-raisers, please contact McGraw-Hill/Osborne at the above address. For information on translations or book distributors outside the U.S.A., please see the International Contact Information page immediately following the index of this book. How to Do Everything with JavaScript Copyright © 2003 by The McGraw-Hill Companies. All rights reserved. Printed in the United States of America. Except as permitted under the Copyright Act of 1976, no part of this publication may be reproduced or distributed in any form or by any means, or stored in a database or retrieval system, without the prior written permission of publisher, with the exception that the program listings may be entered, stored, and executed in a computer system, but they may not be reproduced for publication. 1234567890 FGR FGR 019876543 ISBN 0-07-222887-3 Publisher: Brandon A. Nordin Vice President & Associate Publisher: Scott Rogers Acquisitions Editor: Megg Morin Project Editors: Leslie Tilley, Madhu Prasher Acquisitions Coordinator: Tana Allen Technical Editor: Warren Raquel Copy Editor: Leslie Tilley Proofreader: Paul Tyler Indexer: Valerie Robbins Computer Designers: Carie Abrew, Lucie Ericksen Illustrators: Melinda Lytle, Michael Mueller, Lyssa Wald Series Design: Mickey Galicia Cover Series Design: Dodie Shoemaker Cover Illustration: Eliot Bergman This book was composed with Corel VENTURA™ Publisher. Information has been obtained by McGraw-Hill/Osborne from sources believed to be reliable. However, because of the possibility of human or mechanical error by our sources, McGraw-Hill/Osborne, or others, McGraw-Hill/Osborne does not guarantee the accuracy, adequacy, or completeness of any information and is not responsible for any errors or omissions or the results obtained from the use of such information.
  • 7. This book is dedicated to: My wife, Liez’l. Words cannot adequately express how important you are to my life. My mother, who taught me the true meaning of strength and perseverance. God bless. My father, who at this very moment is surely telling the angel next to him, “That’s my son.” I miss you, Dad.
  • 8. About the Author Scott Duffy has been providing IT consulting services to medium- and large-sized businesses and government organizations for more than six years. Before embarking on a career as a consultant, Scott worked at two of the largest corporations in Canada as a software developer. His 12 years of professional experience cover a wide range of platforms and technologies, including programming in mainframe, client-server, and web-based application environments. He is actively involved in every stage of the software development process, including team management. When he’s not designing software applications for clients, Scott keeps himself busy with his writing projects. He is currently working on his next book for McGraw-Hill/Osborne, a study guide for the Microsoft MCSD 70-300 exam. To contact Scott to discuss your organization’s business needs, or about any other matter, please e-mail him at [email protected] or visit his web site at http://www.mydemos.com.
  • 9. Contents at a Glance Part I Learn JavaScript Basics 1 Prepare to Program in JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2 Learn JavaScript Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 3 Use Built-in JavaScript Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 4 Organize Data into Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 5 Create Your Own JavaScript Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Part II Build JavaScript-Enabled Web Sites 6 Embed JavaScript in a Web Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 7 Create Scripts That Work in Every Browser . . . . . . . . . . . . . . . . . . . . . . . . 161 8 Manipulate Web Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 9 Handle Browser Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 10 Communicate Between Browser Frames . . . . . . . . . . . . . . . . . . . . . . . . . . 223 11 Interact with the Web Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 12 Perform Simple Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 Part III Take JavaScript to the Next Level 13 Debug JavaScript Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 14 Make Your Program Errorproof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295 15 Use JavaScript to Manage Browser Plug-Ins . . . . . . . . . . . . . . . . . . . . . . . 313 A HTML 4.01 Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327 B JavaScript Quick Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331 Index ..................................................... 335 vii
  • 11. Contents Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii PART I Learn JavaScript Basics CHAPTER 1 Prepare to Program in JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Learn the History of JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 The Origin of JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 JavaScript Makes Its Way into Internet Explorer . . . . . . . . . . . . . 5 JavaScript Becomes an Official Standard . . . . . . . . . . . . . . . . . . . 5 Where JavaScript Is Today . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Choose a Development Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Develop JavaScript-Enabled Web Pages . . . . . . . . . . . . . . . . . . . 7 Create Server-Based Web Applications . . . . . . . . . . . . . . . . . . . . 8 Use JavaScript in a DOS or Windows Environment . . . . . . . . . . 9 JavaScript Development Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Learn What JavaScript Can and Cannot Do . . . . . . . . . . . . . . . . . . . . . . 13 Use JavaScript as a Client-Side Language . . . . . . . . . . . . . . . . . . 14 Use JavaScript as a Server-Side Language . . . . . . . . . . . . . . . . . . 14 Decide Which Version of JavaScript to Use . . . . . . . . . . . . . . . . . . . . . . 15 Test JavaScript Programs Using HTML . . . . . . . . . . . . . . . . . . . . . . . . . 16 Create a JavaScript Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 Understand the JavaScript Template . . . . . . . . . . . . . . . . . . . . . . 18 Communicate with the User . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Display an Alert Message . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 Write Text to the Browser Window . . . . . . . . . . . . . . . . . . . . . . . 21 Learn More about Topics Discussed in this Chapter . . . . . . . . . . . . . . . . 22 CHAPTER 2 Learn JavaScript Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Understand Basic Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 ix
  • 12. x How to Do Everything with JavaScript Store Data in Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 Define Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 Define Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 Understand Program Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 Control Program Flow with Statements . . . . . . . . . . . . . . . . . . . . . . . . . 30 Execute Code Conditionally . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 Repeat Statements Using Loops . . . . . . . . . . . . . . . . . . . . . . . . . . 34 Comment Your Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 Set a Default Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 Handle Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 Understand the Basics of Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . 49 Use Operators to Create Complex Expressions . . . . . . . . . . . . . . . . . . . 50 Organize Your Code into Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 Define Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 Accept Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 Understand Variable Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 Return Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 Use the Improvements in JavaScript 2.0 to Create More Powerful Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 Use Named Optional Parameters . . . . . . . . . . . . . . . . . . . . . . . . . 60 Accept Any Number of Parameters . . . . . . . . . . . . . . . . . . . . . . . 61 CHAPTER 3 Use Built-in JavaScript Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 Learn about Objects in JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 Write Unstructured Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 Organize Code into Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . 65 Separate a Program into Modules . . . . . . . . . . . . . . . . . . . . . . . . . 66 Use the Object-Oriented Approach . . . . . . . . . . . . . . . . . . . . . . . 66 Turn Properties and Functions into a Class . . . . . . . . . . . . . . . . . 68 JavaScript’s Built-in Classes and Data Types . . . . . . . . . . . . . . . . . . . . 69 Instantiate an Object with the new Operator . . . . . . . . . . . . . . . . 72 Access an Object with the . Operator . . . . . . . . . . . . . . . . . . . . . . 73 Access an Object with the [] Operator . . . . . . . . . . . . . . . . . . . . . 73 Create a String Object in JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 Create a String Object Using a String Literal . . . . . . . . . . . . . . . . 74 Create a String Object Using the String Data Type . . . . . . . . . . . 76 Use the String Object’s Built-in Functionality . . . . . . . . . . . . . . . 76 Perform Mathematical Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 Apply JavaScript’s Date-Handling Functions . . . . . . . . . . . . . . . . . . . . . 79 Convert Strings into Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 Use the parseInt and parseFloat Functions . . . . . . . . . . . . . . . . . . 82 Prepare Text Before Sending to Web Server . . . . . . . . . . . . . . . . . . . . . . 84 Use the escape and unescape Functions . . . . . . . . . . . . . . . . . . . . 85
  • 13. Contents xi Decide When to Use Regular Expressions . . . . . . . . . . . . . . . . . . . . . . . 86 Understand the Basics of Regular Expressions . . . . . . . . . . . . . . 87 Create Patterns with a RegExp Object . . . . . . . . . . . . . . . . . . . . . 89 Understand JavaScript 2.0’s Powerful New Data Types . . . . . . . . . . . . . 91 Use the Boolean, Integer, and Number Data Types . . . . . . . . . . . 91 Use the char Data Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 Use the Object Data Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 Understand Special Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . 92 CHAPTER 4 Organize Data into Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 Create an Array Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 Create an Empty Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 Specify an Initial Array Length . . . . . . . . . . . . . . . . . . . . . . . . . . 99 Create and Initialize an Array in One Line of Code . . . . . . . . . . . 100 Use Array Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 Call the Properties and Methods of the Array Object . . . . . . . . . 101 Set and Retrieve Values in an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 Use Multidimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 Use JavaScript 2.0’s Enhanced Arrays . . . . . . . . . . . . . . . . . . . . . 111 The StaticArray Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 The DynamicArray Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 The ConstArray Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 CHAPTER 5 Create Your Own JavaScript Classes . . . . . . . . . . . . . . . . . . . . . . . . 117 Learn about Classes in JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 Create Objects in JavaScript 1.x . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 Call a Constructor Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 Use an Object Literal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 Extend an Existing Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 Extend an Existing Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 Create Objects in JavaScript 2.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 Define Your Own Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 Organize Classes Using Inheritance . . . . . . . . . . . . . . . . . . . . . . . 130 Choose Between Static and Instance Members . . . . . . . . . . . . . . 135 Make Class Members Public or Private . . . . . . . . . . . . . . . . . . . . 136 PART II Build JavaScript-Enabled Web Sites CHAPTER 6 Embed JavaScript in a Web Page . . . . . . . . . . . . . . . . . . . . . . . . . . 141 Understand Basic HTML Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 Build an HTML Document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 Indicate the Document Type with <!DOCTYPE> . . . . . . . . . . . . 146
  • 14. xii How to Do Everything with JavaScript Add a Title and Define Document Keywords . . . . . . . . . . . . . . . . 147 Format Text with HTML Elements . . . . . . . . . . . . . . . . . . . . . . . 148 Format Text with Style Sheets . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 Use <script> to Add JavaScript to a Web Page . . . . . . . . . . . . . . . . . . . . 153 Use <noscript> for Browsers That Don’t Support Scripting . . . . . . . . . . 154 Load an External JavaScript File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 Call JavaScript Using Hyperlinks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 Learn More about the Topics in this Chapter . . . . . . . . . . . . . . . . . . . . . 159 CHAPTER 7 Create Scripts That Work in Every Browser . . . . . . . . . . . . . . . . . . 161 Understand Browser Differences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 What Kind of Errors Can Occur? . . . . . . . . . . . . . . . . . . . . . . . . . 163 Detect What Type of Browser the User Is Running . . . . . . . . . . . 164 Query the Document Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 Stick to Web Standards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 Write Cross-Browser Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 CHAPTER 8 Manipulate Web Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 Understand HTML Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 Request User Input Using an HTML Form . . . . . . . . . . . . . . . . . 181 Process Form Input with Client-Side JavaScript . . . . . . . . . . . . . 182 Process Form Input on a Web Server . . . . . . . . . . . . . . . . . . . . . . 183 Insert an HTML Form into a Web Page . . . . . . . . . . . . . . . . . . . . 184 Retrieve and Set Form Control Values in JavaScript . . . . . . . . . . . . . . . . 200 Access Form Values Using the forms Array . . . . . . . . . . . . . . . . 200 Access Form Values Using the elements Array . . . . . . . . . . . . . . 202 Access Form Values Using getElementById() . . . . . . . . . . . . . . . 204 Access Form Values Using getElementsByName() . . . . . . . . . . . 204 Access Form Values Using getElementsByTagName() . . . . . . . . 205 CHAPTER 9 Handle Browser Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 Write JavaScript Event Handlers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 Handle User Interface Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 Handle Mouse Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 Handle Key Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 Handle HTML Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 Handle Events Using the Event Property . . . . . . . . . . . . . . . . . . . . . . . . 218 Trigger Events in JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 Call the Method Associated with an Event . . . . . . . . . . . . . . . . . 219 Use the fireEvent Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 Overcome Browser Incompatibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
  • 15. Contents xiii CHAPTER 10 Communicate Between Browser Frames . . . . . . . . . . . . . . . . . . . . . 223 Learn the Basics of HTML Frames . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 Create a Frameset in HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 Define and Name Frames in a Frameset . . . . . . . . . . . . . . . . . . . . 233 Call JavaScript Functions from Other Frames . . . . . . . . . . . . . . . . . . . . 235 Access Another Frame Using JavaScript . . . . . . . . . . . . . . . . . . . 236 Call a JavaScript Function Located in Another Frame . . . . . . . . . 237 Handle Synchronization Between Frames . . . . . . . . . . . . . . . . . . . . . . . 239 CHAPTER 11 Interact with the Web Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 Learn the Basics of the Document Object Model . . . . . . . . . . . . . . . . . . 245 Manipulate the Contents of a Web Page . . . . . . . . . . . . . . . . . . . . . . . . . 248 Dynamically Modify the Contents of a Web Page . . . . . . . . . . . . 249 Change the Items in a Drop-Down List Box . . . . . . . . . . . . . . . . 251 Examine the Entire Browser Window . . . . . . . . . . . . . . . . . . . . . . . . . . . 252 Retrieve Properties of the Web Browser Software . . . . . . . . . . . . . . . . . 254 Examine the Operating System’s Display Settings . . . . . . . . . . . . . . . . . 256 Access the Web Browser History List . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 Send the Browser to a New Location . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 CHAPTER 12 Perform Simple Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 Learn the Basics of Cascading Style Sheets . . . . . . . . . . . . . . . . . . . . . . 260 Assign Style to Web Pages Using HTML Elements . . . . . . . . . . 261 Assign Style to Web Pages Using Style Sheets . . . . . . . . . . . . . . 264 Use Basic Style Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268 Position Elements on a Web Page . . . . . . . . . . . . . . . . . . . . . . . . 268 Modify Styles Using JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . 270 Understand Cross-Platform Issues . . . . . . . . . . . . . . . . . . . . . . . . 272 Perform Basic Animation Using JavaScript . . . . . . . . . . . . . . . . . . . . . . 274 Dynamically Load Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274 Make Content Move Around the Screen . . . . . . . . . . . . . . . . . . . 276 PART III Take JavaScript to the Next Level CHAPTER 13 Debug JavaScript Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 Understand the Possible Causes of Errors . . . . . . . . . . . . . . . . . . . . . . . . 282 Find the Source of an Error Message . . . . . . . . . . . . . . . . . . . . . . 284 Interpret Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 Use a JavaScript Validator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 Add Debugging Code to Your Programs . . . . . . . . . . . . . . . . . . . . . . . . . 287 Use the JavaScript Console . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290 Use a JavaScript Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
  • 16. xiv How to Do Everything with JavaScript CHAPTER 14 Make Your Program Errorproof . . . . . . . . . . . . . . . . . . . . . . . . . . . 295 Learn the Basics of Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296 Catch Exceptions Using the try and catch Statements . . . . . . . . . . . . . . 297 Understand Exception Bubbling . . . . . . . . . . . . . . . . . . . . . . . . . . 299 Use the IE Error Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301 Use Netscape-Only catch Clauses . . . . . . . . . . . . . . . . . . . . . . . . 302 Use Nonstandard finally Clauses . . . . . . . . . . . . . . . . . . . . . . . . . 302 Create Exceptions Using the throw Statement . . . . . . . . . . . . . . . . . . . . 304 Design Programs That Are Easy to Debug from the Start . . . . . . . . . . . 306 Avoid Unstructured Programming . . . . . . . . . . . . . . . . . . . . . . . . 307 Break Code into Manageable Chunks . . . . . . . . . . . . . . . . . . . . . 307 Reuse Code Using Classes and Objects . . . . . . . . . . . . . . . . . . . . 308 Test Your JavaScript Code Thoroughly . . . . . . . . . . . . . . . . . . . . . . . . . . 309 Create a Testing Harness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309 Force Errors to Test Error-Handling Code . . . . . . . . . . . . . . . . . . 311 Try Your Program in Many Different Environments . . . . . . . . . . 312 CHAPTER 15 Use JavaScript to Manage Browser Plug-Ins . . . . . . . . . . . . . . . . . . 313 Insert Scriptable Objects into HTML Web Pages . . . . . . . . . . . . . . . . . . 315 Include Sun Java Applets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 Connect to Java Applets Using JavaScript . . . . . . . . . . . . . . . . . . 319 Embed Movies and Music in Web Pages . . . . . . . . . . . . . . . . . . . . . . . . 321 Connect to Music and Media Objects Using JavaScript . . . . . . . 322 Use the Microsoft Calendar Control in Your Web Pages . . . . . . . . . . . . 324 APPENDIX A HTML 4.01 Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327 APPENDIX B JavaScript Quick Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331 Index ................................................... 335
  • 17. Acknowledgments Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. —Rich Cook I very much appreciate the efforts of everyone who was involved in getting this book published. I certainly don’t want to imagine what would have been created had I been left to my own devices. I am extremely happy with how this book turned out, and I owe a great debt of gratitude to many people for that: Megg Morin, my acquisitions editor at Osborne. Thank you for all your help in developing the concept and for giving the book the strong push in the right direction that it needed at the beginning. Leslie Tilley, my copy editor and project editor. Thank you, thank you, thank you. I really appreciate your hard work and attention to detail. You’re the primary reason this book turned out so well. Tana Allen, my acquisitions coordinator. Thanks for keeping the project on track. Madhu Prasher. Thanks for doing what you do so well. It’s always good to meet someone who loves her job. Warren Raquel, my technical editor. Thanks for your diligent efforts. Jawahara Saidullah, my agent at Waterside Productions. Thanks for getting me this gig and hopefully many more to come. And last but not least, my wife Liez’l. With you beside me, I can climb mountains and slay dragons. xv
  • 19. Introduction Netscape introduced JavaScript with great fanfare in December 1995 as an “open, cross-platform object scripting language.” It was billed as the perfect complement to the much-anticipated Java programming language, since the two languages can communicate with each other inside a browser window. Today, almost 10 years later, JavaScript is ubiquitous across the Internet landscape. It is estimated that 25 percent of web pages on the Internet today contain JavaScript code. Some of them use that code to perform some very basic scripting effects, such as controlling mouse rollovers and setting the browser status bar. Many of them contain complex dynamic menus and automated forms. No other scripting language comes close to JavaScript’s domination of the web browser environment. The key to JavaScript’s success has been its ease of use. For instance, a single JavaScript statement can create an interesting browser effect, and a small handful of statements is all that’s required for a completely interactive browser environment. You don’t even need any special tools to create these effects. A simple text editor, such as Windows Notepad, is all that is required. If you can create HTML web pages, you have all the tools you’ll need to get started. With the impending release of version 2.0, JavaScript will finally be usable side by side with programming languages such as C++ and Visual Basic. For instance, Microsoft has included a version of JavaScript 2.0, called JScript .NET, in its popular .NET programming environment. JScript .NET can access almost all the .NET Framework classes and can be used to create Windows Forms applications that run on your desktop. In fact, the next new word processor you use may be coded entirely in JavaScript. Who Should Read This Book This book is designed to help anyone interested in adding elements of interactivity to their personal web pages. Some experience with a PC is required, as we will not cover how to access the Internet or how to use a web browser. You don’t have to be an HTML expert, although it will help if you have some experience with that language. When encountering new HTML for the first time, I will briefly explain what’s going on, but always in the context of JavaScript. xvii
  • 20. xviii How to Do Everything with JavaScript How This Book Is Organized How to Do Everything with JavaScript is organized into three main sections. Each section focuses on a different set of JavaScript skills: Part I Chapters 1–5 take you through the basics of JavaScript. This part covers the fundamental aspects of the programming languages, including statements, objects, and data types. Part II Chapters 6–12 show you how to integrate JavaScript into a web site. This part looks at using JavaScript with the Document Object Model, browser events, frames, and web forms. Part III Chapters 13–15 cover advanced JavaScript topics. This part deals with debugging a JavaScript program, errorproofing code, and communicating with other objects embedded in a web page. Often, the best way to learn a programming language like JavaScript is to play around with it. Don’t be afraid to try some of the JavaScript examples in the book yourself. Type them in and change them to something of your own design—you will gain a better understanding of how things work. Ask yourself, “What will happen if I do this instead?” Then go ahead and try it— nothing can go seriously wrong. The worst that can happen is that something you try doesn’t work. And that’s OK. Simply shrug your shoulders and try again.
  • 21. Learn Part I JavaScript Basics
  • 23. Prepare to Chapter 1 Program in JavaScript
  • 24. 4 How to Do Everything with JavaScript How to... ■ Choose a development environment ■ Learn what JavaScript can and cannot do ■ Decide which version of JavaScript to use ■ Test JavaScript programs using HTML ■ Use the HTML <script> tag ■ Create a JavaScript template with Microsoft Notepad ■ Communicate with the user Behind every successful movie, there is a person behind the scenes who governs the interaction of actors, camera operators, writers, and other crew members. This is the director, and although you don’t usually see this person on screen, the quality of the movie rests on the success of his or her efforts. Well, JavaScript is the behind-the-scenes “director” of many Internet web sites. Its job is to govern the interaction of objects and events so that the two interact seamlessly with one another. Generally, the more complex the web site, the more it relies on JavaScript to direct. Lights! Camera! Browser! Action! Perhaps the first question that needs to be asked about JavaScript is, what is it? The simplest answer is that JavaScript is a simple programming language, used mainly to bring interactivity to web sites. It is often called a scripting language, hence the name, but it also has a nonscripting form. A script, in programming terminology, is a program that does not need to be compiled in order to run. Scripts tend to perform a specific task and then exit, and do not generally have a graphical user interface (GUI) to speak of. JavaScript, Perl, and VBScript are the most common scripting languages used by Internet web sites. Learn the History of JavaScript JavaScript was born out of the need to coordinate HTML (Hypertext Markup Language) web pages with embedded content such as Java applets. But JavaScript is used for much more than that. It is often used to help users fill out online forms, provide web site navigation through dynamic menus, and power e-commerce shopping carts. In fact, it is said that 25 percent of all web sites today use JavaScript in one way or another. Although most (99.5 percent or more) of the web browser software in use today has built-in support for JavaScript, users can choose to turn off that support. When designing web sites for everybody to see on the Internet, it’s important to remember that some people won’t “see” JavaScript. Considering how rapidly other web-related technologies have been changing to incorporate new features, JavaScript has been fairly stable. It has taken JavaScript eight years to progress
  • 25. CHAPTER 1: Prepare to Program in JavaScript 5 from its initial 1.0 release to the next major version, 2.0. Some feel that this slow pace has been both a blessing and a curse to the language. 1 The blessing is that JavaScript support is fairly consistent across multiple browser makers and version numbers. Web developers can implement one JavaScript program and not have to worry too much about compatibility issues (other than avoiding certain incompatible coding techniques). JavaScript has gained such widespread adoption mainly because developers can trust that it will work. The curse is that while JavaScript has been standing still, other languages have emerged to fill the technical void. It is far more common to see web sites that use Visual Basic Script (VBScript) or Java Server Pages (JSP) as a server-side web scripting language instead of JavaScript. In fact, a recent release of a popular web server software (iPlanet Web Server) has dropped JavaScript support altogether. This could change, however, as JavaScript 2.0 catches developers’ attention. The Origin of JavaScript JavaScript made its first appearance in Netscape 2.0 in 1995. JavaScript was originally designed to help integrate HTML pages with Java applets—Java applications embedded in web pages. Developers quickly realized its true potential, though, and soon JavaScript was being used to add interactivity to web sites—most of the time without the help of Java. Figure 1-1 shows Navigator 2.0, the first JavaScript-enabled web browser. JavaScript Makes Its Way into Internet Explorer Soon after Netscape Communications first introduced JavaScript in its Navigator 2.0 browser, Microsoft realized the importance of incorporating this language into its Internet Explorer browser. Since Netscape was not exactly going to mail Microsoft the source code, and even the language specification was a well-guarded secret, Microsoft was forced to reverse engineer JavaScript to create its own version. Microsoft named its version JScript, since Netscape owned the trademark on the word JavaScript. Early versions of JScript did not perform certain functions in exactly the same way JavaScript did, and so JavaScript incompatibility between the browsers was something developers often had to take into account when scripting their web pages. JavaScript Becomes an Official Standard In the early days of the Web, cross-browser compatibility was a big issue—a lot bigger than it is today. The two main browser companies were making changes to the HTML and JavaScript languages to try to gain a competitive advantage over each other, causing massive headaches for web developers trying to create web sites that supported both browsers. Luckily for us, both companies relented. Netscape wisely turned JavaScript standardization over to the European Computer Manufacturers Association (ECMA) in 1996. The ECMA concentrated on standardizing the core language, but left other things (such as the JavaScript Document Object Model, or DOM) to the browser makers. The result was that incompatibilities continued to exist between the browsers.
  • 26. 6 How to Do Everything with JavaScript FIGURE 1-1 What the Web looked like in 1995, through the eyes of Navigator 2.0 The ECMA released their standardized scripting language known as ECMAScript in 1997. They updated the standard twice in the two years that followed, calling the updates Edition 2 and Edition 3. JavaScript 1.5 conforms to Edition 3 of the standard. Where JavaScript Is Today The ECMAScript Edition 4 standard will be the first update to be released in over four years. JavaScript 2.0 conforms to Edition 4 of the ECMAScript standard, and the difference between the two is extremely minor. The specification for JavaScript 2.0 can be found on the Mozilla.org web site: http://www.mozilla.org/js/language/js20/index.html. Today, Netscape’s JavaScript and Microsoft’s JScript conform to the ECMAScript standard, although each language still supports features that are not part of the standard.
  • 27. CHAPTER 1: Prepare to Program in JavaScript 7 JavaScript Version Date Released Browsers Standards Compliance 1 1.0 December 1995 Navigator 2, Internet Explorer 3 No 1.1 April 1996 Navigator 3 Partially, with ECMAScript 1 1.2 December 1996 Navigator 4, Internet Explorer 4 Partially, with ECMAScript 1 1.3 August 1998 Navigator 4.06, Internet ECMAScript 1, ISO-16262 Explorer 5 1.4 October 1998 Version 1.4 did not appear in ECMAScript 1, ISO-16262 any web browser 1.5 April 2000 Navigator 6 and 7, Internet ECMAScript 3 Explorer 5.5 and 6, Mozilla 1 2.0 2003 ECMAScript 4 TABLE 1-1 Chronology of JavaScript Releases Table 1-1 contains a chronological list of JavaScript versions, including a short list of popular browsers that supported each one. The exact release date of JavaScript 2.0 and version numbers of the browsers that will support it were not yet determined at the time this was written. Choose a Development Environment One of JavaScript’s biggest strengths is its support on many different platforms, often for different purposes. The most common type of JavaScript application today is one that runs inside a web browser, as a client-side script. JavaScript has long been supported as a web server-side language as well, in popular environments such as IIS and LiveWire. Recently, developers have had even more choices for using JavaScript in different environments. In this section, we will take a look at how JavaScript is used in each of these environments. None of them supports JavaScript 2.0 yet, but it is still important to look at the potential environments that will, since support will probably be introduced in the near future. Also in this section, we will discuss development environments for JavaScript developers. In the first few years of JavaScript’s existence, developers had to create their JavaScript programs using only a text editor, without the aid of integrated development environments (IDEs)—and many still do. But as HTML development tools evolved, many added development support for the world’s most popular scripting language. And today this support exists in all the big tools, as we will see later on in this section. Develop JavaScript-Enabled Web Pages Applications that are designed to run inside a browser are by far the most popular use for JavaScript. JavaScript was given very strong integration into the web browser environment through the DOM. Netscape introduced the original DOM in JavaScript 1.0.
  • 28. 8 How to Do Everything with JavaScript The Client-Server Analogy In web-development terminology, the web browser and the computer it runs on are often called the client. Similarly, the web server software and the computer it runs on are called the server. Thus, the term client-side JavaScript refers to JavaScript programs that are embedded inside a web page and run on the client machine. JavaScript that runs on the server machine is referred to as server-side JavaScript. Fairly soon thereafter, control of the DOM was handed over to the World Wide Web Consortium (W3C), a standards organization. The DOM standard has evolved from dealing with how JavaScript interacts with a browser to dealing with standard ways to create, read, and modify HTML and XML documents. The W3C (http://www.w3.org) specializes in web standards, including HTML, XML, DOM, and Cascading Style Sheets (CSS). The various documents related to the DOM standards can be viewed at http://www.w3.org/DOM/DOMTR. It’s important to note that the original DOM (sometimes called Level 0) is not an official standard. JavaScript applications that are designed to run inside a browser are subject to a number of security restrictions. These applications generally do not have access to the user’s hard drive or any installed applications on the user’s computer. For users, this means a JavaScript application generally poses no security risk, as it cannot contain a virus or other malicious code. Netscape Navigator 4.0 (also known as Communicator) introduced the concept of signed scripts. A script that has been signed using a secure digital key can request additional privileges within the browser environment, such as the ability to send e-mail or read a file from the hard disk. Often the browser would prompt the user to ask if they will allow the script such privilege. The Mozilla web browser, and its cousin Navigator 6, changed the way signed scripts are handled in a way that is no longer compatible with Navigator 4. Microsoft Internet Explorer (IE) handles security completely differently (using trusted zones, for instance). As a result of these heterogeneous security solutions, there still is no standard way to write JavaScript applications that have expanded privileges. In practice, signed JavaScript is rarely used. Client-side application development is still very much one of JavaScript’s core strengths. Developers actually risk incompatibility with many operating systems and web browsers by choosing any language other than JavaScript for their client-side development! Create Server-Based Web Applications Although JavaScript dominates all other languages when it comes to web-client programming, that is not the case with server-side programming. JavaScript was one of the first server-side
  • 29. CHAPTER 1: Prepare to Program in JavaScript 9 languages supported (back in 1996, when Netscape released its web server platform), but it was unable to use that head start to its advantage. Perl quickly became a popular server-side scripting 1 tool, and several other languages have emerged (including VBScript in the ASP environment, PHP, and JSP) as popular alternatives. One of the reasons server-side languages vary so much is that the server environment can be controlled to a certain extent by web developers. In most cases, developers have very little control over the browsers people use. So while the choice of client-side programming language is really a “lowest common denominator” decision (which language is supported by the most browsers), the choice on the server is whatever the developer wants to use. For some developers, getting to choose the programming language is like being a kid in a candy store. There are many server-side programming languages to choose from, and no real reason to choose one over another except personal preference. Use JavaScript in a DOS or Windows Environment For a long time now, Microsoft has been providing the Windows Script Host (WSH) tools as a free add-on to Windows as a download from its web site. WSH includes the latest versions of Microsoft’s two scripting languages—VBScript and JScript. With WSH, you can create a small program in JScript that could be run from the DOS prompt. In fact, many virus writers took advantage of this ability (particularly with VBScript), so these macros and small scripts are less frequently used these days. In fact, many mail systems ban them altogether when sent as an attachment to e-mail, due to the potential for viruses. Windows Script, including the JScript and VBScript engines, can be downloaded free from http://msdn.microsoft.com/scripting. Developers can still create small programs using JScript for use in a Windows environment, although it is rarely done. These JScript programs rely on the presence and enablement of the Windows scripting environment, and in these security-conscious times, that is something which you cannot rely on too heavily. JavaScript Development Tools One of JavaScript’s strengths is that expensive development tools are not usually required. With a simple text editor such as Notepad, which is built into Windows, you can create relatively complex JavaScript code with little trouble. Since it is an interpreted language inside the context of a web browser, you don’t even need to buy a compiler. A compiler is a program that turns programming code into machine-ready form, often called a binary or an executable.
  • 30. 10 How to Do Everything with JavaScript But just because JavaScript can be edited in a simple text editor doesn’t mean that it should be. Development environments offer several key resources that often make development faster and easier, such as: ■ Predefined scripts that can be easily added to a web page ■ Integrated help, to quickly look up the syntax of a function ■ Automatic FTP uploads to a web server ■ Integrated debugging tools In this section, we will examine the top four HTML editors. Each of these editors has significant support for JavaScript development, including ready-to-use scripts, JavaScript editing tools, and embedded help. Microsoft FrontPage Microsoft has developed a popular HTML editor called FrontPage. FrontPage provides web developers with a number of JavaScript tools to assist in the creation of an interactive web site. FrontPage was once the undisputed leader in HTML and JavaScript development tools. Now a couple of other competitors in the field have taken a significant slice of the Microsoft market share—Macromedia and NetObjects. FrontPage still contains many useful features, including capabilities such as designing a web site’s hierarchy before creating any of the pages, configuring web site security, setting sitewide styles, and creating custom banner images. Figure 1-2 shows how FrontPage Explorer can be used to organize a web site by graphically linking pages together. Microsoft FrontPage also has a server-side component called FrontPage Server Extensions, which enables it to integrate well into Microsoft’s IIS web server. FrontPage can be purchased for $90 to $170, which makes it a very affordable tool for nonprofessional web site developers. Microsoft offers a free 30-day trial version of FrontPage 2002 for those who are interested in trying out the software. The trial CD can be ordered from http://www.microsoft.com/frontpage. Macromedia Dreamweaver MX Macromedia Dreamweaver MX is a very popular HTML and JavaScript editor in the professional web development crowd. It is packed with features, including the ability to edit most of the popular web server programming languages (like ASP, JSP, and PHP), provides several handy prebuilt JavaScript components, integrates well with databases, and conforms to new standards such as XHTML and XML. In short, it includes lots of goodies that professionals will find useful but that many home users might not require.
  • 31. CHAPTER 1: Prepare to Program in JavaScript 11 1 FIGURE 1-2 Using FrontPage Explorer to organize a web site The power of the Dreamweaver MX environment is shown in Figure 1-3. Macromedia Dreamweaver MX retails for between $200 and $400, which makes it an ideal tool for professional developers. You can download a free trial of Macromedia Dreamweaver MX for either Windows or Mac at http://www.macromedia.com/software/dreamweaver. Macromedia HomeSite 5 Macromedia purchased Allaire Corporation and took over ownership of Allaire’s flagship product, HomeSite. The most recent version is HomeSite 5, and Macromedia includes a free copy of it with each copy of Dreamweaver it sells. HomeSite appeals to the home user because of its price, although it lacks most of the sophisticated features of its sibling.
  • 32. 12 How to Do Everything with JavaScript FIGURE 1-3 Dreamweaver MX is an extraordinary working environment for the professional web developer. For $29 to $99 users receive a well-liked HTML and JavaScript editor, which will manage their personal web site just fine. Users with large sites to manage or more than one developer might want to consider investing the extra money to get Dreamweaver instead. Macromedia offers a free trial version of HomeSite 5 for Windows at http://www.macromedia.com/software/homesite. Adobe GoLive Adobe is best known to most surfers on the Internet for its Acrobat software, which writes and reads documents in their popular Portable Document Format (PDF). However, Adobe is also a leader in graphics, digital video, and desktop publishing software with its Photoshop, Premiere, and PageMaker products. In fact, it is likely that all the other industry-leading tools and software packages the company produces overshadow their web publishing tool business. However, even though Adobe GoLive
  • 33. CHAPTER 1: Prepare to Program in JavaScript 13 might be trailing the pack in many respects, for developers who regularly work with Adobe’s graphics- and video-editing tools, GoLive may be an easy choice. 1 As with other web authoring tools, you can download a trial copy of GoLive 6.0. GoLive is available for both Windows and Mac, and can be downloaded from Adobe’s web site at http://www.adobe.com/products/golive. NetObjects Fusion FrontPage, Dreamweaver, GoLive, and NetObjects Fusion make up the top four most popular web site development tools in use today. NetObjects, unfortunately, did not have sufficient cash or resources to stay in the race against such tough competitors. The company has been sold and the new owner, Website Pros, has been continuing development of the Fusion tool under the existing brand name. Fusion is priced competitively in the $70 to $150 range. It includes many interesting new features, such as integration with popular online payment services, JavaScript pop-up menus, and improved support for embedded multimedia. It was once a popular tool with developers, and may become so again under new guidance. A free trial of NetObjects Fusion 7 for Windows can be downloaded from the company’s web site at http://www.netobjects.com. The full version of the software can also be purchased and downloaded online. Learn What JavaScript Can and Cannot Do Historically, JavaScript has differentiated itself from other languages in the following ways: ■ It is easy to develop for. ■ It interfaces well with other languages and environments. ■ No special tools or compilers are required. ■ It’s flexible. These properties made it particularly well suited for web development. Web pages can be made dynamic with as little as one line of JavaScript code, and often only a handful of lines are required to accomplish common tasks. DOM provides JavaScript access to the browser, the web page, and all the objects (Java, multimedia, etc.) embedded within it. Despite the significant improvements, JavaScript 2.0 was not designed as an all-purpose language. Specifically, it does not intend to challenge C, C++, or Java in areas where those languages currently dominate. Rather, JavaScript 2.0 tries to improve upon the strengths of the existing language, while also adding features that developers often like to use when developing large or complex code, namely: ■ The ability to write modular and object-oriented applications ■ Improved ability to interface with other programming languages
  • 34. 14 How to Do Everything with JavaScript ■ The ability to write scripts that can be compiled for faster performance ■ The ability to restrict the way functions and code are used The ECMA has actually designed JavaScript 2.0 with these goals in mind. Use JavaScript as a Client-Side Language One of the unique qualities of the core JavaScript specification is that it does not attempt to define how JavaScript interacts with its environment. There are no JavaScript methods or functions in this specification that define how to draw the user interface or how to write text to the screen. Likewise, there are no file input/output routines that allow the language access to the hard drive. That feature can be considered both a strength and a weakness. The flexibility given by this lack of a standard I/O interface has resulted in JavaScript’s use in many different environments (browsers, servers, stand-alone applications, mobile devices, etc.). This has allowed devices with different ways of storing data and different ways of displaying output to run JavaScript applications. The downside to this flexibility is that the same JavaScript application cannot be run in each environment without some alteration. While most web browsers have standardized on a document object model, some differences remain between the DOMs of various browser makers. For example, a JavaScript application designed to run in a web browser cannot be run on a web server without taking the server’s own object model into consideration. Today, JavaScript is practically the only scripting language used inside web pages. Even though a couple of alternatives exist (most notably VBScript), JavaScript was (and still is) the only scripting language supported by all the major browser manufacturers. It is the only scripting language worth learning for client-side development. Use JavaScript as a Server-Side Language JavaScript also gained some popularity as a web server programming language. Both Netscape Enterprise Server and Microsoft IIS (popular web servers of the mid-1990s) supported server- side JavaScript development. Netscape supported this through the LiveWire server-side language. Microsoft allowed JScript as one of the potential languages for ASP development. Unfortunately, Netscape Enterprise Server (now called iPlanet Web Server) no longer supports JavaScript on the server, starting with version 6. This might have something to do with the fact that iPlanet is part of Sun Microsystems, and Sun Microsystems prefers programmers to use Java. And although Microsoft’s ASP environment has been hugely successful, developers prefer to use VBScript when developing for that platform. With the introduction of Microsoft’s ASP .NET platform, VB .NET and C# have become the two languages developers use most. Microsoft did the JavaScript community a small favor when it included JScript .NET support in the Visual Studio .NET development environment. JScript .NET has access to all the classes of the .NET Framework, and was the first (albeit, extremely early) implementation supporting features of the ECMAScript Edition 4 proposal.
  • 35. CHAPTER 1: Prepare to Program in JavaScript 15 Although the ECMA has given JavaScript the ability to function as a full programming language, JavaScript is not necessarily suitable for every environment. You would probably not 1 want to use JavaScript as a programming language for the following types of tasks: ■ Very large applications ■ Performance-critical applications ■ Device drivers and other low-level programs After all, we wouldn’t want to see all those C++ programmers out of a job, would we? Decide Which Version of JavaScript to Use One decision that JavaScript developers must make early on in the development process is which version of the language they wish to support. Several factors go into this decision, such as: ■ The size and scope of the programming task at hand ■ The possibility of future enhancements to the program ■ The need for the program to easily interoperate with other programs written in different programming languages ■ The need to take advantage of new features only offered in JavaScript 2.0 (new built-in objects, for instance) ■ The version of JavaScript supported by your favorite development tool ■ The version of JavaScript supported by the vast majority of your intended audience By far the most important consideration would be the last one. There is no point placing JavaScript 2.0 inside web pages if a significant amount of your intended audience still uses browsers that don’t support it. Of course, if your program will reside only on the server (a server-side program), all that matters is the version supported by the server. It is also important to remember one of the fundamental rules of computer programming: never write more code than is absolutely necessary for a task. So if your JavaScript program is a three-line script that converts degrees Celsius to degrees Fahrenheit, there is no need to create packages and classes in JavaScript 2.0 syntax (as discussed in Chapter 5). You may want to do it for other reasons, including future extensibility of your program. But this is also a case of if it ain’t broke… So as a general rule, be very cautious about developing in client-side JavaScript 2.0 code if your intended audience is likely to be running a wide variety of web browsers. Otherwise, if you know for certain what the minimum browser version will be or are developing in a server or embedded environment, feel free to use the new features and improvements in JavaScript 2.0 to your heart’s content!
  • 36. 16 How to Do Everything with JavaScript Test JavaScript Programs Using HTML Before jumping into the fundamentals of JavaScript, we need to set up a way to test our code. The easiest way to test a JavaScript program is by putting it inside an HTML page and loading it in a JavaScript-enabled browser. To run any of the code samples in this book using this HTML method, you will need a web browser. I recommend using IE 5 or Navigator 4 or later, as some examples won’t work with earlier versions. If you would like to upgrade the browser on your computer to a more recent version, you can visit Microsoft’s IE web site at http://www.microsoft.com/windows/ie, or Netscape Browser Central at http://channels.netscape.com/ns/browsers. Create a JavaScript Template The <script> tag is the HTML element used to signify JavaScript code. It’s a good idea to create this file as a template using Notepad (or your favorite web development tool) and save it on your hard drive. That way it will be much easier to start creating JavaScript-powered web pages using this HTML code as a base. Here’s how to create the template in Notepad: 1. In Windows, click the Start menu button. 2. Select Run from the pop-up menu. 3. Type in notepad as shown here, and press ENTER. 4. In Notepad, enter the following HTML code: <html> <head> <title>JavaScript sample code</title> </head> <body> <h1>My Sample Code</h1> <script language="JavaScript" type="text/javascript">
  • 37. CHAPTER 1: Prepare to Program in JavaScript 17 <!-- // Begin // NOTE:: Replace this line with JavaScript code 1 // End --> </script> </body> </html> 5. Select the File menu, and choose Save As. 6. Navigate to the desired location on your hard drive. The My Documents folder is commonly used, but you can also choose to save it to any directory of your choice. We will use this HTML file to run the JavaScript code samples throughout the book, so put it someplace handy. 7. Give the HTML file a name ending in .htm such as JSTemplate.htm. 8. Close Notepad. 9. From your Windows desktop, choose My Computer. This will bring up Windows Explorer, which allows you to navigate to the directory where you saved your HTML file. 10. Double-click the HTML file. A web browser (usually Microsoft Internet Explorer) will open your HTML document. 11. You should see the words “My Sample Code” in large letters. 12. Close the browser window when you are finished with it. Figure 1-4 shows how the HTML template looks in the browser. This is the most basic example of a <script> tag in an HTML page.
  • 38. 18 How to Do Everything with JavaScript FIGURE 1-4 A simple HTML document containing a <script> tag that does nothing Understand the JavaScript Template Remember that HTML documents are divided into two distinct pieces: the header section and the body. HTML documents always start with the <html> tag and end with the </html> closing tag. Similarly, the HTML header section is delimited with the <head> and </head> tags, as so: <head> <title>JavaScript sample code</title> </head> Generally, the HTML markup inside the header section is used to describe the main content that appears in the body section. Most commonly, the header section contains: ■ A mandatory title for the document (<title>) ■ Style sheet definitions (<style> and <link>)
  • 39. CHAPTER 1: Prepare to Program in JavaScript 19 ■ Meta data, such as search keywords (<meta>) ■ JavaScript functions (<script>) 1 The bulk of the HTML document is inside the body section, delimited by <body> and </body> tags. In this section you would find text, images, forms, and embedded content. JavaScript can also be used in this section to output dynamic text to the screen. Our template’s body section looked like this: <body> <h1>My Sample Code</h1> <script language="JavaScript" type="text/javascript"> <!-- // Begin // NOTE:: Replace this line with JavaScript code // End --> </script> </body> Our body section starts and ends with the mandatory <body> and </body> tags. The <h1> and </h1> tags indicate header text. <h1> is the predefined header with the largest font. The <h2>, <h3>, <h4>, <h5>, and <h6> tags indicate headers with decreasing font sizes. I have included a <script> element inside the body section for later use. I’ve included two attributes with this tag, language and type. The language attribute was the original way to indicate what scripting language was used inside the tags. Although recent versions of HTML (and XHTML, its successor) have phased out the use of this attribute, it is still quite common to use it. The type attribute is what is now recommended to indicate the scripting language in use. The template contains three lines inside the <script> section: <!-- // Begin // NOTE:: Replace this line with JavaScript code // End --> All three of these lines are comments. In web programming, a comment is one or more lines of text that is ignored by the browser when interpreting the code. Programmers often use comments to make a program easier for humans to read, but in the preceding code, the first and last lines are used to stop browsers that don’t support JavaScript from displaying the code. As time goes on, this technique becomes less and less important. But it is still quite prevalent, and there is really no reason not to include it. The <!-- and --> are markers for the start and end of HTML comments. JavaScript comments are marked with double slashes (//), which is why the browser will ignore the second line as well. Communicate with the User Many JavaScript programs perform their tasks quietly. A web page may use JavaScript to verify that all the fields on a form have been completed in the proper manner. When they are complete,
  • 40. 20 How to Do Everything with JavaScript the JavaScript program allows the form to be submitted to the web server for further processing. But if one of the form fields has not been filled out properly, JavaScript should, ideally, inform the user so that they can correct the problem and submit the form again. There are generally two ways to bring an error like this to the user’s attention. The first is to take advantage of a JavaScript alert box, which requires the user to click an OK button in order for processing to continue. This is considered a slightly intrusive technique that ensures the user reads and acknowledges the error message. The other way is to write an informative message inside the web page directly. This is obviously a less intrusive technique, although you must be sure that the user does not accidentally overlook the message. In this section, we will examine how to communicate with the user using both methods, as each will be important before we move on to the next chapter. Display an Alert Message JavaScript provides three types of pop-up dialog boxes for use in your applications: ■ An alert box ■ A confirm box ■ A user-input prompt box Basic alert messages are displayed using the built-in alert function: alert ("This message will be displayed to the browser"); You can place any text string or expression inside the parentheses. The dialog box displayed looks like this in Internet Explorer. Netscape Navigator displays a similar message box.
  • 41. CHAPTER 1: Prepare to Program in JavaScript 21 A confirm box acts in much the same way as an alert box, except it displays both OK and Cancel buttons to the user. The confirm box tells the program which button the user chose, 1 allowing two different outcomes. result = confirm ("Would you like a piece of chocolate cake?"); The result variable will contain true if the user selects the OK button, or false otherwise. This is how the confirm box appears in Internet Explorer. Finally, the user-input prompt box allows the program to ask for a typed response to a message. This is rarely used on Internet web pages, as HTML web forms are a more commonly accepted way to retrieve user input. firstname = prompt ("What is your first name?", "Enter name here"); The result of this JavaScript code is shown here. Write Text to the Browser Window Many of the examples in this book will use the document.write() function to print text into the web browser window. This can be used for more than just error reporting. In fact, it is quite common to see web sites using document.write() to support dynamic functions such as navigation, user help, banner ad rotation, and more. document.write ("<b>This text goes right into the browser</b>")
  • 42. 22 How to Do Everything with JavaScript Notice how you can include HTML tags inside the document.write() function and the browser will process those tags. By adding a few document.write() statements into our HTML template, we can create a web page with a bit more content. <html> <head> <title>JavaScript sample code</title> </head> <body> <h1>Hamlet, by Bill Shakespeare</h1> <script language="JavaScript" type="text/javascript"> <!-- // Begin // NOTE:: Replace this line with JavaScript code document.write ("To be, or not to be: that is the question:<br>"); document.write ("Whether 'tis nobler in the mind to suffer<br>"); document.write ("The slings and arrows of outrageous fortune,<br>"); document.write ("Or to take arms against a sea of troubles,<br>"); document.write ("And by opposing end them.<br>"); // End --> </script> </body> </html> As you can see in Figure 1-5, our document.write() statements were output to the screen just as if we had entered them directly in HTML. This technique becomes more useful when we get into the next chapter, when we learn about variables, functions, and statements. Now that we have covered the boring stuff—the history of the language, and what it is used for—we are ready to jump into a bit of real programming. The next chapter starts off by covering the basics of JavaScript, to get you ready to start coding on your own. Learn More about Topics Discussed in this Chapter There are several good books available to learn more about HTML and Java, namely: ■ How to Do Everything with HTML, by James Pence (McGraw-Hill/Osborne, 2001) ■ HTML: A Beginner’s Guide, 2nd edition, by Wendy Willard (Osborne, 2002) ■ Java 2: A Beginner’s Guide, by Herbert Schildt (Osborne, 2000) ■ Learn to Program with Java, by John Smiley (Osborne, 2001)
  • 43. CHAPTER 1: Prepare to Program in JavaScript 23 1 FIGURE 1-5 Hamlet’s famous soliloquy, as delivered by JavaScript In addition, you may want to check out some of the following web sites: ■ DevGuru: http://www.devguru.com ■ W3 Schools: http://www.w3schools.com/html ■ Sun Microsystems’ Java home page: http://java.sun.com ■ JavaRanch: http://www.javaranch.com
  • 46. 26 How to Do Everything with JavaScript How to... ■ Define variables ■ Define constants ■ Understand program flow ■ Execute code conditionally ■ Repeat statements using loops ■ Comment your code ■ Set a default object ■ Handle errors ■ Understand the basics of expressions ■ Organize your code into functions ■ Use the improvements in JavaScript 2.0 to create more powerful functions JavaScript is extremely dependent on other technologies for help. In fact, if you tried to write a program in JavaScript that didn’t rely on anything outside of the official JavaScript specification, your program would not be able to do very much. JavaScript relies on external components for communication with the outside world, such as writing to a screen, retrieving data from a web form, and receiving notification of browser events. In this chapter, we will examine JavaScript’s fundamentals. We will learn the basics of writing a program by learning about statements, variables, and functions—the three basic building blocks of any program. Understand Basic Terminology Like practitioners of other specialties, computer programmers have developed their own lingo over the years. Ordinary English words such as variable, function, and string have been given computer-related meanings. Table 2-1 lists some of the programming terms you will encounter in this chapter and throughout the book. Store Data in Variables When it gets right down to it, there are only three places to store information in modern computing: the hard disk, a database, or memory. Sure, there are other data-storage media, such as floppy disks, CDs, Zip disks, and backup tapes upon which information can be saved, but the devices these media require are much slower than a hard drive—sometimes taking 100 times as long (or more) to record the same data. So application programmers cannot—and should not—generally rely on any of these media when storing information.
  • 47. CHAPTER 2: Learn JavaScript Fundamentals 27 The programming term... Refers to... statement One line of programming code; statements are often separated by semicolons (;) in JavaScript. variable A named location for storing values that can be changed during program 2 execution. constant A named location for storing values that cannot be changed during program execution. function A named set of statements that perform some operation and can optionally return a single value. keyword A word that has a predefined meaning in JavaScript, and cannot be used for any other purpose. operator Typically a symbol (such as +, -, *, or / ) that takes one or more values (called operands) and returns a result. expression A combination of keywords, operators, variables, and/or functions from which a result can be calculated. string A sequence of 0 or more letters, numbers, or other text characters; strings are typically enclosed in quotation marks, as in “this is a string”. Boolean A value or expression that evaluates to either true or false. literal A Boolean, number, or string that is written directly in the code; for instance, the expression ((3+2)/total) contains two numeric literals, 3 and 2. value A number, Boolean, string, or object. TABLE 2-1 Common JavaScript Programming Terminology On the hard disk, information is stored in the form of files. In a database, information is stored as records. But in memory, program data is stored and retrieved using variables. Variables are named sections of memory. Define Variables In JavaScript 1.5, variables are declared using the var keyword: var counter; This code tells JavaScript that we intend to store information in a variable we’ll refer to as “counter.” Variables defined in such a way can contain any type of information: numbers, strings, Booleans (true and false), or objects. For convenience, you could assign the variable an initial value like so: var counter = 5; We have assigned the variable named counter an initial value of 5.
  • 48. 28 How to Do Everything with JavaScript JavaScript 2.0 has introduced the concept of data types into JavaScript programming. Before this release of the language, programmers could not predefine the types of data that a variable could contain—all JavaScript variables could be assigned any type of data. But with this important new release of the language, we can now restrict variables to certain types of data: integers, for example, or strings. Attempting to assign data that does not belong to the variable’s predefined data type would result in an error. Data types are defined as follows: var counter : Integer; The counter variable defined here belongs to the Integer data type. Thus, that variable can never contain anything other than whole numbers. (We examine all the data types available in JavaScript 2.0 in Chapter 3.) Define Constants Variables are called variables for a reason: a program is free to change the value stored inside the variable at any time. Constants are similar to variables, but once a value has been assigned, constants cannot be changed. Constants are only currently supported by Netscape 6 and later, or the Mozilla web browser. Microsoft IE has not yet incorporated support, so the use of constants should be limited to uses when you are absolutely sure they are safe. Constants were introduced into JavaScript starting with version 1.5, so early versions of the language do not support them. But other programming languages (most notably C) use constants very effectively, and they can be useful in your JavaScript programming as well. Constants are defined using the const keyword: const ERR_INVALID_USERID; In the preceding code, I created a constant named ERR_INVALID_USERID. Notice how I capitalized the name. It is not mandatory, but it is a programming convention often used in C, so you will sometimes see constants capitalized in JavaScript as well. JavaScript Can Store Some Mighty Big Numbers Integers in JavaScript 2.0 are double-precision floating-point numbers, which allows them to contain values in the range of approximately +/–100 unodecillion—1 with 38 zeros after it.
  • 49. CHAPTER 2: Learn JavaScript Fundamentals 29 Once a value has been set, a constant cannot be altered. const ERR_INVALID_USERID = 300; ERR_INVALID_USERID = 50; // This will cause an error! 2 Constants are often used to give human-readable names to error codes and other numbers that “mean something.” It is much easier for humans to read the following code than if it just used the error numbers directly: switch (returncode) { case ERR_INVALID_USERID: // do something case ERR_INVALID_PASSWORD: // do something else case ERR_INVALID_DOMAIN_NAME: // etc. } Like variables, constants can be assigned a data type in JavaScript 2.0. Understand Program Flow The bulk of this chapter is devoted to learning the fundamentals of the JavaScript programming language, statements, and functions. But before we get into that, it is important to spend a few moments examining program flow. When I talk about program flow, I am talking about the order in which JavaScript executes a program’s code. Assuming you have a program that is five lines long, JavaScript will always start by executing the first line of code. In theory, the second line is executed next, then the third, and so on until it reaches the last line (line 5 in our example). Figure 2-1 illustrates this. In reality, that is an extreme oversimplification of what goes on. The next line to be executed depends on the task that the current line asked JavaScript to perform. If the current line calls a function, all the code inside the function will be executed first, before JavaScript continues with the next line. If the current line contains a loop, the same group of lines will be executed repeatedly. And if the current line declares a new function to be defined, JavaScript will read the function into memory without executing any of it (until it is called elsewhere in the program). FIGURE 2-1 JavaScript executes a program from start to finish in order.
  • 50. 30 How to Do Everything with JavaScript FIGURE 2-2 JavaScript will stop executing a program in order to execute the contents of a function. But, for the most part, it is still fair to characterize a program as being executed in order from start to finish. Figure 2-2 shows how the program flow jumps around depending on the code itself. We can see that all the code inside a function is executed before the program continues where it left off. Control Program Flow with Statements The HTML template we defined in Chapter 1 (see “Create a JavaScript Template”) didn’t really do anything useful, other than displaying some header text. The only way we can get our JavaScript program to do anything is to add some statements. A statement is the basic action item in any program code. In effect, each statement is telling the computer to do something. Statements can be divided up into five categories: ■ Conditional ■ Loops ■ Object manipulation ■ Comments ■ Expressions The typical JavaScript program uses statements that fall into each of those categories. Often, statements inside a program are organized into functions and classes as well, to make the program easier to manage and more efficient to develop. We will examine functions in more detail later in this chapter, and classes in Chapter 5. Execute Code Conditionally Computer programs almost always contain conditional statements. There are two conditional statements in JavaScript: if and switch. The if statement allows the program to choose one of two alternatives, based on some predefined factor. In real life, you might decide that, if it were not raining, you would like to go to the baseball game. Of course, if it were raining, you would then decide to stay home. You can make that same decision in a JavaScript program with the following code:
  • 51. CHAPTER 2: Learn JavaScript Fundamentals 31 function stay_or_go (raining) { if (raining == false) { return "Go to baseball game!"; } else { 2 return "Got to stay home today."; } } So you see, conditional statements give programs a choice between two or more alternatives in much the same way we make those choices in real life. The if Statement Depending on how you use it, the if statement can be very simple or very complex. The if statement can be used in the following ways. Syntax Use if (expression) {statements;} If expression evaluates to true, execute statements. if (expression) {statements1;} If expression evaluates to true, execute statements1. else {statements2;} Otherwise, execute statements2. if (expression1) {statements1;} If expression1 evaluates to true, execute statements1. else if (expression2) {statements2;} Otherwise, if expression2 evaluates to true, execute else {statements3;} statements2. Otherwise, execute statements3. The if statement evaluates an expression to determine which set of statements to execute, if any. Since the if statement expects a Boolean expression (one that evaluates to either true or false), it will try to convert expressions of other data types to either true or false. JavaScript makes certain assumptions when converting from other data types to Boolean. The strings “true” and “false” evaluate to the Booleans true and false. The integers 1 and 0 are also converted to the Booleans true and false, respectively. In computer programming terminology, an expression is a piece of code that, when evaluated, returns a value. In JavaScript, the following can be used as expressions. Expression Example A variable if ( x ) {statements;} A function that returns a value if ( myfunc(x) ) {statements;} A literal if ( true ) {statements;} Variables, functions, and literals combined if ( a > 5 ) {statements;} using operators
  • 52. 32 How to Do Everything with JavaScript Even the same if statement can be written in at least four different ways, all of which are valid: ■ if (expression) statement; ■ if (expression) statement; ■ if (expression) {statements;} ■ if (expression) { statements; } The various preceding forms of the if statement are technically equivalent. The first two can include only one statement. Notice that the third and fourth forms use curly brackets, { and }, to enclose the statements. Statements enclosed in curly brackets are generally treated as a group, called a statement block. The if statement can include an optional else clause, to decide between one of two alternatives. This form of the statement is sometimes called the if-else statement: if (expression) {statements1;} else {statements2;} The else clause allows you to specify a statement or group of statements that will be executed if the expression does not evaluate to true. Only one else clause is allowed in any if statement. Again, the statement can be used with or without the curly brackets. Finally, the if statement can be used to choose between one of three or more alternatives. With the introduction of the else-if clause, the if statement can include multiple expressions that will each be evaluated until either one of them evaluates to true or the else clause is encountered. Multiple else-if clauses can be included, but keep in mind that the else-if clause must always precede any else clause. if (expression) { statements; } else if (expression) { statements; } else { statements; } If you find yourself using more than two or three else-if clauses in a single if statement, you may want to consider using a switch statement instead, as described in the following section.
  • 53. CHAPTER 2: Learn JavaScript Fundamentals 33 The switch Statement The switch statement has a very similar role to the if statement in JavaScript. The switch statement evaluates an expression and compares the value to one or more case clauses. If you need to compare a variable against more than two or three values, the switch statement is the 2 most efficient way. The following code shows how the switch statement is typically used in JavaScript programming. In this example, our program will try to determine the name of a country based on its official three-letter ISO (International Organization for Standardization) country code. // ISO official country codes switch (countrycode) { case "ALB": countrystring="Albania"; break; case "DZA": countrystring="Algeria"; break; case "ASM": countrystring="American Samoa"; break; case "AND": countrystring="Andorra"; break; case "AGO": countrystring="Angola"; break; // etc. case "", "?": default: countrystring="Unknown code"; } The same code could be written using if-else-if statements, but that would be both inefficient and harder to read. Let’s take a look at the preceding code, to see what is going on. The first line of the statement uses the switch keyword, followed by the expression that needs to be evaluated. switch (countrycode) {
  • 54. 34 How to Do Everything with JavaScript In this example, countrycode is a variable that happens to contain a string. The next three lines in the switch statement contain the first case clause. case "ALB": countrystring="Albania"; break; The case clause indicates that we would like to compare the value of countrycode (the expression the switch statement is acting on) with the string "ALB". If there is an exact match, JavaScript will execute the next two lines: ■ Set the countrystring variable to "Albania". ■ Exit the switch statement at the break statement. Of course, if the value of countrycode does not match the string "ALB", the countrystring variable is not set and the switch statement continues. The next case clause compares the expression against a new value: case "DZA": countrystring="Algeria"; break; The switch statement evaluates each of the case statements in order, until it finds one that matches. It then executes the code that immediately follows the case clause until the first break statement is encountered. Once a match is found, JavaScript will execute all the code that follows, even inside other case clauses, until the break statement is encountered. In JavaScript, the switch statement has a special kind of case clause known as the default clause. The default clause executes only if JavaScript was unable to match the expression with any of the previous clauses. The default clause must always be the last clause in a switch statement. case "", "?": default: countrystring="Unknown code"; Our example includes an empty case clause, trying to match against the empty string ("") or a question mark (?). You can provide multiple values to match against the expression in a single case clause, as long as they are separated with commas. If the expression matches our empty case, the code inside the default clause will be executed, since there is no break statement to stop it. Repeat Statements Using Loops Loops are convenient statements for two purposes: ■ When you want to repeat a set of statements a specific number of times ■ When you want to repeat a set of statements an unknown number of times
  • 55. CHAPTER 2: Learn JavaScript Fundamentals 35 There are four loop statements in JavaScript: while, do-while, for, and for-in. JavaScript also provides the break and continue statements to give programmers more control over how loops execute. In this section, we will examine each of the statements related to looping and see how they can be applied in our programs. 2 The while Loop The while loop evaluates an expression before executing a group of statements. It will execute the statements repeatedly, until the expression no longer evaluates to true. while (expression) { statements; } JavaScript processes the while loop in the following manner. The expression is first evaluated, and its value is interpreted as a Boolean (true or false) value. If the expression evaluates to true, the statements contained inside the curly brackets are executed once. The expression is then evaluated again, and if it still evaluates to true, the statements are executed a second time. This continues indefinitely until the expression evaluates to false. A common programming trap is the infinite loop. An infinite loop is a loop statement that never ends, and this is most like to happen with the while statement. Most browsers will inform the user when a script takes too long to execute, which allows them to force an infinite loop to end. To avoid infinite loops, it is common programming practice to make sure the expression always has a chance to evaluate to false. The following while statement is guaranteed not to cause an infinite loop: var counter = 1; while (counter < 101) { document.write ("This is line number " + counter + "<br>n"); counter++; } This code will execute exactly 100 times. We know this because the counter variable starts off at 1, and after every successive while loop iteration, it is incremented by one. (We will learn about operators, such as the ++ operator, later in this chapter. In this code, the ++ operator takes
  • 56. 36 How to Do Everything with JavaScript the counter variable and increments it by 1.) When it reaches 101, the loop will exit, since “counter < 101” would evaluate to false. If we paste this while loop into our HTML template from Chapter 1, we get the following HTML code: <html> <head> <title>JavaScript sample code</title> </head> <body> <h1>My Sample Code</h1> <script language="JavaScript" type="text/javascript"> <!-- // Begin var counter = 1; while (counter < 101) { document.write ("This is line number " + counter + "<br>n"); counter++; } // End --> </script> </body> </html> Loading this HTML code into a web browser gives you something similar to Figure 2-3. The browser window has been scrolled all the way to the bottom to demonstrate exactly how many lines were printed. FIGURE 2-3 The while loop prints exactly 100 lines.
  • 57. CHAPTER 2: Learn JavaScript Fundamentals 37 The do-while Loop The do-while loop acts exactly like the while loop, with one exception. The expression is evaluated after the end of each iteration in a do-while loop. That means the loop is guaranteed to execute at least one time. A while loop evaluates its expression prior to each iteration, which 2 means that it’s possible that the contents of the loop will never be executed. do { statements; } while (expression); Even though the expression is evaluated after each iteration of the loop, the following loop still executes exactly 100 times. So the only iteration that is affected by choosing do-while instead of a while loop is the first run through the loop. var counter = 1; do { document.write ("This is line number " + counter + "<br>n"); counter++; } while (counter < 101); You can look at the while and do-while loops as two versions of the same statement. Everything you can do with do-while, you can do with while. As a result, do-while loops are less commonly seen “in the wild” than while loops. The for Loop In discussing while loops just now, we used the following example: var counter = 1; while (counter < 101) { document.write ("This is line number " + counter + "<br>n"); counter++; } That while loop can be rewritten using a for loop. In fact, this type of loop (one that employs a counter variable) is better suited to a for loop. for (var counter = 1; counter < 101; counter++) { document.write ("This is line number " + counter + "<br>n"); }
  • 58. 38 How to Do Everything with JavaScript As you can see, the for loop version is a more efficient way of looping a predefined number of times. The for loop syntax has four components: for (initializer; expression; incrementor) { statements; } The initializer section is traditionally used to define variables and give them an initial value. In our example, we defined a new variable named counter and set it to the value 1. The JavaScript code contained in the initializer section gets executed only once—before the loop begins. The expression is evaluated before every loop. Whether or not the statements are executed depends on the Boolean results of this expression. The incrementor section contains code that gets executed following each run through the loop. Traditionally, this is where any counters are incremented or decremented. In our example, we add 1 to the counter variable using this section. Each of these sections is optional. If the variables being used are already defined and have a value set, the initializer can be empty. But don’t forget that the semicolon in between is mandatory. In fact, the following code is an infinite loop using a for statement: for (;;) { // do nothing }; Although this is another example of an infinite loop (which is generally a bad idea in programming) this loop is a valid technique if you have code inside the loop that executes a break statement when a certain condition is met. The for-in Loop I only want to talk about the for-in loop here for the sake of context. You will see a proper discussion of it in Chapter 5, when we talk about classes and objects. For now, think of an object as a tool chest that contains a bunch of tools. The for-in loop will extract each tool individually from that tool chest, and allow you to examine and manipulate it on its own. In the following code, we create a simple object (compatible with JavaScript 1.5) and retrieve each of its properties using the for-in loop. <html> <head> <title>JavaScript Test</title>
  • 59. CHAPTER 2: Learn JavaScript Fundamentals 39 </head> <body> <h1>for-in Loop</h1> <script language="JavaScript" type="text/javascript"> 2 <!-- // Begin // We define the tool chest object var toolchest = {tool1:"Wrench", tool2:"Hammer", tool3:"Cordless drill", tool4:"Needlenose pliers"}; // for-in iterates over its properties for (var tool in toolchest) { document.write(toolchest[tool] + "<BR>"); } // End --> </script> </body> </html> This program creates an object named toolchest. The object is created using an object literal, as discussed in Chapter 5. // We define the tool chest object var toolchest = {tool1:"Wrench", tool2:"Hammer", tool3:"Cordless drill", tool4:"Needlenose pliers"}; The code that we’re interested in is the for-in loop: // for-in iterates over its properties for (var tool in toolchest) { document.write(toolchest[tool] + "<BR>"); }
  • 60. 40 How to Do Everything with JavaScript This code picks loops through the contents of the toolchest object—tool1, tool2, tool3, and tool4. When executed, the program outputs the value of each property, like so. The break and continue Statements We already saw the break statement in action when we looked at the switch statement. When JavaScript encounters a break statement inside a switch, it stops executing code inside the switch and continues execution at the first statement that follows it. The break statement works in a similar fashion with loops. When JavaScript encounters a break statement, it stops executing the code inside the loop and starts again at the first statement outside the loop. The break statement is not valid outside a loop or a switch statement. The continue statement causes JavaScript to stop executing code inside the loop as well, but execution continues at the next iteration of the loop instead. In effect, the break statement says, “Exit the loop,” while the continue statement says, “Skip this iteration and move on to the next.” The continue statement is also not valid outside of a loop. var Fahrenheit, Celsius; for (Celsius = -70; Celsius <= 70; Celsius += 10) { Fahrenheit = (Celsius * 9/5) + 32; document.write ("Celsius = " + Celsius); document.write (", Fahrenheit = " + Fahrenheit + "<br>"); if (Fahrenheit > 100) { // It's getting hot in here break; } }
  • 61. CHAPTER 2: Learn JavaScript Fundamentals 41 The for loop in this code is designed to run through all of the degrees Celsius starting at –70, incrementing by 10 degrees per iteration, until Celsius reaches +70 degrees (–70, –60, –50, –40, etc.). But if you examine the code inside the loop, it tells JavaScript to break out of the loop when the temperature exceeds 100º Fahrenheit. Since 100º Fahrenheit is approximately 37º Celsius, the 2 loop will actually exit when Celsius hits 40, and not 70. The break statement causes the loop to exit prematurely. The continue statement is very useful when you want to loop through a range of values, ignoring some that don’t meet certain criteria. But when you find some that do, you have a lot of code to execute inside the loop. Instead of surrounding dozens of lines of code with a giant if statement, the continue statement can be used to skip on to the next iteration. // Which numbers are evenly divisible by 23? var iNumber; for (iNumber = 1; iNumber <= 1000; iNumber++) { if (iNumber % 23 > 0) { // Not divisible by 23 continue; } document.write("<b>" + iNumber + "</b>"); document.write(" is evenly divisible by 23!<br>"); }
  • 62. 42 How to Do Everything with JavaScript In this code, the loop is designed to execute 1,000 times, running through the numbers from 1 to 1,000. The if statement inside the loop checks to see whether the number is evenly divisible by 23, using the modulus (%) operator. If it is not evenly divisible by 23, the continue statement is executed—the rest of the current loop is skipped and the next iteration of the loop starts. Every 23 numbers (it’s odd how it works out like that), we will run into a number that is evenly divisible by 23. The continue statement is not executed, and the rest of the loop has a chance to run. In our example, we output the happy news that we finally found a number that matches, using the document.write() function. Using Labels A label is a named line of code. Since their only purpose is related to loops—nested loops in particular—labels are rarely used in real life, although it is important to know they exist. In programming terminology, you have created a nested loop when you place one loop completely inside another—for instance, if you have a for loop inside a while loop. In this situation, the for loop is known as the inner loop, and the while loop is called the outer loop. Loops can be nested many levels deep.
  • 63. CHAPTER 2: Learn JavaScript Fundamentals 43 Labels are fairly easy to create. 1. Open your JavaScript program using a text editor, such as Notepad. 2. Pick the line of code that you would like to name. Labels must appear at the beginning of 2 a valid statement. 3. Type a label name, using only letters or numbers. No spaces or other special characters are allowed in the name. 4. End the label with a colon (:). For instance, in the following code, we have a set of nested loops, which are also labeled. var x, y, z; outer: for (x = 1; x < 20; x++) { middle: for (y = 1; y <= x; y++) { inner: for (z = 1; z <= y; z++) { document.write ("x = " + x + "; y = " + y + "z = " + z + "<br>"); } } } In this code, we have three loops. The innermost loop, acting on the variable z, is labeled “inner.” The middle loop, which encloses the loop named “inner,” is called “middle.” And the outermost loop is named “outer” and encloses both the middle and inner loops. The only reason to label a loop is because the break and continue statements are designed to work with labels. By adding the following code immediately after the document.write function call inside the innermost loop, you could cause all three loops to exit prematurely: break outer; This is convenient when you have a condition inside an inner loop (it doesn’t have to be the innermost one, however) that would make you want to stop processing all the loops—or even just stop processing the two innermost and continue with the outer loop. For instance, the following code placed inside the innermost loop in the preceding code would cause the variables y and z to never get past the value of 1, while x is allowed to increment to 20: break middle; Comment Your Code We discussed comments briefly in Chapter 1. Comments are not really a type of statement, although they are often lumped in with the other JavaScript statements for the sake of convenience. There are two ways to add comments inside a JavaScript program.
  • 64. 44 How to Do Everything with JavaScript You can add a single line of comments by starting your comments with two slashes. // Everything after the slashes will be ignored by JavaScript It is also possible to include comments on the same line with valid code. var Students = 3; // There will be three students in the class Another way to comment code is with block comments. Block comments start with a slash and an asterisk (/*). /* This is the start of block comments Block comments continue until an asterisk and slash (*/) are encountered, even if the comments extend over several lines. /* This is the start of block comments Even this will be ignored document.write ("This will not be executed either!"); Because it is still considered a comment */ When you are developing small JavaScript programs for yourself, you may not wish to spend much time commenting your code. That is fine—it’s called programmer’s prerogative. You may find, however, that comments are useful for the following reasons: ■ You can include a copyright notice with your program. ■ You can describe what a program or function does in “plain English.” ■ In the development stage, or when debugging, sometimes you would like code not to execute, but you don’t want to delete it. ■ Comments can also be placeholders for code you want to add some time in the future. If you create programs professionally, you may be required to include a copious amount of comments to make it easier for others to understand your code. Set a Default Object We have not yet spent any time looking at the concept of programmable objects in this book and I’m going to defer most of that discussion to Chapters 3 and 5, when we get to built-in objects and user-defined classes. But in order to understand the with statement and its ability to specify a default object for a set of statements, let’s spend a moment looking at what objects, methods, and properties are. To understand the concept of objects in programming, it is helpful to draw an analogy to the real world. Almost anything in real life can be thought of as programmable object—a car, a television, a coffee cup, or even a person. In programming, objects can have both methods and properties. An object’s methods are actions it can take, while an object’s properties describe the object. For instance, let’s assume we have created a Person object in JavaScript. In real life, a person typically has certain unique features, such as a name, hair color, eye color, and height. These features would be defined as properties of the Person object. In real life, a person can take actions
  • 65. CHAPTER 2: Learn JavaScript Fundamentals 45 such as eating, sleeping, talking, and listening. These actions would translate into methods of the Person object. The with Statement 2 The with statement allows you to access the methods and properties of an object without having to specify the name of the object on every line. Without the with statement, you will always need to specify the name of the object you are working on next to every property or method you wish to access: person.fullname = "Bob Jones"; person.haircolor = "Black"; person.eat(); person.sleep(); But when statements are surrounded by the with statement, the object name is implied, as in: with (person) { fullname = "Bob Jones"; haircolor = "Black"; eat(); sleep(); } When JavaScript first encounters the reference to fullname inside the with statement, it will first check to see if a variable called fullname exists. If not, it will check to see if the person object has a property called fullname. As you can see, when you need to access the same object repeatedly over many lines, it may make sense to surround your code in a with statement. The with statement can be a convenient statement for the programmer to use—anything that saves typing is convenient. But some developers feel using the with statement also makes your program a bit harder to read. With the technique of copy-and-paste in most text editors, there may not be many reasons you would need to use this statement in your programs. with (document) { write("99 bottles of beer on the wall<br>"); write("99 bottles of beer<br>"); write("If one of the bottles happens to fall<br>"); write("98 bottles of beer on the wall<br><br>"); write("98 bottles of beer on the wall<br>"); write("98 bottles of beer<br>"); write("If one of the bottles happens to fall<br>"); write("97 bottles of beer on the wall<br><br>"); }
  • 66. 46 How to Do Everything with JavaScript In the preceding code, we start off by declaring that we would like document to be the default object. Notice how we can then start using the write() method without referring to document at all. The default object set using the with statement applies only to code within the curly brackets. Outside the curly brackets, the object will need to be explicitly used once again. Handle Errors Perhaps the most difficult programming challenge most developers face on a regular basis is intelligently handling errors. In JavaScript programming, an error is a problem that the browser encounters when it is trying to run a program. Errors can be triggered by something the browser saw and didn’t like, called a system error. Or it can be triggered by something your program saw and didn’t like, called an application error. A JavaScript program could easily be doubled in size with the addition of a reasonable amount of error-handling code. Error-handling code is typically additional code a programmer has to write to check for the existence of errors and do something with them. In JavaScript, if the program contains no error-handling code, the default action is often for the browser to present the problem to the user. The problem with error-handling is that it often takes as much work (or more) to create good error-handling code as it took to create the rest of the program. So frequently, for a variety of reasons, programmers skip that step. It is all too easy to write a program (in any language) without any error-handling code. You can tell the computer to go to the database, read in some values, ask the user for some input, add the user’s input into the existing data, and put it back into the database. That can be done in a programming language such as Visual Basic in about 30 lines of code. But that assumes nothing could ever go wrong. If you think about it, lots of things can go wrong: ■ The database is not available. ■ The database is available but you are unable to log in. ■ You can log in to the database, but the data is not available. ■ The data you retrieve from the database contains invalid values. ■ The user enters invalid values. ■ Adding the user’s data into the database data causes an error. ■ You are unable to save the data back to the database. So by the time you add code to your program to handle all those errors, you are suddenly looking at a 120-line program, instead of a 30-line program. So you see, it is certainly easier to avoid worrying about this type of stuff. But when you are writing programs professionally, you must worry about how errors are handled. Should the program crash when the user types in a wrong value? Or should you simply
  • 67. CHAPTER 2: Learn JavaScript Fundamentals 47 continue on, writing the bad data to the database, causing errors the next time the program is run? Or is the best solution to inform the user of their mistake and ask them to try again? This is why errors such as these need to be caught and properly handled. 2 The try-catch Statement Web browsers are designed to handle errors differently depending on the browser type and version, and to some degree on the user’s browser settings. In some cases, if you include some bad JavaScript code inside a web page the browser would simply not run it, with no error message or other indication that something went wrong. In other cases, the browser pops up a message box with details of the error it encountered, asking the user what to do next. The JavaScript error message usually looks something like this. For JavaScript developers, neither of the default error-handling methods is ideal. Ignoring an error completely stops the program from executing. And displaying an ugly error message to the user can be embarrassing for the programmer—not to mention frustrating to the user. There are some minor differences between the ways Netscape and Microsoft use this statement and what the official ECMA specification defines. In this section, I am using the statement as supported by most web browsers. The try-catch statement is used to allow programs to handle the error themselves, instead of allowing the browser to do it. It is often used to wrap a statement or set of statements that are likely to fail. The statement has the following syntax: try { statements; } catch (variable) { // error handling code statements; } The try-catch statement was only added in JavaScript 1.4, so only recent browsers (such as IE 5.5 and Netscape 6) support it.
  • 68. 48 How to Do Everything with JavaScript For example, you can surround a function call using the try-catch statement, and report a more friendly error message to the user if it fails. try { open_database(); } catch (err) { // error handling code alert("An error occurred connecting to the database." + " Please try again in a few minutes."); } So instead of receiving the ugly-looking JavaScript error message (or none at all, depending on the browser settings), your user will receive a friendlier message asking them to try again in a few minutes: The official system error message that occurred is still passed to the statement as a parameter of the catch clause. In our example, the err variable contains the description of the error that occurred. So if you needed to determine what happened inside the catch clause, you can. You can even display the original error message text to the user. The try-catch statement is not only used for catching system errors; you can also use this construct to catch errors generated by your own program. It is a good idea to use a try-catch statement when your program is attempting to do something that could cause an error, for instance, if your program is attempting to connect to an embedded Java applet. It is possible for an applet to encounter a problem and be unable to load, or for a browser’s security settings not to permit certain Java applets to run. If you surrounded such code in a try-catch statement, you could detect this problem and redirect the user to a non-Java version of the application. There are also plenty of errors that your application could detect programmatically, including: ■ Invalid user input in a form ■ Unsupported browser maker or version ■ Missing or invalid browser cookies The throw Statement The throw statement allows a JavaScript program to declare an error in the exact same manner as it would use for system errors. That means these errors can be caught using a try-catch statement.
  • 69. CHAPTER 2: Learn JavaScript Fundamentals 49 It also means that user-declared errors that are not caught are displayed to the user in a JavaScript pop-up dialog box. Like the try-catch statement, the throw statement was only added in JavaScript 1.4, so only recent browsers (such as IE 5.5 and Netscape 6) support it. 2 The following is an example of a program that throws its own errors. try { var errors = 0; // Do something errors++; if (errors > 0) { throw "Could not find the file."; } } catch (errorstring) { alert("The following error occurred:nn" + errorstring); } Understand the Basics of Expressions Many of the programming statements that we have been examining in this chapter use an expression to make some sort of decision. An expression is anything that returns a value. Table 2-2 lists the common types of expressions, along with an example of their use. Expression Example Numeric literal 47 String literal "Hello" Boolean literal true Object literal {make : "Toyota"} Program-defined variable x Program-defined function get_toast() Null null Assignment expression x=5 Mathematical operations x+y Boolean operations x == y Conditional operator x == 5 ? "yes" : "no" Combination x = "You have " + messagecounter + " new messages" TABLE 2-2 Common Types of Expressions
  • 70. 50 How to Do Everything with JavaScript Some statements, such as the if statement or while statement, specifically require expressions that return a Boolean value (true or false). JavaScript does its best to automatically convert strings and integers to the appropriate Boolean value. Expressions are also often used as parameters to functions, and can also be used as statements themselves. x = 5; This code is an expression, but it is also a statement. It assigns the value 5 to the variable x. Use Operators to Create Complex Expressions JavaScript provides a number of operators to perform mathematical and other functions within your code. Some operators modify the variables they operate on, although most do not. All operators return a value, and thus can be used to create complex expressions. There are 12 types of operators in JavaScript, and several dozen individual operators. Most operators are represented by symbols (like +), while some operators are represented by words (like new). Most operators require two operands, while some operators only require one (particularly the unary operators). Table 2-3 lists the operators available in JavaScript 1.5. Operator Type Operators Member dot (.) square bracket ([]) Unary new delete typeof instanceof void ++ -- negation (-) logical not (!) bitwise not (~) Multiplicative multiply (*) divide (/) modulus (%) Additive add (+) subtract (-) Bitwise Shift shift left (<<), unsigned shift right (>>>), signed shift right (>>) TABLE 2-3 Operators Available in JavaScript
  • 71. CHAPTER 2: Learn JavaScript Fundamentals 51 Operator Type Operators Relational less-than (<) greater-than (>) less-than-or-equal (<=) 2 greater-than-or-equal (>=) in Equality equal (==) not equal (!=) strictly equal (===) strictly not equal (!==) Bitwise Logical bitwise and (&) bitwise or (|) bitwise exclusive or (^) Logical logical and (&&) logical or (||) logical exclusive or (^^) Conditional conditional (?:) Assignment equals assignment (=) shortcut assignment (*=, /=, +=, -=, %=, <<=, >>=, >>>=, &&=, ||=, ^^=, &=, |=, and ^=) Special comma (,) function this TABLE 2-3 Operators Available in JavaScript (continued) JavaScript 2.0 adds two new operators to the language, and they are both considered relational: ■ is ■ as We have already seen a few of these operators in action so far in this chapter, such as equals (==), greater-than (>), increment (++), in, and equals assignment (=). Most of these operators have their origin in mathematics. Additional operators exist to deal with logical Booleans (such as logical and and logical or), plus binary operators to deal with the ones and zeros of binary math. Organize Your Code into Functions There may be the occasional instance when you can sit down and write an entire JavaScript program without functions, but believe it or not, that type of JavaScript program is rare. Most JavaScript programs contain at least one function.
  • 72. 52 How to Do Everything with JavaScript Functions allow you to predefine a group of JavaScript statements before you actually need to call that code. Since functions can be called repeatedly, with varying parameters, they are also convenient time-savers. Define Functions Functions are defined using the function keyword. Functions must be assigned a name and can optionally take one or more parameters. Parameters are contained in brackets, and separated by commas. function name(parameter1, parameter2, …, parameterN) { statements; } This is the JavaScript 1.5 format for defining functions. JavaScript 2.0 introduces some powerful extensions to this basic format, by allowing parameters to have a data type, the function itself to have a data type, parameters to be optional, named parameters, and more. We will examine the JavaScript 2.0 functions later in this chapter. The parameters specified inside the function definition are treated as variables inside the function. Parameter names must be unique, in that two parameters of the same function cannot have the same name. From the basic function syntax, we can define a basic function: function add_two(x, y) { if (x > 7) { x = x - 7; } else { x = x + 7; } if (y > 18) { y = y - 18; } else { y = y + 18; } return x + y; } The preceding code creates a function called add_two(). This function accepts two parameters, named x and y. The function’s name and the parameters it accepts are defined in the first line of code: function add_two(x, y) { The function’s code defines a somewhat complicated way to add two numbers together. First, the contents of both x and y are examined, and depending on their values something is added or subtracted from each.
  • 73. CHAPTER 2: Learn JavaScript Fundamentals 53 if (x > 7) { x = x - 7; } else { x = x + 7; 2 } if (y > 18) { y = y - 18; } else { y = y + 18; } Then the two numbers are added together and the result is returned. With the addition of a return statement that returns a result, this function can act as an expression, by returning a value. return x + y; Now the code just defines a function. If you were to add this into our HTML template and try to execute it in a web browser, it would actually do nothing. Functions need to be called in order to run. And if a function defines one or more parameters, values must be given for those as well. In order to call a function, you must do the following: 1. Type its function name followed by an open parenthesis: add_two( 2. Provide a list of parameters, if required, separated by commas: add_two(12, 2 3. Followed by a close parenthesis and a semicolon: add_two(12, 2); 4. Of course, in the case of our function, we need to assign its return value to a variable, or use it in a context that expects a value: var result = add_two(12, 2); We can combine the function definition, our HTML template, and a bit of code that calls our function with various parameters as follows: <html> <head> <title>JavaScript sample code</title> </head> <body> <h1>Defining JavaScript Functions</h1> <script language="JavaScript" type="text/javascript">
  • 74. 54 How to Do Everything with JavaScript <!-- // Begin function add_two(x, y) { if (x > 7) { x = x - 7; } else { x = x + 7; } if (y > 18) { y = y - 18; } else { y = y + 18; } return x + y; } document.write("add_two(2, 17) = " + add_two(2, 17) + "<BR>"); document.write("add_two(14, 9) = " + add_two(14, 9) + "<BR>"); document.write("add_two(100, 200) = " + add_two(100, 200) + "<BR>"); // End --> </script> </body> </html> In this code, we have inserted our add_two() function definition into the <script> section of our HTML template. For the code inside that function to be executed, we need to call that function. In our code, we call the function three times, with three different sets of parameters. When we load this code into a browser, we see something similar to Figure 2-4. Since we are calling the functions inside the document.write() function call, the output of the function is written to the screen. This is also a good example of how functions can themselves be passed as parameters to other functions—the value of add_two has to be executed to come up with the value that gets passed to document.write. Accept Parameters Of course, a function can be defined without any parameters. function print_header() { The parentheses are still required when defining and calling such a function. print_header();
  • 75. CHAPTER 2: Learn JavaScript Fundamentals 55 2 FIGURE 2-4 Defining a function and calling it repeatedly Another important consideration when using functions is how variables and even parameters are treated. Consider the following bit of JavaScript code: var counter; counter = 5; function add2(input) { input = input + 2; document.write("input = " + input + "<br>"); return; } add2(counter); document.write("counter = " + counter + "<br>"); What value will be written to the screen at the end of that program? We start off by defining a variable named counter, and assigning it a value of 5. We then define a function named add2()
  • 76. 56 How to Do Everything with JavaScript which appears to add the value 2 to the parameter that is passed to it. We then call this function with our counter variable and print its value to the screen. The answer is that counter will still have a value of 5 at the end of the program. Why? Well, that has to do with how parameters are handled inside functions. JavaScript does not pass the actual counter variable into the add2() function. It actually makes a copy of counter, and passes the copy into add2(). Therefore, any changes add2() makes to the parameter are lost when the function exits. JavaScript passes parameters by value, which means the value of any parameters cannot be permanently altered inside a function. Understand Variable Scope Another important rule concerning functions is one of variable scope. In programming, when and where a variable can be used is determined by where you define it. If you declare a variable inside
  • 77. CHAPTER 2: Learn JavaScript Fundamentals 57 a function, it can only be used inside that function. When you exit the function, the variable is no longer defined and its value is lost. // get_factors() returns all the numbers that divide into // the parameter evenly 2 function get_factors(inputValue) { var counter; var factorString = ""; for (counter = 1; counter <= inputValue; counter++) { if ((inputValue % counter) == 0) { factorString = factorString + counter + " "; } } } get_factors(6777214); document.write (factorString); For instance, in this code, a function named get_factors() is defined. We then call it using the value 6,777,214 as its parameter. We would like to print out the string that results using document.write(), but by that time it is too late. The factorString variable is only valid inside the function, because that is its scope. When we attempt to run this program, an error message attributed to the final line of our program is displayed. The variable factorString cannot be used outside the function in which it is defined.
  • 78. 58 How to Do Everything with JavaScript If we were to move the document.write() statement inside the function call, we would see a better result. Return Values Inside a function, the return statement serves two purposes: ■ It causes the function to exit. ■ It optionally passes a value back to the line of code that called it. Much as the break statement causes a loop to exit, the return statement causes a function to exit as well. Since functions can act as expressions by returning a value to the code that called it, the return statement can accept the value returned as an optional parameter. ■ return; ■ return "Hello"; ■ return 32; ■ return true;
  • 79. CHAPTER 2: Learn JavaScript Fundamentals 59 All four of these are valid uses of the return statement inside a function. Use the Improvements in JavaScript 2.0 2 to Create More Powerful Functions JavaScript 2.0 brings a number of improvements to the language. The European Computer Manufacturers Association (ECMA) has added a number of features that increase the power and flexibility: ■ Classes ■ Packages ■ Namespaces ■ Data types ■ More powerful and flexible data arrays ■ Access controls, such as public and private With this added functionality, JavaScript can now be used for tasks that used to require a more complex language like C++ or Java, while still retaining the simplicity that has made JavaScript so popular with web developers for all these years. If you’ve worked with JavaScript before, one of the first changes you will notice is the addition of data types to the language. Data types allow you to restrict the range of values a variable can contain or a function can return. We can modify the add_two() function we defined earlier in this chapter with JavaScript 2.0 syntax to use data types for all its variables, parameters, and the function itself: function add_two(x : Number, y : Number) : Number { if (x > 7) { x = x - 7; } else { x = x + 7; } if (y > 18) { y = y - 18; } else { y = y + 18; } return x + y; }
  • 80. 60 How to Do Everything with JavaScript Now that we have added the Number data type to our x and y parameters, JavaScript will report an error if something other than a number is passed. It is also clearer to other developers what data types we expect for each of the parameters. Use Named Optional Parameters Another change to the way parameters are used in JavaScript 2.0 is the ability to define named optional parameters. The named keyword allows us to identify some parameters as optional when defining the parameter list of a function. For instance, let’s say we have a function that expects a person’s name to be passed to it in three parts: function sayHello (first : String, initial : String, last : String) : String { var fullname; if (initial <> "") { initial = initial + ". "; } fullname = first + " " + initial + last; return fullname; } If we define it using the preceding syntax, we have no choice but to call it in the following way: sayHello ("Scott", "", "Duffy"); But by using the named modifier on the middle initial parameter, we can allow the function to be called without the middle initial. function sayHello (first : String, last : String, named initial : String = "") : String { var fullname : String; if (initial <> "") { initial = initial + ". "; } fullname = first + " " + initial + last; return fullname; } document.write (sayHello ("Scott", "Duffy") + "<br>"); document.write (sayHello ("Bobby", "Jones", initial:"H") + "<br>");
  • 81. CHAPTER 2: Learn JavaScript Fundamentals 61 By defining the middle initial parameter as named, we can then call the sayHello() function with only the first and last name specified. Named parameters must always specify an initializer in case a value is not specified for that parameter, so one can be assigned. If you want to provide a value for a named parameter, you have to refer to that parameter by name. 2 Accept Any Number of Parameters Functions in JavaScript 2.0 can be defined so that they can accept an unlimited number of parameters. You would want to do this when your function needs to accept a large number of identical parameters but you do not want to create lots of named optional parameters. The rest parameter must always appear at the end of any unnamed parameters that are defined, using three periods (...). Named parameters, those defined using the named keyword, can still be listed after the rest parameter. Of course, there can only ever be one rest parameter for a single function. The following code defines a function that can accept an unlimited number of parameters. The first four arguments passed will be assigned to the first four parameters defined: name, address, phoneNum, and spouseName. Any arguments passed beyond those four will be assigned to an array called childName. We can use a for-in loop to get the list of names out of that variable. (We will look at arrays in depth in Chapter 4.) function printform (name : String, address : String, phoneNum : String, spouseName : String, ... childName : Array) { // An unlimited number of children can be provided with (document) { write ("Name: " + name + "<br>"); write ("Spouse: " + spouseName + "<br>"); write ("Address: " + address + "<br>"); write ("Phone: " + phoneNum + "<br>"); for (child in childName) { write ("Child " + childName[child] + "<br>"); } } return; } In the next chapter, we will focus on some of JavaScript’s most powerful features—its built-in objects and functions.
  • 83. Use Built-in Chapter 3 JavaScript Classes
  • 84. 64 How to Do Everything with JavaScript How to... ■ Master objects in JavaScript ■ Understand JavaScript’s built-in classes and data types ■ Create a String object in JavaScript ■ Perform mathematical functions ■ Apply JavaScript’s date-handling functions ■ Convert strings into numbers ■ Prepare text before sending to web server ■ Decide when to use regular expressions ■ Use JavaScript 2.0’s powerful new data types ■ Decide when to use JavaScript 2.0’s special data types JavaScript has always contained a number of built-in classes that programmers could employ when developing programs. These classes—self-contained data and code—provide useful functionality for handling dates, mathematical functions, and arrays. For instance, if you wanted to retrieve the current date and time in JavaScript, you would create an instance of the Date class, as so: var today = new Date(); The today variable in this code is actually an object. Not only does the today object contain a value (today’s date in fact), but it also contains a number of built-in functions for retrieving and setting individual parts of the date and converting it into a number of different formats (a string, for instance). The Date class, and all of its functionality, is explored in the section “Apply JavaScript’s Date-Handling Functions,” later in the chapter. JavaScript 1.5 contains nine such classes, but only three are used in common practice (Array, Date, and Math). JavaScript 2.0 has expanded the list to more than 18 classes, and almost all of them are useful. In this chapter, we will examine most of these classes and learn to apply them in our JavaScript programs. Learn about Objects in JavaScript We are approaching the 50th anniversary of the development of Fortran, the first high-level programming language, which was developed in 1956. Since that time, computer scientists have developed several programming methodologies. Table 3-1 lists the most common methods of designing programs. It’s important to remember that no methodology is perfect for every situation. In JavaScript programming, you are likely to use any of the four methodologies listed in Table 3-1, depending on the task at hand.
  • 85. CHAPTER 3: Use Built-in JavaScript Classes 65 Methodology Description Unstructured Sequence of statements acting on global data Procedural Main program that calls functions to perform certain tasks Modular Main program that uses modules to group related functionality Object-oriented Main program that uses objects to group related data and functionality 3 TABLE 3-1 Common Programming Methodologies Write Unstructured Programs Unstructured programming is usually best used for short, simple scripts, since they would not benefit from many functions and objects. An unstructured program is simply a set of JavaScript statements that does not use user-defined functions or objects. The following is an example of an unstructured program, in the context of an HTML web page. Notice that there are only three lines of JavaScript code in the program. <html> <head> <title>JavaScript sample code</title> </head> <body> <h1>Unstructured Program</h1> <script language="JavaScript" type="text/javascript"> <!-- // Begin for (var counter = 1; counter < 101; counter++) { document.write ("This is line number " + counter + "<br>n"); } // End --> </script> </body> </html> Organize Code into Procedures Procedural code is also quite common in JavaScript programming. We could easily rewrite the unstructured code in the preceding program using the procedural approach. function printline(value) { document.write ("This is line number " + value + "<br>n"); } for (var counter = 1; counter < 101; counter++) { printline(counter); }
  • 86. 66 How to Do Everything with JavaScript This program creates a function named printline(), whose sole job is to write text to the screen that includes the value passed to it as a parameter. Later on in the program, we can repeatedly call that function. The benefits of this type of programming practice are twofold: ■ The same function can be called from multiple locations in a program, thereby removing the code duplication of an unstructured approach. ■ Dividing a program into functions makes it easier to test, which generally results in fewer bugs. Separate a Program into Modules If a program gets sufficiently big (in size and scope), it gets increasingly difficult to manage and maintain. Programmers require an additional technique (besides using procedures and functions) to separate their programs into smaller, more manageable pieces. The next logical step up from the procedural approach is the modular approach. Modular programming generally involves separating one large program into two or more separate files. These files, or modules, as they are called, are not necessarily self-contained, but they do group related code and functions together. Typically, a modular program consists of a main program plus one or more modules, such as: ■ Main program ■ Database module ■ User interface module ■ Error-handling module We can infer from the preceding modular configuration that the main program does most of the work, but it calls functions that exist in the database module whenever it needs to talk to the database. Similarly, it uses the user interface and error-handling modules to do their own tasks, as needed. This type of program is much easier for a programmer to manage when broken up into modules, as opposed to one large single module. To create a modular program using JavaScript, you need to create one or more JavaScript files. When you import those external code files into an HTML page using a property of the <script> tag, your main program has access to all the functions defined in those external modules. We will learn more about creating and importing JavaScript files in Chapter 6. Use the Object-Oriented Approach The next progression from modular programming is to object-oriented programming. The concept of objects can be a little bit intimidating at first, but that should not stop anyone from attempting to at least understand how using objects can make the job of a programmer much easier.
  • 87. CHAPTER 3: Use Built-in JavaScript Classes 67 In programming, an object is simply a “thing” that has its own attributes (known as properties) and related functions (known as methods). You can think of objects in programming just as you would think of objects in real life. Let me give you an example. My car is an object that has certain attributes and can perform certain actions. The unique attributes of my car distinguish it from most others on the road. Even if I encounter another vehicle that is the same make and model as my own, they are still separate vehicles. The 3 following is a list of some common properties of my car: Property Value Year 2001 Make Toyota Model 4Runner SR5 Tires 4 Doors 4 Color Thundercloud Speedometer (mph) Ranges from 0 to 70 Gas gauge (volume, in gallons) Ranges from 0.0 to 16.0 Etc. What I have just listed are, in fact, the programming variables that will go into my Car object. In fact, the first five properties (Year, Make, Model, Tires, and Doors) are permanent— in programming parlance they’re constants. The rest of the properties can be changed, thus they are variable. Remember, we examined constants and variables in Chapter 2. If I were to turn the list of properties related to my car into JavaScript 2.0 code, it would look something like this. const Year : Integer; const Make : String; const Model: String; const Tires : Integer; const Doors : Integer; var Color : String; var CurrentSpeed : Number; var CurrentGas : Number; Besides having several properties, my car also has several actions it can perform: If I do this… The car does this… Step on the gas pedal Increases its speed; increases fuel consumption Step on the brake pedal Decreases its speed; decreases fuel consumption
  • 88. 68 How to Do Everything with JavaScript If I do this… The car does this… Turn the steering wheel right or left Turns its front wheels right or left Press the center of the steering wheel Honks its horn Add gasoline into the gas tank Increases its gas volume Again, from a programmer’s perspective these are functions of the car. Many of the functions are related to the car’s properties. For instance, both the gas pedal and the brake pedal affect the car’s speed and gasoline usage. If my car were a programmable object, it would have the following JavaScript 2.0 function definitions. function depressGasPedal (howMuch : Integer) {} function depressBrakePedal (howMuch : Integer) {} function turnSteeringWheel (degrees : Integer) {} function beepHorn () {} function addGas (volume : Number) {} Turn Properties and Functions into a Class Simply defining the collected constants, variables, and functions of a car does not make it an object. Before a collection of code can become an object, it must first become a class. A class is a self-contained grouping of variables and functions. The variables and functions of a class, also called its members, cannot be used to store data or perform actions. Classes are merely the blueprints from which objects are created. There will only ever be one Car class in our computer program, but there could potentially be several Car objects. There could also be no Car objects, if we do not choose to create any. There is one exception to the rule that classes cannot store data or perform actions. If a class member is defined as static, it can be used without the existence of an object. Static class members are discussed in more detail in Chapter 5. We will examine user-defined classes in Chapter 5. There is a different syntax for creating this class definition in JavaScript 1 and JavaScript 2, and it is important to understand the difference. Without getting into more detail, this is how our Car class would look in JavaScript 2.0 syntax. class Car { const Year : Integer; const Make : String; const Model: String; const Tires : Integer; const Doors : Integer;
  • 89. CHAPTER 3: Use Built-in JavaScript Classes 69 var Color : String; var CurrentSpeed : Number; var CurrentGas : Number; function depressGasPedal (howMuch : Integer) { // Gas pedal JavaScript code } 3 function depressBrakePedal (howMuch : Integer) { // Brake pedal JavaScript code } function turnSteeringWheel (degrees : Integer) { // Steering wheel JavaScript code } function beepHorn () { // Horn JavaScript code } function addGas (volume : Number) { // Gas tank JavaScript code } } We can create a Car object by calling the new operator with the name of the Car class. We will examine the new operator in more detail in the section “Instantiate an Object with the new Operator,” later in this chapter. var myAuto = new Car(); myAuto.Year = 2001; myAuto.Make = "Toyota"; // etc. Finally, classes in JavaScript 2.0 are also automatically defined as data types, so variables can be defined that can only contain the specified object. var Ferrari : Car = new Car(); JavaScript’s Built-in Classes and Data Types Despite the lack of true data types in previous versions of the language, JavaScript has always had the concept of classes. Developers could use a number of built-in classes, which provided useful methods and functions for manipulating certain types of data. Table 3-2 lists the classes that exist in JavaScript 1.5, along with a brief description of the functionality each class provides. The most significant improvement in JavaScript 2.0 is that the language has evolved to become more object-oriented than it ever was before. JavaScript 1.5 was object-based, but did
  • 90. 70 How to Do Everything with JavaScript Class Name Description Array Allows lists of data to be stored in a single variable Boolean A wrapper for Boolean values Date Lets you work with dates and times Function Allows you to define a function programmatically Math Contains convenient mathematical constants and functions Number A wrapper for primitive numeric values Object All objects derive from this data type RegExp Provides support for regular expressions in JavaScript String A wrapper for string values TABLE 3-2 Predefined Core JavaScript 1.5 Classes not meet several of the key attributes of object-oriented programming languages. JavaScript 2.0 meets most of the key attributes. Table 3-3 lists the classes supported by JavaScript 2.0. The list is obviously much longer than that in Table 3-2. Class Name Description Array Allows lists of data of type Object to be stored in a single variable; is equivalent to the Array[Object] data type Array[type] Allows lists of data of type type to be stored in a single variable Boolean Supports variables that can only store true and false char Supports variables that can only store a single character ConstArray Allows lists of data of type Object to be stored in a single constant; is equivalent to the ConstArray[Object] data type ConstArray[type] Allows lists of data of type type to be stored in a single constant DynamicArray[type] Allows resizable lists of data of type type to be stored in a single variable Function The “data type” of functions Integer Supports variables that can only store integers Never Supports variables that cannot contain any value Null Supports variables that can only store “null” Number Supports variables that can only store numbers Object Supports variables that can contain any value Prototype Supports variables that contain prototype-based objects (JavaScript 1.5’s way of handling objects) TABLE 3-3 Predefined Data Types in JavaScript 2.0
  • 91. CHAPTER 3: Use Built-in JavaScript Classes 71 Class Name Description StaticArray[type] Allows writable lists of data of type type to be stored in a single variable String Supports variables that can only store strings Type The “data type” of data types Void Supports variables that can only store “undefined” 3 TABLE 3-3 Predefined Data Types in JavaScript 2.0 (continued) All classes in JavaScript 2.0, even ones you create yourself, can be used as data types. Consequently, the list of classes in Table 3-3 is also a partial list of data types. In addition to the list of predefined classes that can be used as data types in Table 3-3, there are a number of machine types in JavaScript 2.0. These machine types (listed in Table 3-4) are low-level data types that can be used in JavaScript, although not all JavaScript environments will support them. They are provided for compatibility with other languages—for instance, when your JavaScript program needs to exchange data with an external C-language application. NaN (Not a Number) is a defined constant in JavaScript that is, effectively, a number representing that an error occurred when processing that variable. Machine types can be used just like data types derived from classes, although they are not classes themselves. For instance, in the following JavaScript 2.0 code listing, we create a handful of variables defined as machine types. var counter : short = 14; var account_balance : int = 1701330222; var bigNumber : long = 74440000000000; var anotherBigNumber = 312L; The machine type suffixes listed in Table 3-4 are convenient shorthand notation for assigning a machine type to a value. The three suffixes—L, UL, and F—indicate to JavaScript that you wish to treat a number as either a long, unsigned long (ulong), or float number respectively. So the expression “0L” tells JavaScript to treat the value 0 as a long, due to the L machine-type suffix. In the preceding code, the variable anotherBigNumber will be treated as a long integer, since we are assigning the value 312L to it. The L suffix forces the value 312 to be treated as a long integer. This works only when assigning numeric literals to a variable, and will not work with other types of expressions such as variables.
  • 92. 72 How to Do Everything with JavaScript Type Suffix Range of Values sbyte Integers between –128 and +127 byte Integers between 0 and +255 short Integers between –32768 and +32767 ushort Integers between 0 and +65535 int Integers between approximately –2.1 billion and +2.1 billion uint Integers between approximately 0 and +4.3 billion long L Integers between approximately –9 quintillion and +9 quintillion (9 followed by 18 zeros) ulong UL Integers between approximately 0 and +18 quintillion (18 followed by 18 zeros) float F Single-precision floating point numbers, including positive and negative zeros, infinities, and NaN TABLE 3-4 Machine Types Defined in JavaScript 2.0 Instantiate an Object with the new Operator The procedure to create an object from either a user-defined or system-defined class is basically the same. JavaScript provides a special operator called new for this purpose, also called object instantiation. var myAuto = new Car(); When the new operator is called with the name of an existing class (in this example, Car), it calls the class’s constructor and returns an instance of the object. By assigning that object instance to the variable myAuto, we are keeping a reference to that object so we can use it in our program. A constructor is a special function defined in some classes that makes the object ready for use. The initialization code is placed in the constructor. Classes can have more than one constructor or none at all. We examine creating your own classes, and constructors for those classes, in Chapter 5. Any parameters included in our new operator are passed to the constructor as parameters as well. If we had defined a constructor to our Car class, we would probably want to allow the user to pass in most of the relevant properties (Make, Model, Year, etc.) as parameters, so that the constructor can make the object completely ready for use. Otherwise, we would have a Car object with no predefined properties and our program would have to manually set each relevant one. var myAuto = new Car (2001, "Toyota", "4Runner SR5", "Thundercloud"); This technique of object initialization using the constructor is a recommended programming technique.
  • 93. CHAPTER 3: Use Built-in JavaScript Classes 73 Access an Object with the . Operator Once an object has been created using the new operator, we can access all its public properties and methods using the dot operator (.). The dot operator is placed between the object name (not the class name) and the name of the property or method you wish to access. document.write ("Your car was created in " + myAuto.Year); 3 In this code example, we actually use the dot operator twice. We use it to access the write() method of the built-in document object and also to access the Year property of our user-defined myAuto object, which is an instance of the Car class. You can define properties and methods as private, which restricts the ability to access them using the dot operator. We will examine private properties and methods in Chapter 5. Access an Object with the [] Operator JavaScript also allows access to an object’s properties using the square brackets operator ([]). The one advantage this operator has over the dot operator is that you do not need to know the name of the property you wish to look up. For instance, let’s look at the following for-in loop. for (var tool in toolchest) { document.write(toolchest[tool] + "<BR>"); } In this code example, we are passing a variable named tool to the square brackets operator, which is then able to extract the value of the property from the toolchest object. The public properties of any class defined in JavaScript 2.0 can be accessed using the square brackets operator. This even works for JavaScript’s built-in DOM objects for version 1.5. for (var prop in document) { document.write ("document." + prop + " = " + document[prop] + "<BR>"); } This code results in the entire contents of the DOM document object being written to the web browser window, as you can see in Figure 3-1. Since the DOM is slightly different between different browser makers and even versions of the same browser, your own test will probably reveal different properties and values. Create a String Object in JavaScript A string is simply a sequence of zero or more Unicode characters. The following are all valid strings: ■ "" (an empty string) ■ "How was work today, Sofia?"
  • 94. 74 How to Do Everything with JavaScript ■ "32" (numeric characters) ■ "Êtes-vous prêt pour l’examen?" (non-English characters) There are two ways to create strings in JavaScript: ■ A string literal ■ Using the String object The vast majority of strings are created using the string literal, since it is by far the quickest and easiest technique. Create a String Object Using a String Literal A string literal in JavaScript is simply a sequence of zero or more characters surrounded by either single or double quotation marks, like so: var myString = "This is a string literal"; var myOtherString = 'So is this, using single quotation marks.'; FIGURE 3-1 The contents of the document object in Internet Explorer 6.0
  • 95. CHAPTER 3: Use Built-in JavaScript Classes 75 The string literal can be used with any version of JavaScript. In JavaScript 2.0, you can even go so far as to assign the variable a String data type, while using a string literal to create the object. var title : String = "How To Do Everything with Paper Clips"; 3 It’s important to remember that creating a String object using a string literal still allows you to use all the properties and methods provided by the object. var myString = "This is a string literal"; var myOtherString = 'So is this, using single quotation marks.'; document.write (""" + myString + "" = " + myString.length + " characters<br>"); document.write ("'" + myOtherString + "' = " + myOtherString.length + " characters<br>"); Length is a property of the String object. Accessing the length property results in the actual length of the string, as we can see in the following browser output.
  • 96. 76 How to Do Everything with JavaScript Create a String Object Using the String Data Type JavaScript 1.1 introduced the ability to create strings using the String class constructor. var hometown = new String("Chicago"); By passing the text of the string to be created into the constructor, we end up with the hometown variable being a String. There are almost no advantages to creating strings like this, and you will very rarely see it done. Use the String Object’s Built-in Functionality String objects are given a number of predefined functions, which allow you to perform all sorts of manipulations on them. Table 3-5 lists the most common String methods. Four of the methods listed in Table 3-5 work with regular expression patterns. We examine regular expressions in the section “Understand the Basics of Regular Expressions,” later in this chapter. Method Purpose charAt (index) Returns one character from the string charCodeAt (index) Returns the ASCII code of one character from the string concat (string) Joins two strings together indexOf (string, index) Finds the first occurrence of one string inside another lastIndexOf (string, index) Finds the last occurrence of one string inside another match (regexp) Searches the string for the regular expression pattern, and returns any matches replace (regexp, newString) Searches the string for the regular expression pattern, and replaces any matches with the string provided search (regexp) Searches the string for the regular expression pattern, and returns the index of the first match split (separator, limit) Splits a single string into an array of substrings, based on a separator character or regular expression substring (start, end) Returns a part of a string toLowerCase () Returns the string as lowercase characters toString () Same as valueOf (); returns the string toUpperCase () Returns the string as uppercase characters valueOf () Returns the string TABLE 3-5 Common String Object Methods
  • 97. CHAPTER 3: Use Built-in JavaScript Classes 77 Each of the methods listed in Table 3-5 can be accessed from any String object using the dot operator. var msg = "ERROR: Invalid User ID or Password<br>"; document.write ( "<b>Original message:</b> " + msg.valueOf() ); document.write ( "<b>Upper case:</b> " + 3 msg.toUpperCase() ); document.write ( "<b>Lower case:</b> " + msg.toLowerCase() ); document.write ( "<b>Partial string:</b> " + msg.substring(20, 22) + "<br>" ); document.write ( "<b>Single character:</b> " + msg.charAt(17) + "<br>" ); document.write ( "<b>Search from beginning:</b> " + msg.toLowerCase().indexOf("sword") + "<br>" ); document.write ( "<b>Search from end:</b> " + msg.lastIndexOf("User ID") + "<br>" ); As you can see from the following screenshot, all the String properties can be applied to the msg object, since msg is of type String.
  • 98. 78 How to Do Everything with JavaScript More than one dot operator can appear in a single expression. Take the expression “msg.toLowerCase()”—this expression will return the msg string as all lowercase characters. You can apply another String method to that expression, such as “msg.toLowerCase().indexOf(“sword”)”. Since the indexOf() method returns an integer, you could add a third dot operator to perform one of the Integer object methods. Perform Mathematical Functions JavaScript provides one built-in class that cannot actually be used to create an object—Math. The purpose of the Math class is to provide all sorts of mathematical functions and constants. Since all the members of the Math class are defined as static, you can call them directly using the Math object. Attempting to create an object based on the Math class results in an error in JavaScript. You call Math’s static members using the dot operator, just as you would with the instance members of any other class. Table 3-6 lists the names of all the predefined constants provided by the Math class. The Math class also provides a number of methods that are useful for performing complex mathematical calculations, as shown in Table 3-7. For example, if we wanted to create some JavaScript code that took advantage of the mathematical constants and functions provided by the Math object, we could do the following: // area of a 12-inch circle, (PI * r^2) var area = Math.PI * Math.pow (12/2, 2); // length of the long side of a right angle triangle // assume, 5 inch base and 7 inches high, (a^2 + b^2 = c^2) var longside = Math.sqrt( Math.pow(5,2) + Math.pow(7,2) ); Instance Members Versus Static Members By default, properties and methods of a class will be defined as instance members. This means that they can only be accessed within the instance of an object based on that class. These objects are created using the new keyword, and a new copy of the class’s instance members will be created for each new object created. If you create 100 objects based on a class, you have 100 separate copies of each method and variable. Changing the value of one of the copies does not affect the others. Properties and methods of a class can optionally be defined as static members. Static members can only be accessed directly from the class and are not part of instances created based on that class. In essence, static class members are global, since only one version of that member ever exists, regardless of how many objects have been created from it.
  • 99. CHAPTER 3: Use Built-in JavaScript Classes 79 Constant Purpose E Euler’s constant, 2.7183 LOG2E The base 2 logarithm of E LOG10E The base 10 logarithm of E LN2 The natural logarithm of 2 3 LN10 The natural logarithm of 10 PI Pi, 3.1416 SQRT2 The square root of 2 SQRT1_2 The square root of one-half (0.5) TABLE 3-6 A List of the Static Constants Provided by the Math Class Apply JavaScript’s Date-Handling Functions We already took a quick look at the Date class at the beginning of this chapter, but it is worth looking at it again in more detail. The Date class allows you to create Date objects containing any date you specify, or today’s date if you specify none. With a Date object, you can: ■ Retrieve specific parts of the date (the month, for instance) ■ Change or modify parts of the date ■ Convert the date between different string formats ■ Convert the date between different time zones Method Purpose abs (x) The absolute value of x acos (x), asin (x), atan Trigonometry functions (x), atan2 (y, x), cos (x), sin (x), tan (x) ceil (x) Returns the next largest integer larger than x (or x, if it is an integer) exp (x) Returns the constant E to the power of x floor (x) Returns the next lower integer less than x (or x, if it is an integer) log (x) Returns the natural logarithm of x max (x, y) Returns x or y, whichever is highest min (x, y) Returns x or y, whichever is lowest pow (x, y) Returns x to the power of y TABLE 3-7 Static Methods of the Math Object
  • 100. 80 How to Do Everything with JavaScript Method Purpose random () Returns a pseudorandom number between 0 and 1 round (x) Rounds x to the nearest integer sqrt (x) Returns the square root of x TABLE 3-7 Static Methods of the Math Object (continued) Early versions of JavaScript restricted the Date object so that it could not handle dates before January 1, 1970. This was corrected in version 1.3 of the language. Dates can now range between –100 million and +100 million days of January 1, 1970, which is approximately 270,000 years into the past and future. There are no such things as date literals in JavaScript, so a Date object can only be created out of the Date class. The constructor for the Date class accepts a number of different input parameters. var holiday = new Date ("July 4, 2010"); var newyears = new Date (2010, 12, 31); var today = new Date (); var midnight = new Date (2010, 12, 31, 23, 59, 59, 999); As we can see in the code, the Date constructor can attempt to interpret a date written as a string literal. You can also pass in the year, month, and day as integers. You can even specify the date and time down to the millisecond. If no parameters are provided, the object is set to today’s date by default. Table 3-8 lists all the methods supported by the Date object. Using these methods, you can extract specific parts of a date, change the date, or convert it to different formats. Method Purpose getDate () Returns the day of the month (1–31) according to local time getDay () Returns the day of the week (1–7) according to local time getFullYear () Returns the four-digit year according to local time getHours () Returns the hour component of the time according to local time getMilliseconds () Returns the milliseconds component of the time according to local time getMinutes () Returns the minutes component of the time according to local time getMonth () Returns the month (0–11) according to local time; 0 is January, 1 is February, and so on getSeconds () Returns the seconds component of the time according to local time TABLE 3-8 Methods of the Date Object
  • 101. CHAPTER 3: Use Built-in JavaScript Classes 81 Method Purpose getTime () Returns the numeric value corresponding to the time getTimezoneOffset () Returns the number of hours the current time is offset from Universal time (Greenwich mean time) getUTCDate () Returns the day of the month (1–31) according to Universal time 3 getUTCDay () Returns the day of the week (1–7) according to Universal time getUTCFullYear () Returns the four-digit year according to Universal time getUTCHours () Returns the hour component of the time according to Universal time getUTCMilliseconds () Returns the milliseconds component of the time according to Universal time getUTCMinutes () Returns the minutes component of the time according to Universal time getUTCMonth () Returns the month (0–11) according to Universal time; 0 is January, 1 is February, and so on getUTCSeconds () Returns the seconds component of the time according to Universal time getYear () Returns the year according to local time parse (string) Parses a date string and returns the number of seconds since January 1, 1970 setDate () Sets the day of the month (1–31) according to local time setFullYear () Sets the four-digit year according to local time setHours () Sets the hour component of the time according to local time setMilliseconds () Sets the milliseconds component of the time according to local time setMinutes () Sets the minutes component of the time according to local time setMonth () Sets the month (0–11) according to local time; 0 is January, 1 is February, and so on setSeconds () Sets the seconds component of the time according to local time setTime () Sets the numeric value corresponding to the time setUTCDate () Sets the day of the month (1–31) according to Universal time setUTCFullYear () Sets the four-digit year according to Universal time setUTCHours () Sets the hour component of the time according to Universal time setUTCMilliseconds () Sets the milliseconds component of the time according to Universal time setUTCMinutes () Sets the minutes component of the time according to Universal time setUTCMonth () Sets the month (0–11) according to Universal time; 0 is January, 1 is February, and so on setUTCSeconds () Sets the seconds component of the time according to Universal time setYear () Sets the year according to local time toDateString() Returns a string representing the date portion of the specified Date object toGMTString () Converts a date to a string, using the Internet GMT conventions TABLE 3-8 Methods of the Date Object (continued)
  • 102. 82 How to Do Everything with JavaScript Method Purpose toLocaleDateString() Converts the date portion of a date to a string, using the current locale’s conventions toLocaleString () Converts a date to a string, using the current locale’s conventions toLocaleTimeString() Converts the time portion of a date to a string, using the current locale’s conventions toString () Returns a string representing the specified Date object toTimeString() Returns a string representing the time portion of the specified Date object toUTCString () Converts a date to a string, using the Universal time convention UTC () Returns the number of milliseconds in a Date object since January 1, 1970, 00:00:00, Universal time valueOf () Returns the primitive value of a Date object TABLE 3-8 Methods of the Date Object (continued) The constructor for the Date class accepts four formats. The actual date the object represents depends on the number and type of parameters passed. To create a date based on... Use this... A date string new Date (“January 1, 2008”) Date components new Date (2008, 0, 31) Date and time components new Date (2008, 0, 31, 12, 0, 0, 0) Milliseconds since new Date (1034214221530) January 1, 1970 Current date and time new Date () JavaScript expects numbers in the range of 0 to 11 to represent months of the year. January is month 0, February is month 1, and so forth. Convert Strings into Numbers JavaScript contains two built-in ways to convert numbers embedded in strings (like "32") into actual numbers that can be used in mathematical equations (like 32)— parseInt () and parseFloat (). As their names imply, the parseInt function will return an integer (a number without a decimal portion), and parseFloat will return a floating-point number (including any decimal portion). Use the parseInt and parseFloat Functions JavaScript provides parseInt and parseFloat to help you convert numbers inside strings into actual number data types. This is an important technique when it comes to Internet web pages, since data read in from URLs and forms usually arrives as strings. Here is how they work:
  • 103. CHAPTER 3: Use Built-in JavaScript Classes 83 1. Start by defining a variable to contain your string. var myString; 2. Assign a string that contains a valid number to that variable. This number does not have to be an integer. var myString; 3 myString = "3.14159265358979323846"; // The value of Pi... 3. Define a variable to contain your integer. var myString, myInteger; myString = "3.14159265358979323846"; // The value of Pi... 4. Call the parseInt () function on the string, and assign the value to the integer. var myString, myInteger; myString = "3.14159265358979323846"; // The value of Pi... myInteger = parseInt (myString); 5. The parseInt () function should return the value 3 from the string defined in this example. We can verify this with a call to the alert message box. var myString, myInteger; myString = "3.14159265358979323846"; // The value of Pi... myInteger = parseInt (myString); alert (myInteger); 6. What would happen if myString were not a valid number? Let’s modify it and find out. var myString, myInteger; myString = "Madrid, Spain"; // The value of Pi... myInteger = parseInt (myString); alert (myInteger);
  • 104. 84 How to Do Everything with JavaScript The parseFloat () function works in a similar fashion to parseInt (), except the digits after the decimal place are included. We can verify this by changing the function name. var myString, myInteger; myString = "3.14159265358979323846"; // The value of Pi... myInteger = parseFloat (myString); alert (myInteger); Prepare Text Before Sending to Web Server Every web page on the Internet has a unique URL (uniform resource locator). Even web pages stored on your hard drive have their own unique URL. The following are a few examples of URLs: URL URL Description http://www.amazon.com/ Default web page of Amazon.com news:comp.infosystems.www.servers.unix Usenet newsgroup file:///C:/temp/test.html File residing on user’s hard drive Uniform Resource Locator (URL) Limitations The URL format only accepts the following characters in the URL string: ■ Letters—a to z ■ Numbers—0 to 9 ■ Marks—$ - _ + ! * ‘ ( ) , ■ Special characters reserved for special purposes—; / ? : @ = & No other characters can appear in a URL. And the special characters can only be used in their designated roles. Characters that fall outside these rules must be properly escaped, as described in “Use the escape and unescape Functions.”
  • 105. CHAPTER 3: Use Built-in JavaScript Classes 85 Imagine a file with a long and uniquely creative name, such as We're #1 & proud of it; no ifs ands or buts!.htm. Windows does allow such a name for a file. But when it comes to accessing this file through a browser, we’re going to have problems. The space, #, &, !, and ; characters are not allowed in the URL naming scheme. In order to access the file, it will first have to be escaped, as described in the following section. 3 Use the escape and unescape Functions Escaping a file is the process of converting all the invalid characters into specially encoded symbols before sending the URL to the server to process. To escape a filename, we must use the escape function built into JavaScript. 1. Start with a string that has some invalid characters inside it. var filename; filename = "We're #1 & proud of it; no ifs ands or buts!.htm"; 2. Define a variable to contain the escaped character sequence. var filename, newFilename; filename = "We're #1 & proud of it; no ifs ands or buts!.htm"; 3. Assign the result of the escape function on the string to the new variable. var filename, newFilename; filename = "We're #1 & proud of it; no ifs ands or buts!.htm"; newFilename = escape(filename); 4. To examine the results of the escape() function, we should display it to the user using an alert box. var filename, newFilename; filename = "We're #1 & proud of it; no ifs ands or buts!.htm"; newFilename = escape(filename); alert (newFilename);
  • 106. 86 How to Do Everything with JavaScript Decide When to Use Regular Expressions Regular expressions are a powerful search-and-replace technique that is widely used in other environments (such as Unix and Perl), but rarely used in JavaScript. Perhaps if more programmers knew about the existence of regular expressions in JavaScript, their use would catch on. JavaScript only started supporting regular expressions in version 1.4 of the language, which means they will only work in Netscape 4 or Internet Explorer 4 web browsers, or subsequent releases. A regular expression is a sequence of characters written using a special regular expression language, which can be used to match patterns in other strings. To give you an idea of how powerful the regular expression pattern matching capability is, I wrote a little JavaScript program (primarily using the String object’s substring() method) that checks to see if a string matches the standard telephone number format—(XXX) XXX–XXXX, where X represents any number from 0 to 9. That program contained 69 lines of JavaScript code, just to check a phone number. Fortunately, the program can be rewritten using regular expressions, as follows: var phonenum = "(415) 555-1212"; var pattern = /^(d{3}) d{3}-d{4}$/; document.write ("Trying to match "" + phonenum + "" with pattern " + pattern.toString() + "...<br><br>"); if (pattern.test (phonenum)) { document.write ("This is a valid phone number."); } else { document.write ("This is NOT a valid phone number."); } Running this JavaScript results in this output to the browser window.
  • 107. CHAPTER 3: Use Built-in JavaScript Classes 87 As you can see, substantial time and effort can be saved by using regular expressions to check a string against a pattern. We’ll look at the workings of this code in the next section. Understand the Basics of Regular Expressions Regular expressions in JavaScript deal with pattern matching. Other programming languages allow regular expressions to search and replace text, but JavaScript programmers do not have that 3 luxury. Despite this, regular expressions are still a powerful way to search for complex patterns. For instance, you can use them to ■ Validate telephone numbers in more than one format ■ Extract all the numbers from a string ■ Ensure a date is entered in the valid format ■ Verify an e-mail address has the proper format As we saw in the preceding code example, the regular expression pattern is quite complex and can be a little bit intimidating. var pattern = /^(d{3}) d{3}-d{4}$/; As I mentioned, regular expressions have their own language. There are many, many symbols and special characters to represent different things. The following are some general rules: 1. We start with defining a variable for our regular expression pattern. var pattern; 2. The forward slash (/) signifies the start and end of a regular expression literal in JavaScript. Regular expression literals allow us to create a regular expression object without having to use the RegExp class. var pattern = //; 3. The caret (^) and dollar sign ($) represent the start and end of a line. They also represent the start and end of a string. If we only wanted to match the pattern to part of the string, we would omit them. Similarly, if we wanted to test specifically for a pattern at the beginning of a long string, we could just use the caret (^) by itself. The following pattern only matches an empty string (“”) so far. var pattern = /^$/; 4. The d represents a single digit. If we add the d to our pattern, it would only match a one-character string containing a number from 0 to 9. var pattern = /^d$/;
  • 108. 88 How to Do Everything with JavaScript 5. If we want to match more than one number (as we do with a phone number), we can put multiple d tokens together; ddd would represent three numbers. We can also specify the number in curly braces: d{3}. var pattern = /^d{3}$/; 6. Other characters in the pattern, such as spaces and hyphens, represent only themselves. So the following pattern would match 999-999-9999, which is one way to represent a telephone number. var pattern = /^d{3}-d{3}-d{4}$/; 7. Since the parentheses characters have special meaning in regular expression syntax, to include them we will need to escape them with a backslash: ( and ). That gives us a pattern that matches (999) 999-9999, which is what we want. var pattern = /^(d{3}) d{3}-d{4}$/; There are many special tokens in the regular expression syntax to match different sets of characters. The tokens listed in Table 3-9 are the basic set. Character Meaning Either denotes the start of a special token (for example, d matches a digit) or indicates a special character is to be treated literally ( * matches an asterisk) ^ Matches the beginning of a line; also matches the beginning of every string $ Matches the end of a line; also matches the end of every string * A special quantifier, meaning the preceding token or group of tokens must match zero or more times + A special quantifier, meaning the preceding token or group of tokens must match one or more times ? A special quantifier, meaning the preceding token or group of tokens must match zero or one time only . Matches any single character except the newline character (n) (abcd) Matches “abcd” and remembers the match car|bus Matches either “car” or “bus” {3} Matches exactly three occurrences of the preceding token or group of tokens {3,} Matches three or more occurrences of the preceding token or group of tokens {4,8} Matches four to eight occurrences of the preceding token or group of tokens [abcdef] Matches any one of the characters a through f [a-f] Matches any one of the characters a through f [a-zA-Z0-9] Matches any single alphanumeric character TABLE 3-9 Regular Expression Syntax in JavaScript
  • 109. CHAPTER 3: Use Built-in JavaScript Classes 89 Character Meaning [^aeiou] Matches everything except a, e, i, o, and u d Matches a digit; identical to the pattern [0-9] D Matches a nondigit; identical to the pattern [^0-9] s Matches a space character (there are eight defined space characters) 3 S Matches a nonspace character t Matches a tab n Matches a new line r Matches a carriage return w Matches any alphanumeric (word) character (a–z and 0–9), including underscore ( _ ); identical to the pattern [a-zA-Z0-9_] W Matches any nonword character; identical to the pattern [^a-zA-Z0-9_ ] 0 Matches null TABLE 3-9 Regular Expression Syntax in JavaScript (continued) Create Patterns with a RegExp Object We’ve already seen how to create patterns with a regular expression literal. A regular expression literal starts and ends with a forward slash (/), as follows: var zipCodePattern = /^d{5}(-d{4})?$/; JavaScript also provides a class named RegExp to create these patterns as well. We can rewrite the pattern using this class’s constructor, as follows: var zipCodePattern = new RegExp ("^d{5}(-d{4})?$"); The backslash ( ) character needs to be escaped anytime it is included in a string, and the RegExp constructor is no exception. The double backslash ( ) represents the escaped backslash character. The RegExp object provides two main methods for performing its search and match functions: test() and exec(). Table 3-10 lists the most common methods of the RegExp object. Method Purpose compile () Compiles a regular expression exec () Searches a string for a pattern and returns all the matches test () Compares a string to a pattern and returns true or false based on the result TABLE 3-10 Methods of the RegExp Object
  • 110. 90 How to Do Everything with JavaScript Once a RegExp object has been created, JavaScript makes it very easy for you to test that pattern against any string. var myPattern = new RegExp ("hat.*hat"); document.write ("Pattern 1: "hat.*hat"<br>"); document.write (myPattern.test ("That is a nice hat.") + "<br>" ); document.write (myPattern.test ("I love your hat!") + "<br><br>" ); var myPattern2 = new RegExp ("w+sw+"); document.write ("Pattern 2: "w+sw+"<br>"); document.write (myPattern2.test ("Jackie Gleason") + "<br>" ); document.write (myPattern2.test ("Cher!") + "<br>" ); The results of this pattern checking can be seen in Figure 3-2. FIGURE 3-2 Creating and testing patterns using the RegExp object
  • 111. CHAPTER 3: Use Built-in JavaScript Classes 91 Understand JavaScript 2.0’s Powerful New Data Types Up until this point, we have been examining the classes supported by the vast majority of web browsers used today. JavaScript 2.0 introduced a number of new classes, which were listed earlier, in Table 3-3. The way objects are created and accessed remains virtually the same from previous versions of JavaScript, with the new and dot (.) operators doing most of the work. In this section, we will examine some of these new data types and learn how their powerful 3 functionality can be applied in JavaScript programs. The rest of the code in this chapter is designed to work in environments that support JavaScript 2.0 and will not work elsewhere. Use the Boolean, Integer, and Number Data Types There are three basic data types in JavaScript known as primitives: numbers, strings, and Boolean values. All other data types are built on these three basic building blocks. We already examined the String data type earlier in this chapter. The String object provides many methods to assist in manipulating strings, including searching (indexOf), extracting a portion of a string (substring), and determining the length of a string (length). The Boolean data type is very simple compared to String. You can use it to store a Boolean value (true or false), and you can retrieve that Boolean value. That’s pretty much it. There is really no reason to use the Boolean class in your programming, as the Boolean literals are easier to create and just as useful. var isFinished : Boolean = false; var paidToll : Boolean = true; The number primitive is actually represented by two JavaScript data types: Number and Integer. The only difference between the two is that an Integer data type cannot contain a decimal portion. Other than that, the two classes are identical. Again, for the most part I will continue to use numeric literals to create simple numbers, for the sake of convenience. var counter : Integer = 0; var invoice_amount : Number = 12363.22; Use the char Data Type Perhaps the one thing that distinguishes the char data type more than anything else is the odd way it was named. This data type does not capitalize its initial letter and its name is not a complete word. (In fact, the ECMA technical committee wanted to call it the “Character data type” at one point during the language’s development, which would have been more in line with how other classes were named.) The char data type represents only single 16-bit Unicode characters. Some languages call this a byte, and it is normally used when allocated memory space is a prime consideration. It exists
  • 112. 92 How to Do Everything with JavaScript for compatibility with other languages, and does not have much practical purpose in modern-day web programming. Use the Object Data Type Every class in JavaScript—both user-defined and system-defined—is a member of this data type. If you wanted to create a variable that could hold any object in the system, this would be the data type to use. var myObject : Object = new Date (); myObject = new String ("This is a string"); myObject = new Car (2002, "Ferrari", "Testarosa", "Cherry red"); The myObject variable, once defined as a member of the Object data type, can act as an object for any other class in the system. This ability, where one class can act as an object for another related class, is known in object-oriented programming as polymorphism. Inheritance and polymorphism are discussed in Chapter 5, when we create our own classes. Understand Special Data Types JavaScript 2.0 also contains some data types that you may not use in everyday programming— or may not ever use. As you learned in the previous chapter, functions can return a value. And in JavaScript 2.0, you can assign a data type to that value. function addTwo (num1 : Number, num2 : Number) : Number { return num1 + num2; } Use the Void Data Type Well, you may sometimes need to define a function that does not return any result. The following program does its task and exits without returning a value. function errorMessage (msg : String) { alert ("A serious error occurredn" + msg + "nPress OK to continue."); return; } Defining a function without any return value, as in this code, is certainly valid. But by doing so you have left the return value type ambiguous. Your function can either return a value or not, neither of which is an error. Leaving off the data type from the function only tells the system that the type of the return value is unknown. If you want to explicitly state that your function does not return a value, you can use the Void data type. A function defined as type Void is not allowed to return a value—it is an error condition if it does.
  • 113. CHAPTER 3: Use Built-in JavaScript Classes 93 function errorMessage (msg : String) : Void { alert ("A serious error occurredn" + msg + "nPress OK to continue."); return; } 3 Use the Never Data Type Or perhaps your function reports the error and then stops running completely. You can’t do this in a web browser environment, but you can in other environments, such as on the server. Functions that cause the program to exit should have the data type of Never, as in “This function will never return.” The following code example is written using JavaScript in an IIS web server environment. function errorMessage (msg : String) : Never { response.write ("A serious error occurredn" + msg + "nPress OK to continue."); response.end; } Use the Null Data Type Finally, the Null data type can only contain one valid value—null. I honestly cannot think of a reason why you would wish to do this. var useless : Null = null; Well, we have looked at every object and data type that JavaScript allows us to use—almost, that is. We haven’t talked about arrays yet. JavaScript 2.0 has introduced five new array classes. In the next chapter, we will examine arrays and see how they can be used to store tons of easily accessible data.
  • 114. This page intentionally left blank
  • 115. Organize Data Chapter 4 into Arrays
  • 116. 96 How to Do Everything with JavaScript How to... ■ Create an Array object ■ Set and retrieve values in an array ■ Use multidimensional arrays ■ Use JavaScript 2.0’s enhanced arrays In Chapter 2, we examined how our programs could use variables to store data for later retrieval. There is almost no limit to the number of variables a program can define. The number is limited only by the programmer’s ability to remember what each variable does. But you may sometimes be faced with the task of having to store dozens, or even hundreds, of related values into variable names for later use. For instance, how would you store the following? ■ The names of the 50 U.S. states ■ The names of the months of the year ■ The album titles of the CDs in your collection ■ The list of products in your store inventory You may be able to come up with ways to store the first two lists (state and month names) in JavaScript code, perhaps by assigning each name its own variable (for example, var Nebraska = "Nebraska"). But while this is possible, it’s not that practical. What’s the point of having variables (or even constants) whose value won’t ever change and whose value matches the variable name? So then, how could you store those types of lists (album titles and products in inventory)? After all, these lists could get quite large (your store could carry hundreds of products), the values can (and do) change, and even the length of the list will be different over time. JavaScript provides Array objects to handle lists of data. Arrays can handle long lists of data whose values can be easily retrieved or modified. Arrays can also grow or shrink as required. for (counter = 0; counter < 50; counter ++) { document.write ("State #" + counter + ": " + statesArray[counter]); } In the code, the variable statesArray contains an array of the 50 U.S. state names. We can access this array using its index (which ranges in value from 0 to 49) using the square brackets ([]) operator. statesArray[counter]; Of course, the code neglects to show how the Array object was created. There are two ways to create Array objects: ■ The Array class ■ The Array literal
  • 117. CHAPTER 4: Organize Data into Arrays 97 Unfortunately, there is a little inconsistency between the official specifications and the way each of the major browser manufacturers has implemented arrays in JavaScript. In this chapter, we will examine how arrays are created and how to create code that works across all browsers. We will also take a look at some of the exciting improvements in arrays in JavaScript 2.0. Create an Array Object There are three ways to create an Array using the JavaScript Array class: 4 ■ new Array () ■ new Array (size) ■ new Array (element1, element2, ..., elementN) Create an Empty Array Passing no arguments to the constructor of the Array class creates an empty array, also called an array of zero length. (In JavaScript, the number of items inside an array is known as its length.) We can then populate the array manually, as follows. 1. We start by defining a variable to contain our array. var months; 2. We then create a new Array object using the new operator. var months = new Array(); 3. We manually assign a value to the first index of the array. Indexes start at value 0. var months = new Array(); months[0] = "January"; 4. Now our array has a length of 1. We can then populate the rest of the values for our array. var months = new Array(); months[0] = "January"; months[1] = "February"; months[2] = "March"; months[3] = "April"; months[4] = "May"; months[5] = "June"; months[6] = "July"; months[7] = "August"; months[8] = "September"; months[9] = "October"; months[10] = "November"; months[11] = "December";
  • 118. 98 How to Do Everything with JavaScript 5. We now have an array that can be accessed by the rest of our program using only its numerical index. var months = new Array(); months[0] = "January"; months[1] = "February"; months[2] = "March"; months[3] = "April"; months[4] = "May"; months[5] = "June"; months[6] = "July"; months[7] = "August"; months[8] = "September"; months[9] = "October"; months[10] = "November"; months[11] = "December"; for (var i = 0; i < 12; i++) { document.write (months[i] + "<br>"); } 6. As you can see here, JavaScript is able to store a list of related values (months of the year) into a single variable, and then easily access each of those values for later use.
  • 119. CHAPTER 4: Organize Data into Arrays 99 7. A list such as this (months of the year) is convenient if you want your program to convert a numerical month into its string equivalent. Luckily, the Date object’s getMonth() function returns the month in a range of 0 to 11, so we do not even have to adjust the value before using it. var today = new Date(); var monthnum = today.getMonth(); document.write ("Today is a lovely " + months[monthnum] + " day."); 4 Specify an Initial Array Length JavaScript allows you to specify an initial length for your array by passing a single integer as a parameter. var months = new Array(12); Setting the length of an array in advance like this provides few advantages in JavaScript 1.5, since arrays grow automatically. Perhaps the one benefit it does provide is to remind you how large an array you intended to define. The length of an array can also be set within the program by altering the length property of the Array object. var months = new Array(); months.length = 12;
  • 120. 100 How to Do Everything with JavaScript Create and Initialize an Array in One Line of Code Looking at the months array defined earlier, we ended up writing 13 lines of code just to create and initialize the array. It would be nice if we could create this same array using only one line of code. Of course, I wouldn’t have mentioned it if JavaScript couldn’t do it... var months = new Array ("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"); The constructor of the Array class also accepts a comma-separated list of the initial values of the array. The first item listed is assigned the index 0, the next item becomes index 1, and so on. This is especially helpful for long lists of items. For instance, if we needed an array containing the 50 U.S. states, it would be much easier to create it in one line of code, as opposed to 51 or more. var USStates = new Array ("Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"); Use Array Literals Just as JavaScript provides ways to create numbers, strings, and regular expressions without having to manually create an object, you can do the same thing with arrays. var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; Break Long Lines of Code into Several Lines To make long lines of code more readable (to yourself and other programmers looking at your code), it is a wise idea to include a carriage return before the text scrolls off the right side of the screen. JavaScript supports code written over several lines, as long they are placed in the proper places. JavaScript will ignore extra spaces and new line characters, as it considers the semicolon (;) the actual end of the statement.
  • 121. CHAPTER 4: Organize Data into Arrays 101 The square brackets in the preceding code cause JavaScript to interpret their contents as the contents of a new array. It is equivalent to creating an array using the proper constructor syntax. var months = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"); All the properties and methods of the Array object are available to objects created using the Array literal. 4 Call the Properties and Methods of the Array Object The Array object in JavaScript exposes only three properties. Two of those properties are only set when the array being called is the result of a regular expression pattern match, as discussed in Chapter 3. The length property (which is available to all arrays) is the only one of the three that can be modified, as it indicates the current length of the array. Property Description index Related to regular expression pattern matching; contains the index of the matching substring (read-only) input Related to regular expression pattern matching; contains the original string against which the match was made (read-only) length Retrieves or sets the length of the array Not every element in an array has to contain a value. You could just as easily create an array that skips every second index number, or skips an arbitrary number of index numbers. The length property takes into account the number of empty (unused) indexes in an array as well as the number of elements an array contains. So if you skip a large amount of index numbers, the length property will be much larger than the number of elements. var employee = new Array(); employee[127756] = "Tom Jones"; alert(employee.length); This code returns 127,757 as the length of the array, since that is the number of elements (including empty ones) from 0 through 127,756.
  • 122. 102 How to Do Everything with JavaScript The Array object also contains a number of helpful methods to make managing the contents of the array easier for the programmer, as we can see in Table 4-1. Using the methods of the Array object listing in Table 4-1 provides several advanced modification functions on the contents of arrays. Four of the methods allow us to treat arrays like either a call stack or a queue. In programming, a call stack is similar to a stack of pancakes. The last pancake added to the top of stack has to be the first pancake taken off (or eaten). This arrangement is sometimes called the last in, first out (LIFO) method. A queue is much like a line at a bank, where the first person to enter the line is the first person served. Not surprisingly, this arrangement is sometimes called the first in, first out (FIFO) method. Method Description pop() and push() Last in, first out (LIFO); similar to a call stack shift() and unshift() First in, first out (FIFO); similar to a queue There are several other interesting methods that allow you to convert an array into a single string, split arrays into subarrays, or even concatenate two or more arrays together. In the following code, we create a number of arrays using the Array class. var MainMenu = new Array("File", "Edit", "View", "Window", "Help"); var FileMenu = new Array("New", "Open", "Close", "Save", "Exit"); var EditMenu = new Array("Undo", "Repeat", "Cut", "Copy", "Paste"); var ViewMenu = new Array("Normal", "Web Layout", "Outline"); var WindowMenu = new Array("New Window", "Arrange All", "Split"); var HelpMenu = new Array("Contents", "About", "Contact Us"); Method Description concat (array1, array2...arrayN) Joins two or more arrays into a single array join (separator) Joins all the elements of an array into a single string, separated by the separator indicated or a comma if none is specified pop () Returns the last element of an array and removes it push (element1, element2...elementN) Adds one or more elements to the end of an array and returns its new length reverse () Reverses the order of the elements in an array shift () Similar to pop (); returns the first element of an array and removes it TABLE 4-1 Methods of the Array Object
  • 123. CHAPTER 4: Organize Data into Arrays 103 Method Description slice (begin, end) Creates a new array from a subsection of the existing array, as defined by the start and end indexes splice (index, howMany, element1, Used to add or remove elements from an array element2...elementN) sort (functionName) Used to sort the elements of an array unshift (element1, element2...elementN) Similar to push (); adds one or more elements to the beginning of an array and returns its new length 4 TABLE 4-1 Methods of the Array Object (continued) These arrays represent a menu of a hypothetical web site. We can use some of the methods of the Array object on each of these arrays to modify it or extract bits of information. //Creates a string of all elements of an array // The array itself is unaffected var MenuItemsStr = MainMenu.join(" | "); document.write (MenuItemsStr + "<br><br>"); // Creates a new array that contains all elements of all arrays // The existing arrays are all unaffected var AllMenuItems = MainMenu.concat(FileMenu, EditMenu, ViewMenu, WindowMenu, HelpMenu); document.write (AllMenuItems.join(", ") + "<br><br>"); // Reverses the order of elements in an array // Modifies the existing array MainMenu.reverse(); document.write (MainMenu.join(" | ") + "<br><br>"); // Creates a new array that contains a subset of an existing array // The existing arrays are all unaffected var ChildMenuItems = AllMenuItems.slice(MainMenu.length); document.write (ChildMenuItems.join(" <font size=+3>||</font> ") + "<br><br>");
  • 124. 104 How to Do Everything with JavaScript The results from these array manipulations can be seen in the following screenshot. Set and Retrieve Values in an Array Elements inside the JavaScript Array object are accessed using the square brackets operator. var myArray = new Array(); myArray[16] = "Some value"; document.write (myArray[16]); The number inside the square brackets is called the index. You can think of an array as a series of parking spaces, numbered from 0 up to infinity. When the valet parks your car in one of those spaces, he has to keep note of the spot number in order to be able to find your car again. JavaScript arrays support using strings as indexes. When a string is used as an index, this is called a hash table. var FruitColors = new Array(); FruitColors["Apple"] = "red"; FruitColors["Banana"] = "yellow"; FruitColors["Grape"] = "purple";
  • 125. CHAPTER 4: Organize Data into Arrays 105 Here, the string "Apple" is being used as the index to store the value "red". The string "Apple" can be referred to as the key. Values stored in hash tables can be retrieved using the key, just as they can with numerically indexed arrays. document.write ("Apples are " + FruitColors["Apple"] + ".<br>"); document.write ("Bananas are " + FruitColors["Banana"] + ".<br>"); document.write ("Grapes are " + FruitColors["Grape"] + ".<br>"); As we saw in Chapter 2, arrays can also be accessed using the for-in statement. The for-in statement will loop through each of the elements in an array, returning the indexes or keys. 4 var FruitColors = new Array(); FruitColors["Apple"] = "red"; FruitColors["Banana"] = "yellow"; FruitColors["Grape"] = "purple"; for (var fruit in FruitColors) { document.write (fruit + "s are " + FruitColors[fruit] + ".<br>"); } Here, the for-in loop iterates over the document.write() function three times, once for each of the items in the array. The resulting output can be seen in Figure 4-1. FIGURE 4-1 The for-in loop iterates over a hash table.
  • 126. 106 How to Do Everything with JavaScript The same technique can be used for arrays with numerical indexes: var Players = new Array(); Players[0] = "Jaime"; Players[1] = "Mom"; Players[2] = "Bart"; Players[3] = "Liez'l"; // Who do we have playing bridge? for (var name in Players) { document.write (name + ": "); document.write (Players[name] + " is playing bridge.<br>"); } As you can see from the output in Figure 4-2, the for-in loop was able to iterate over each of our bridge players as well. FIGURE 4-2 The for-in loop iterates over an array.
  • 127. CHAPTER 4: Organize Data into Arrays 107 Use Multidimensional Arrays The arrays that we have seen thus far in this chapter are sometimes called one-dimensional arrays. If you think of an array as a graphical table containing rows and columns, these one-dimensional arrays would only have one column, as shown in Figure 4-3. A two-dimensional array is an array that would contain more than one column when displayed as a graphical table. Two-dimensional arrays are used when you need to store more than one value for each item in your list. Figure 4-4 shows a graphical representation of a two-dimensional array. A three-dimensional array would look more like a cube, as an element of depth is added to 4 the graph. Believe it or not, there are such things as four-dimensional arrays and higher. We live in a three-dimensional world, though, and it gets increasingly difficult to graphically display these complex sets of data. Some programming languages allow the definition of multidimensional arrays as a core feature of the language. Unfortunately, JavaScript is not one of them. If you want to define a multidimensional array in your JavaScript application, you will have to work within the limitations of the one-dimensional array. There are two techniques you can use to simulate a multidimensional array in JavaScript: ■ You can create parallel one-dimensional arrays. ■ You can create arrays of arrays. FIGURE 4-3 A graphical representation of a simple (one-dimensional) array
  • 128. 108 How to Do Everything with JavaScript FIGURE 4-4 A two-dimensional array contains multiple columns. One of the first arrays we looked at in this chapter was a listing of the months of the year. Let’s continue with that example. We started with the following one-dimensional array: var months = new Array ("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"); Let’s say we wanted to make a list of the following four items: ■ The months of the year ■ The birthstone related to each month ■ The color of each birthstone ■ The meaning associated with each birthstone Right now our array only contains months; if we were to arbitrarily add the three other things we wish to list, it would only add confusion to the array and make it harder to use. var months = new Array ("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "Garnet", "Amethyst", "Bloodstone or Aquamarine", "Diamond", "Emerald", "Pearl, Moonstone, or Alexandrite", "Ruby", "Sardonyx or Peridot", "Sapphire", "Opal or Tourmaline", "Topaz", "Turquoise or Lapis lazuli", "Red", "Purple", "Green/Red or Blue", "White/Clear", "Green", "Cream", "Red", "Light Green",
  • 129. CHAPTER 4: Organize Data into Arrays 109 "Blue", "Many Colors", "Orange/Brown", "Blue", "Constancy", "Sincerity", "Courage", "Innocence", "Love and success", "Health and longevity", "Contentment", "Married happiness", "Clear thinking", "Hope", "Fidelity", "Prosperity"); As you can see from this code, simply adding the extra lists to the existing array is not the best solution. Not only is it difficult for humans to read and understand, the programmer will also have to be careful when creating the program so that things don’t get mixed up. 4 We can rewrite that messy array using four parallel arrays, as follows. var months = new Array ("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"); var stones = new Array ("Garnet", "Amethyst", "Bloodstone or Aquamarine", "Diamond", "Emerald", "Pearl, Moonstone, or Alexandrite", "Ruby", "Sardonyx or Peridot", "Sapphire", "Opal or Tourmaline", "Topaz", "Turquoise or Lapis lazuli"); var colors = new Array ("Red", "Purple", "Green/Red or Blue", "White/Clear", "Green", "Cream", "Red", "Light Green", "Blue", "Many Colors", "Orange/Brown", "Blue"); var meaning = new Array ("Constancy", "Sincerity", "Courage", "Innocence", "Love and success", "Health and longevity", "Contentment", "Married happiness", "Clear thinking", "Hope", "Fidelity", "Prosperity"); The elements in each of the arrays match exactly to the same indexes in the other arrays, so let’s say I want to find out something about the seventh month of the year. (Remember that the arrays start at index 0, so the seventh month of the year is described at element number 6.) document.write ("The seventh month is <b>" + months[6]); document.write ("</b>. Its birthstone is <b>"); document.write (stones[6] + "</b>. The " + stones[6]); document.write (" is a <b>" + colors[6] + "</b> colored stone, "); document.write ("and it means <b>" + meaning[6] + "</b>"); document.write (" traditionally.<br>"); In this manner, we are able to store several columns of information about each month, by defining them in their own arrays. We can see the results of this code in our web browser screenshot in Figure 4-5.
  • 130. 110 How to Do Everything with JavaScript FIGURE 4-5 The use of parallel arrays can simulate two-dimensional arrays. The other method of creating a multidimensional array is to create an array that contains other arrays—an array of arrays, as this is called. To create an array of arrays, you would go through the following steps. 1. First, define the four arrays, just as you would if you were defining parallel arrays. var months = new Array ("January", "February", ...); var stones = new Array ("Garnet", " Amethyst", ...); var colors = new Array ("Red", "Purple", ...); var meanings = new Array ("Constancy", "Sincerity", ...); 2. Next, define a master array that will hold all four arrays. var marray = new Array(); 3. Then, assign each of the four arrays that contain the data to this master array. var marray = new Array(); marray[0] = months;
  • 131. CHAPTER 4: Organize Data into Arrays 111 marray[1] = stones; marray[2] = colors; marray[3] = meanings; 4. You should then modify your program to access the subarrays using the name of the master array with the appropriate index to the array. var marray = new Array(); marray[0] = months; 4 marray[1] = stones; marray[2] = colors; marray[3] = meanings; document.write ("The fourth month is <b>" + marray[0][3]); document.write ("</b>. Its birthstone is <b>"); document.write (marray[1][3] + "</b>. The " + marray[1][3]); document.write (" is a <b>" + marray[2][3] + "</b> " + "colored stone, "); document.write ("and it means <b>" + marray[3][3] + "</b>"); document.write (" traditionally.<br>"); As you see, instead of referring to the array as months[3], we must now refer to it using the name and index of the master array, as in marray[0][3]. As you can see in Figure 4-6, this technique is also a valid way to create two-dimensional arrays. Use JavaScript 2.0’s Enhanced Arrays JavaScript 2.0 has added three distinct subclasses to the traditional Array class. Each subclass is very similar to the way arrays have always worked in JavaScript, with some unique differences. Table 4-2 lists the traditional Array class and the three new classes, and describes the different classes. Array Object Name Description Array [datatype] This (the original Array class) is an abstract class. When called, it returns a DynamicArray object. If no data type is specified, it defaults to type Object. StaticArray [datatype] This new subclass does not automatically grow when new elements are added. It cannot contain empty elements and cannot be called without a data type. DynamicArray [datatype] This new subclass is the traditional JavaScript Array object. It cannot be called without a data type. ConstArray [datatype] This new subclass creates an array of constants whose value cannot be changed once set. It cannot contain empty elements. If no data type is specified, it defaults to type Object. TABLE 4-2 Array Classes in JavaScript 2.0
  • 132. 112 How to Do Everything with JavaScript FIGURE 4-6 The array of arrays technique closely simulates true two-dimensional arrays. Each of the Array types is usually instantiated with a data type. Both Array and ConstArray provide defaults for the data type, while the others do not. The data type provided when defining an array restricts the contents of the array to objects of that data type only. In this section, we will examine each of the three new array types and see how they can be used in JavaScript programs. The StaticArray Class The StaticArray class creates arrays of predetermined length whose values can be modified at any time. There are two ways to create a new StaticArray: ■ new StaticArray [datatype] () ■ new StaticArray [datatype] (size) The JavaScript 2.0 specification says that StaticArrays must be defined with a data type. To create an array that can accept any data type, we can define the array to accept values of type
  • 133. CHAPTER 4: Organize Data into Arrays 113 Object. Since Object is the parent data type of all classes in JavaScript, including those that you create yourself, Object arrays can accept any value. Creating a StaticArray without passing in a data type results in an array that can contain any object. Recall from the last chapter that Object is the data type of every class in the system, including those that you define yourself. var myArray : StaticArray = new StaticArray[Object](); myArray.length = 4; myArray[0] = "This is the first element"; 4 myArray[1] = 3.141; myArray[2] = new Car(2001, "Toyota", "4Runner", "Thundercloud"); myArray[3] = new Date(); This code creates a new StaticArray variable of type Object. We take advantage of this by storing a string, a number, a user-defined Car object, and a Date object into this array. Since the StaticArray has to have a predefined length, we started by initializing the length property of the array to the value 4, the number of items we intended to store. Attempting to add an additional item would cause a JavaScript error, unless we manually increased the value of the length. var myArray : StaticArray = new StaticArray[Object](); myArray.length = 5; myArray[0] = "This is the first element"; myArray[1] = 3.141; myArray[2] = new Car(2001, "Toyota", "4Runner", "Thundercloud"); myArray[3] = new Date(); myArray[4] = "This is a new element."; Providing a more specific data type, such as Number, would restrict the elements of the array to only that type. var mySecondArray : StaticArray = new StaticArray[Number](6); mySecondArray[0] = 14.2; mySecondArray[1] = 13; mySecondArray[2] = 21.9999; mySecondArray[3] = 2141330119; mySecondArray[4] = 0.0000003; mySecondArray[5] = 1.0121E26; Arrays of type StaticArray cannot have missing elements; that is, you cannot skip index numbers as you can with DynamicArrays. Attempting to add a string to a StaticArray that accepts only numbers will cause a JavaScript error. mySecondArray[5] = "This is not allowed.";
  • 134. 114 How to Do Everything with JavaScript The DynamicArray Class A DynamicArray is similar to a StaticArray, except that the size of the array will adjust itself automatically based on the elements you try to add to it. There are two ways to create a DynamicArray: ■ new DynamicArray [datatype] () ■ new DynamicArray [datatype] (size) This means that you can create an empty array and add elements to it without regard for the existing array length. var Nieces : DynamicArray = new DynamicArray[String](); Nieces[0] = "Sofia"; Nieces[1] = "Monica"; Nieces[2] = "Tiffany"; Nieces[3] = "Liz"; Nieces[4] = "Elke"; Nieces[5] = "Christine"; Nieces[6] = "Leah"; This DynamicArray, Nieces, can continue to grow to almost an unlimited size, limited only by the amount of computer memory. Another difference between DynamicArrays and the other types of arrays is that you are not obligated to fill every element. The following is valid code using DynamicArrays: var emps : DynamicArray = new DynamicArray[String](); emps[9931] = "John H. Smith"; Even though we have not provided values for indexes 0 through 9930, we can skip ahead to 9931 and provide a value for that element of the array. The ConstArray Class The third new array type supported by JavaScript 2.0 is ConstArray. ConstArrays are very similar to DynamicArrays, with three notable differences: ■ They can be defined without specifying a data type. ■ Their value cannot be changed once set. ■ They do not support skipped elements. There are four ways to create a new ConstArray: ■ new ConstArray () ■ new ConstArray (size)
  • 135. CHAPTER 4: Organize Data into Arrays 115 ■ new ConstArray [datatype] () ■ new ConstArray [datatype] (size) The ConstArray class takes its cue from the JavaScript constant variable type. (We looked at constants in Chapter 2.) Once set, the value of a constant cannot be changed. var months : ConstArray = new ConstArray[String](12); months[0] = "January"; months[1] = "February"; 4 months[2] = "March"; months[3] = "April"; months[4] = "May"; months[5] = "June"; months[6] = "July"; months[7] = "August"; months[8] = "September"; months[9] = "October"; months[10] = "November"; months[11] = "December"; Since the names of the months of the year are not likely to change during the execution of our program, we can define them as constants. We are then free to access those strings later in our program using the same square brackets syntax described earlier in the chapter. The last two chapters have focused on the built-in classes provided by JavaScript, and in particular the new classes and data types provided by JavaScript 2.0. The next chapter is all about creating your own classes, in both JavaScript 1.5 and 2.0.
  • 136. This page intentionally left blank
  • 137. Create Your Own Chapter 5 JavaScript Classes
  • 138. 118 How to Do Everything with JavaScript How to... ■ Create objects in JavaScript 1.x ■ Use an object literal ■ Create objects in JavaScript 2.0 ■ Organize classes using inheritance The last couple of chapters discussed how JavaScript’s built-in classes could be used to store many types of data (Dates, Numbers, Booleans, etc.). JavaScript also provides a way for you to create your own classes, so that you can design your own data types. In this chapter, we will examine the methods a JavaScript program can use to define objects for its own use. We will also examine the difference between objects created in JavaScript 1.x and those created in JavaScript 2.0. Learn about Classes in JavaScript In some ways JavaScript is an object-oriented programming language, and in some ways it is not. JavaScript has always had the ability to create and use objects. And in fact it is practically impossible to design a JavaScript program that does not, in some way, use the Document Object Model or any of the object-based data types JavaScript provides. But JavaScript programs are not normally designed around the object-oriented programming model, as Java and C++ programs are. JavaScript does not mandate the use of classes, which would force programmers to use the object-oriented programming model discussed in Chapter 3. JavaScript programmers are free to write unstructured or procedural programs to fit the task at hand. Nonetheless, support for user-defined classes and objects is one aspect of the language that will gain in acceptance over the coming months and years. Support for classes in JavaScript 1.x is limited, but it does exist. Class support in JavaScript 2.0 has been vastly improved. We will see the use of classes grow as programmers begin to discover the benefits of organizing their code into stand-alone, reusable objects. Create Objects in JavaScript 1.x There are four ways to create your own objects in JavaScript 1.x: ■ Call a constructor function ■ Use an object literal ■ Extend an existing class ■ Extend an existing object In the following sections, we will examine each of these methods.
  • 139. CHAPTER 5: Create Your Own JavaScript Classes 119 Call a Constructor Function One way to create an object in JavaScript is to create a special function called an object constructor. It is the job of this constructor to initialize the object for use—essentially to perform all the necessary setup tasks. The constructor function starts off looking just like a regular function, but uses a special object—the this object—to add properties to itself. To create a constructor, follow these steps: 1. Define an empty function, with the name of the class you wish to create. function Car () { } 5 2. The special this object is what a class uses to refer to itself. We can use the this object to add a new property inside the constructor function. function Car () { this.Make = "Toyota"; } 3. Since we want the constructor to be flexible and support many different types of Car objects, it would be better to define any properties using parameters of the function. function Car (make) { this.Make = make; } 4. We can then add many more properties to make our Car object complete. function Car (make, model, year, color) { this.Make = make; this.Model = model; this.Year = year; this.Color = color; } 5. Of course, we can add a property that does not rely on any parameters. function Car (make, model, year, color) { this.Make = make; this.Model = model; this.Year = year; this.Color = color; this.FullName = this.Year + " " + "<b>" + this.Make + "</b> " + this.Model; }
  • 140. 120 How to Do Everything with JavaScript 6. Now that we have defined a constructor for the Car class, our program can call it to create a Car object. function Car (make, model, year, color) { this.Make = make; this.Model = model; this.Year = year; this.Color = color; this.FullName = this.Year + " " + "<b>" + this.Make + "</b> " + this.Model; } var mySUV = new Car("Toyota", "4Runner SR5", 2001, "Thundercloud"); 7. With the mySUV object created, we can access any of the properties of the Car class. var mySUV = new Car("Toyota", "4Runner SR5", 2001, "Thundercloud"); document.write ("I drive a " + mySUV.FullName);
  • 141. CHAPTER 5: Create Your Own JavaScript Classes 121 8. In fact, we can create several objects from this one constructor, all with their own independent properties. Changing the value of one object’s property does not affect the value of the same property inside other objects. var mySUV = new Car("Toyota", "4Runner SR5", 2001, "Thundercloud"); var mySportsCar = new Car("Acura", "NSX-T", 1999, "Red"); var myDreamCar = new Car("Ferrari", "F355 F1", 2000, "Ferrari Red"); 5 mySportsCar.Color = "Black"; document.write (mySUV.FullName + " = " + mySUV.Color + "<br>"); document.write (mySportsCar.FullName + " = " + mySportsCar.Color + "<br>"); document.write (myDreamCar.FullName + " = " + myDreamCar.Color + "<br>"); This method of creating objects will work in JavaScript using all browsers dating back to Internet Explorer 3.0 and Netscape Navigator 3.0.
  • 142. 122 How to Do Everything with JavaScript Property names are case-sensitive in JavaScript. The property myCar.color is not the same as myCar.Color. Use an Object Literal The JavaScript object literal is a convenient way to create an object without having to predefine a constructor function. It is, in effect, an unnamed constructor. One of JavaScript’s greatest strengths is that it allows programmers to create programs quickly, and the object literal is a prime example of how it does this. The tradeoff to creating objects quickly using the object literal is that you lose out on the ability to reuse code for other objects or other programs. The object literal consists of a number of property-value pairs enclosed in a pair of curly brackets. Colons separate the properties and values, and commas separate the property-value pairs. { property1 : value , property2 : value , ... , propertyN : value } We can create the same mySUV object we created in the last section using an object literal as follows: var mySUV = {Make:"Toyota", Model:"4Runner SR5", Year:2001, Color:"Thundercloud"}; We will have to use a bit of a trick in order to define the FullName property using an object literal. Within the object literal itself, you cannot refer to any of the other properties. The following code shows how we are forced to define the FullName manually: var mySUV = {Make:"Toyota", Model:"4Runner SR5", Year:2001, Color:"Thundercloud", FullName:"2001 Toyota 4Runner SR5"}; When it comes to defining the other two objects from the last section (mySportsCar and myDreamCar), the only way to reuse the code from the mySUV object is to copy and paste, which most people would agree is not the best way to reuse code. var mySportsCar = {Make:"Acura", Model:"NSX-T", Year:1999, Color:"Red", FullName:"1999 Acura NSX-T"};
  • 143. CHAPTER 5: Create Your Own JavaScript Classes 123 var myDreamCar = {Make:"Ferrari", Model:"F355 F1", Year:2000, Color:"Ferrari Red", FullName:"2000 Ferrari F355 F1"}; As you can see, object literals are best used when you do not anticipate needing to create other objects of the same type. Extend an Existing Class JavaScript allows you to extend the capabilities of a class by assigning your own methods and 5 properties to it. This includes adding new methods and properties to any of the predefined system classes. It does this through a system called prototyping. JavaScript automatically gives each class a property called prototype that can be used to extend the functionality at the class level. ClassName.prototype.member1 = value1; A new member (member1) can be assigned a default value (value1) and added to the class specified (ClassName). This new member is static, in that its value is shared by all objects derived in that class. Changing the value inside one object changes it for all. Let’s start with an example. In the following code, we have defined a function that accepts a Date object as its parameter and will return a string that represents the name of the season ("Spring", "Summer", "Fall", or "Winter") that the date belongs to. function getSeason (obj) { var mon = obj.getMonth(); var day = obj.getDay(); if (mon < 2 || (mon == 2 && day < 20)) { return "Winter"; } else if (mon < 5 || (mon == 5 && day < 21)) { return "Spring"; } else if (mon < 8 || (mon == 8 && day < 23)) { return "Summer"; } else if (mon < 11 || (mon == 11 && day < 22)) { return "Fall"; } else { return "Winter"; } }
  • 144. 124 How to Do Everything with JavaScript Thus, we can call the preceding function using a Date object and get the correct season that the date falls into. var today = new Date(); document.write(getSeason(today)); You might think that it would be more convenient if the getSeason() function was a method of the Date object, instead of an external piece of code. To attach the getSeason() function to the Date class, we first need to modify it to work on the special this object, as all methods inside classes should. function getSeason () { var mon = this.getMonth(); var day = this.getDay(); if (mon < 2 || (mon == 2 && day < 20)) { // Covers Jan 1 through Mar 19 return "Winter"; } else if (mon < 5 || (mon == 5 && day < 21)) { // Covers Mar 20 through June 20 return "Spring"; } else if (mon < 8 || (mon == 8 && day < 23)) { // Covers June 21 through Sept 22 return "Summer"; } else if (mon < 11 || (mon == 11 && day < 22)) { // Covers Sept 23 through Dec 21 return "Fall"; } else { // Covers Dec 22 through Dec 31 return "Winter"; } } We must then attach the getSeason() function to the Date object as follows: Date.prototype.getSeason = getSeason; We can then call the getSeason() method right from any and all Date objects we create. var today = new Date(); document.write("The season is currently " + today.getSeason());
  • 145. CHAPTER 5: Create Your Own JavaScript Classes 125 5 Even though the getSeason() method is still not technically a member of the Date class, JavaScript is smart enough to check to see if it exists inside the list of prototype members, which is where we created it. Extend an Existing Object Just as a class can be extended using the prototype property, objects themselves can have new properties and methods attached to them. function Car (make, model, year, color) { this.Make = make; this.Model = model; this.Year = year; this.Color = color; this.FullName = this.Year + " " + "<b>" + this.Make + "</b> " + this.Model;
  • 146. 126 How to Do Everything with JavaScript } var mySUV = new Car("Toyota", "4Runner SR5", 2001, "Thundercloud"); mySUV.mileage = 12323; document.write(mySUV.FullName + " has traveled " + mySUV.mileage + " miles.<br><br>"); Even though the Car class does not define a property named mileage, we were able to create one for the mySUV object simply by assigning a value to it. Since we applied this property to the mySUV object and not the Car class, other objects derived from the Car class will not have a mileage property. Create Objects in JavaScript 2.0 JavaScript 2.0 has totally redesigned the way classes are defined. Although most JavaScript environments will still support the old way for the sake of backward compatibility, it is hard to compare the two techniques. Prototypes and manually added properties are no longer the preferred method for generating user-defined classes and objects in JavaScript.
  • 147. CHAPTER 5: Create Your Own JavaScript Classes 127 Define Your Own Classes In JavaScript 2.0, classes are defined using the following syntax: class className { statements; } As you can see, this syntax is quite simple. In practice, classes are quite easy and straightforward to define. We can take the Car class defined earlier in the chapter and define it using the JavaScript 2.0 syntax. 1. Define a class named Car using the class definition syntax. class Car { 5 } 2. Then define all the properties our Car class will possess. class Car { var Make; var Model; var Year; var Color; var FullName; } 3. Remember that JavaScript 2.0 supports data types for variables, so let’s make our definition more specific. class Car { var Make : String; var Model : String; var Year : Integer; var Color : String; var FullName : String; } 4. We will need to add a constructor function to the Car class to initialize these variables. The constructor usually has the same name as the class, although it is possible to define constructors with different names using a special syntax. The this object is still used to refer to the current object. class Car { var Make : String; var Model : String; var Year : Integer; var Color : String; var FullName : String;
  • 148. 128 How to Do Everything with JavaScript function Car (make, model, year, color) { this.Make = make; this.Model = model; this.Year = year; this.Color = color; this.FullName = this.Year + " " + "<b>" + this.Make + "</b> " + this.Model; } } 5. The Car class can be instantiated in the exact same manner as classes defined under JavaScript 1.x were, using the new keyword. var mySUV = new Car("Toyota", "4Runner SR5", 2001, "Thundercloud"); 6. With the mySUV object created, we can access any of the properties of the Car class. var mySUV = new Car("Toyota", "4Runner SR5", 2001, "Thundercloud"); document.write ("I drive a " + mySUV.FullName); It is easier to create methods using JavaScript 2.0 classes, as functions can be defined inside of the body of the class. class Book { var title : String; var author : String; var chapters : Array[String]; function print_title () { document.write ("Title: " + this.title + "<br>"); } function print_author () { document.write ("Author: " + this.author + "<br>"); } function print_all () { var counter = 0; print_title(); print_author(); for (chapter in this.chapters) { counter++; document.write ("Chapter " + counter + ": " + this.chapters[chapter] + "<br>"); }
  • 149. CHAPTER 5: Create Your Own JavaScript Classes 129 } } Once the Book class is defined, we can create a Book object using the new keyword. Since our class does not have a constructor, we can then manually set each of the properties. Calling a method of that new object results in the behavior we expect. var thisBook = new Book(); thisBook.title = "How To Do Everything with JavaScript"; thisBook.author = "Scott Duffy"; thisBook.chapters = new Array(15); thisBook.chapters[0] = "Prepare to Program in JavaScript"; 5 thisBook.chapters[1] = "Learn JavaScript Fundamentals"; thisBook.chapters[2] = "Use Built-In JavaScript Classes"; thisBook.chapters[3] = "Organize Data into Arrays"; thisBook.chapters[4] = "Create Your Own JavaScript Classes"; // etc. thisBook.print_all(); This results in the following browser output.
  • 150. 130 How to Do Everything with JavaScript Organize Classes Using Inheritance One of the benefits of organizing your program into classes is that you can establish relationships between classes using inheritance. Inheritance allows you to do two things: ■ Save programming time, because related classes can share code ■ Enforce a standard set of common properties and methods for related classes JavaScript 2.0 enables one class to inherit from another using the extends keyword. class ClassName extends ParentClass { statements; } This establishes a parent-child relationship between the ParentClass and the ClassName classes. The best way to understand inheritance is to think of the class structure like a hierarchical tree. At the top of the tree is the Object class, the parent of all classes in the system. All the classes in the system that do not have an explicit parent object derive from the Object class by default. Those that do have an explicit parent class defined, inherit from that class instead. Note: All classes in JavaScript 2.0 (both system and user-defined) have the Object class as either a direct or indirect ancestor, even those that extend from another class. We can define the parent class in the normal way. class Vehicle { var Maker; var Price; var Color; function Vehicle (maker, price, color) { this.Maker = maker; this.Price = price; this.Color = color; } function Vehicle () { this.Maker = "Default"; this.Price = 0.0; this.Color = "Transparent"; } } This code defines a Vehicle class, although there are only three properties. This class represents any generic vehicle, whether it is a boat, or a plane, or a car. That class should be able to handle any object that can be considered a vehicle.
  • 151. CHAPTER 5: Create Your Own JavaScript Classes 131 A class can contain multiple constructors, as long as the number and type of parameters (known as the function signature) are unique for each constructor. We can then be a bit more specific by defining classes that break down the type of vehicle. By extending the Vehicle class, our child classes automatically inherit the properties and methods of the Vehicle class. class LandVehicle extends Vehicle { // Land specific code var Speed; var xPosition; var yPosition; 5 } class WaterVehicle extends Vehicle { // Water specific code var Speed; var WaterDisplacement; var xPosition; var yPosition; var zPosition; } class AirVehicle extends Vehicle { // Air specific code var AirSpeed; var LandSpeed; var xPosition; var yPosition; var zPosition; } class SpaceVehicle extends Vehicle { // Space specific code var Thrust; var DistanceFromEarth; } We can continue to define classes that inherit from these child classes (LandVehicle, AirVehicle, WaterVehicle, and SpaceVehicle). The idea is that each child class is a more specific version of the parent class. So LandVehicle would have the following child classes: ■ Car ■ Train ■ Bus ■ Truck
  • 152. 132 How to Do Everything with JavaScript The Story of Interfaces The ECMA, the designers of the JavaScript 2.0 specification, originally planned to include an object-oriented programming concept called interfaces in the specification, but it was dropped at the last minute. Interfaces allow you to define a set of standard method names and parameter lists without having to provide code for them. A class could then declare, “I support the following interfaces...”; this would provide a reliable way to know what methods are supported by the class. Let’s say you define an interface named DoorLock, which contains two methods, Lock() and Unlock(). We know that the Car class implements the DoorLock interface, so we can be sure that a Car object has Lock() and Unlock() methods as well. Notice that a Car is not a type of DoorLock, so a parent-child relationship (one created by inheritance) should not be established. By defining a DoorLock interface, we have created a standard set of methods for classes that need to define door lock activity, such as the Car class and the House class. A Car is a more specific type of LandVehicle, which is a more specific type of Vehicle. If we wanted to further define Car, for instance, we could create SUV and SportsCar classes that inherit from it, and so on. There are obviously two major benefits to having classes inherit in such a manner. The first is the ability to reuse code. We defined a constructor all the way back in the Vehicle class. function Vehicle (maker, price, color) { this.Maker = maker; this.Price = price; this.Color = color; } Assuming none of the child classes defined a constructor for itself, all the descendants of the Vehicle class can use the original Vehicle constructor. class Vehicle { var Maker; var Price; var Color; function Vehicle (maker, price, color) { this.Maker = maker;
  • 153. CHAPTER 5: Create Your Own JavaScript Classes 133 this.Price = price; this.Color = color; } } class LandVehicle extends Vehicle { // Land specific code var Speed; var xPosition; var yPosition; } 5 class Car extends LandVehicle { // Car specific code var Model; var Year; } // Car inherits the Vehicle constructor var myCar : Car = new Car ("Ford", 19500, "Blue"); myCar.Model = "Focus"; myCar.Year = 2002; myCar.Speed = 32; // Car inherits the properties of Vehicle document.write ("Vehicle class properties: " + myCar.Maker + "<br>"); // Car inherits the properties of LandVehicle document.write ("LandVehicle class properties: " + myCar.Speed + "<br>"); // Car has its own properties as well document.write ("Car class properties: " + myCar.Model + "<br>"); As you can see from Figure 5-1, even though the Car class itself has only two properties, it does inherit all of the properties from its parents. Another benefit of using inheritance is what computer geeks like to call polymorphism. Essentially, a variable defined as the Vehicle data type can contain any of the objects derived from Vehicle (like LandVehicle or Car). This allows a program to act on an object without having to know or care what the exact type of the object is. If it can act on the parent object, the same actions can be performed on any of the child objects.
  • 154. 134 How to Do Everything with JavaScript FIGURE 5-1 Classes inherit the properties and methods of their parents. Perhaps the best demonstration of this would be with our own type of number, which we will call SuperNumber. class SuperNumber extends Number { override function toString() { return super.toString() + " !!!!"; } } The only difference between a regular Number class and a SuperNumber class is that the SuperNumber will return four exclamation marks appended to the end of the number when a user calls the toString() function. Once we have defined a SuperNumber, we can use it just like we would use a number. Any function that works on Numbers will be able to handle SuperNumbers, due to the inheritance relationship. Even the existing arithmetic operators will be able to handle these variables without modification. var x : SuperNumber = new SuperNumber(13); var y : SuperNumber = new SuperNumber(22);
  • 155. CHAPTER 5: Create Your Own JavaScript Classes 135 var z : Number = x + y; alert (z); We can see the result of the program here. 5 This illustration depicts the result we would expect to see when JavaScript 2–compatible browsers are eventually released. Choose Between Static and Instance Members We examined the concept of static class members when we discussed the built-in Math method in Chapter 3. Basically a static member is any property or method that is defined only in the class itself, and not in any of the objects derived from that class. You do not even have to have an object of a particular class defined in order to access its static members. Static members are defined using the static keyword. class Books { static const MAX_WIDTH = 8.5; static const MAX_HEIGHT = 11; static const MAX_WEIGHT = 10; var title; var author; var page_count; } In the Books class defined here, we have defined three static members. They happen to be defined as constants, but variables and even functions can be defined as static. In order to access them, we call them through the Books class, and not through any object created based on Books. alert (Books.MAX_HEIGHT);
  • 156. 136 How to Do Everything with JavaScript This illustration depicts the result we would expect to see when JavaScript 2–compatible browsers are eventually released. Instance members are any members that are not static. Instance members are accessed through objects that have been created, and they cannot be accessed using the class directly. var myBooks = new Books(); myBooks.title = "How To Do Everything With a Pencil"; myBooks.author = "Mary Major"; In this code, both title and author are instance members, and they can be accessed only by using an object (myBooks) based on the class Books, and not the class itself. Make Class Members Public or Private Another common task in object-oriented programming is to define members that cannot be accessed from outside the class. This is primarily used for security and data integrity. Members are made private using the private keyword, and made public using the public keyword. By default, members that are not explicitly defined as either are public. class Car { private var Make : String; private var Model : String; private var Year : Integer; private var Color : String; public function setMake (value) : Void { this.Make = value; } public function setModel (value) : Void { this.Model = value; } public function setYear (value) : Void { this.Year = value; } public function setColor (value) : Void { this.Color = value; } } In this code, all the properties of the Car class are defined as private. This means that they cannot be accessed from outside the class. Attempting to do the following will cause an error. var myCar = new Car(); myCar.Make = "Mercedes";
  • 157. CHAPTER 5: Create Your Own JavaScript Classes 137 To set the properties, we have to call the public methods we created for ourselves. The following code will work. var myCar = new Car(); myCar.setMake ("Mercedes"); Notice how we created a Car class that has made it impossible to read the values of the properties. In the real world, the class would also contain a number of functions to retrieve the values as well. Obviously, there is more to learn about classes in JavaScript, including getters and setters, packages, and namespaces. But these topics go beyond the scope of this chapter, and of this book. For more information on classes, consult the official JavaScript 2.0 specification on the 5 Mozilla web site, located at http://www.mozilla.org/js/language/js20/core/classes.html. In the next chapter, we will start to learn how to apply the concepts learned in the previous four chapters, as we use JavaScript inside web pages. We will learn about some of the key HTML tags and where JavaScript should be placed in the web page.
  • 158. This page intentionally left blank
  • 159. Build Part II JavaScript- Enabled Web Sites
  • 160. This page intentionally left blank
  • 161. Embed JavaScript Chapter 6 in a Web Page
  • 162. 142 How to Do Everything with JavaScript How to... ■ Understand basic HTML structure ■ Use <script> to add JavaScript to a web page ■ Use <noscript> for browsers that don’t support scripting ■ Load an external JavaScript file ■ Call JavaScript using hyperlinks Up until this point in the book, we have been concentrating on JavaScript’s programming syntax—the statements and definitions that are the nuts and bolts of the language. As you’ve seen, JavaScript has many features that make it an ideal language for many tasks, and one of its strongest features is its ability to integrate into a wide variety of other environments. Versions of JavaScript exist in many different environments: ■ An Application Server Pages (ASP) language for Microsoft IIS web servers (one of several supported languages) ■ Server-Side JavaScript (SSJS) for Netscape/iPlanet web servers ■ A server-side programming language for other web servers ■ An embedded language for Adobe Acrobat PDF documents ■ An embedded language for Macromedia Flash files (ActiveScript) But even today, almost 10 years after it was first introduced, JavaScript’s biggest success remains as an embedded programming language for web pages. It is supported by virtually every web browser in use today—it is installed on hundreds of millions of PCs worldwide. In this chapter, we will examine how to embed JavaScript in HTML pages and some basic text formatting techniques. Understand Basic HTML Structure Hypertext Markup Language, or HTML for short, is the language that web pages are written in. HTML is known as a markup language, because it uses a set of predefined tags, or markup, to provide formatting and other instructions to the web browser. For instance, the following example contains a number of HTML markup tags: <font size="2"><b>Now is the time</b> for all good men <u>to come to the aid</u> of <i>their party</i>.</font> As you can see, the HTML markup tags are always enclosed in angle brackets (< and >). Most HTML tags have both a starting tag (the bold text tag, <b>, for instance) and a closing tag (like </b>), although there are some exceptions to this rule.
  • 163. CHAPTER 6: Embed JavaScript in a Web Page 143 The following shows how an HTML document with the preceding markup would appear in a standard web browser. 6 Closing tags always start with a forward-slash character (/) followed by the name of the related start tag. For instance, if the start tag is <font>, the end tag must be called </font>. Entire books have been written on the subject of HTML. Actually, to be truly accurate, you could say enough books to fill more than a few bookshelves (or even bookcases) have been written on the topic. My goal, in this chapter and the ones that follow, is not really to teach the ins and outs of HTML. But since JavaScript programs rely so much on what’s happening inside the browser (frames, forms, browser events, etc.), it is impossible to understand what is going on with JavaScript without first understanding the HTML it relates to. For reference, Appendix A lists each of the HTML 4.01 tags and gives a brief description of their use. The major browser makers (Microsoft and Netscape) have in some cases added their own tags, so their lists might not match the official list in Appendix A.
  • 164. 144 How to Do Everything with JavaScript Why XML and XHTML Are the Coming Thing Although humans can easily read HTML documents using a web browser, computers themselves have a difficult time finding specific data to extract from a web page. For instance, it would be very difficult to create an application that can reliably download daily flight schedules from all the airline web sites. XML (Extensible Markup Language) is an ideal language for transmitting computer data over the Internet. Whereas HTML is an extremely flexible markup language, with very few mandatory elements or attributes, XML has a strict set of formatting rules. Programmers can impose additional rules on individual types of documents by creating an XML schema or DTD. XML is the new standard language for data formatting over the Internet, and it is the foundation of many of the Web Services initiatives, including Sun ONE and Microsoft .NET. A new version of HTML has been created that allows web documents to be valid XML as well, called XHTML. In fact, the World Wide Web Consortium (W3C) has stopped developing the HTML standard (version 4.01) and has been hard at work at XHTML standards— versions 1.0 and 1.1 have already been released. For more information on the XHTML standard, visit the W3C web site at http://www.w3c.org/markup. In addition, as mentioned in Chapter 1, a special set of tags denotes comments in HTML: <!-- indicates the start of commented text, and --> indicates the end. Comments serve as useful documentation or author notes, such as the following: <!-- Survey.html Purpose: To gather visitor opinions on this site Author: John Q. Doe --> <!-- Copyright 2003, Scott J. Duffy Incorporated All rights reserved. --> As you can see, comments can extend over several lines. All text that appears inside HTML comment markup is ignored by the browser and not displayed to the user in the main display. Don’t forget that the user can see the underlying HTML code in most browsers by selecting View | Source from the menu bar, so your comments won’t be entirely private.
  • 165. CHAPTER 6: Embed JavaScript in a Web Page 145 What “Officially Deprecated” Means The World Wide Web Consortium (W3C), the group that creates and maintains several important specifications dealing with the Internet including HTML, has indicated a number of HTML tags are deprecated. Indicating that a tag is deprecated is a polite way of saying support for it in the specification will likely be dropped in a future release. The W3C would like to encourage web developers to employ another method instead, such as using Cascading Style Sheets (CSS) for defining fonts. However, given the widespread use of such tags as <font>, <center>, and <u>, it is highly 6 unlikely that the major browser makers are going to drop support for them anytime soon. Build an HTML Document One of the strengths of HTML is simplicity: it is very easy to build a web page using just a few basic tags. There are three essential elements to building a web page: 1. Every HTML document must begin with the HTML start tag (<html>) and end with the HTML end tag (</html>). The only exception is for <!DOCTYPE> or <?xml?> declaration statements, which are then placed before the HTML tags. (The <?xml?> declaration is used to define documents that conform to XHTML, which is beyond the scope of this book. However, we will look at <!DOCTYPE> in the following section.) <html> </html> 2. The HTML document is then divided into two sections, a head and a body. The head section is where a document title, descriptive keywords, style sheets, and JavaScript functions are defined. <html> <head> <title>How to Do Everything with JavaScript</title> </head> </html> 3. The body section is where the contents of the document are placed. Often this will be plain text (sentences and paragraphs), marked up with some formatting HTML tags like <b>, <i>, and <p>. <html> <head>
  • 166. 146 How to Do Everything with JavaScript <title>How to Do Everything with JavaScript</title> </head> <body bgcolor="white"> <h1>A typical document header</h1> <p>The start of a paragraph.</p> <p><b>Our second paragraph.</b></p> </body> </html> Granted, the web page in our example is fairly simple, but even web pages with hundreds of lines of code start with three simple tags: <html>, <head>, and <body>. Get in the habit of creating all your HTML documents using lowercase tag names, properly nested tags, and properly quoted attribute values. It will pay off when you want to start creating XHTML 1.0 documents, because XHTML has very strict rules. You are probably already familiar with the basics of HTML. If not, since it’s not feasible to compress a tutorial on HTML into one chapter, I have included a list of useful web sites at the end of this chapter. Indicate the Document Type with <!DOCTYPE> There is only one way to indicate to a browser (or any other application reading your HTML file) which version of HTML your web page is written for: <!DOCTYPE>. Up until a few years ago, this tag was ignored entirely by web browsers. But recent versions of browsers look for this code to determine which set of rules to use in interpreting the web page. An HTML document that conforms to the HTML 4.01 specification would have the following <!DOCTYPE> as the very first line of the page, even before the <html> tag: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> If a browser encounters a web page that uses this <!DOCTYPE> tag, the browser will expect valid HTML 4.01 Transitional code in the rest of the document. Transitional HTML includes all the deprecated tags (such as <font>). There is also a version of HTML called Strict that does not include deprecated tags, and another called Frameset that allows browser frames to be created. (We will look at browser frames in Chapter 10.) If we wanted to use a different version of HTML, like XHTML (the XML compliant version of HTML), we would use a different <!DOCTYPE>, like so: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  • 167. CHAPTER 6: Embed JavaScript in a Web Page 147 When a browser encounters this <!DOCTYPE>, it knows to treat the contents as XHTML 1.0 Transitional. Depending on the browser, this may be slightly different from the way it treats HTML 4.01 code. Add a Title and Define Document Keywords The HTML head element contains information about the current document, such as its title, keywords, and other data that is not considered content. The HTML <title> tag is used to specify a title for the document, and it is mandatory in HTML 4.01. <html> <head> <title>This is the document title</title> </head> 6 <body></body> </html> The contents of the <title> tag are usually displayed in the title bar of the window, as you can see here: Optionally, you can specify a number of keywords, which will make it easier for Internet search engines to find your web site. Keywords and a brief description of the web page can be specified using the <meta> tag. For instance, if you had a page focused on exotic pets, you might have the following <meta> tags: <meta name="description" content="Articles, pictures, and stories about exotic pets"> <meta name="keywords" content="exotic pets, reptiles, amphibians, frog, toad, salamander, newt, siren, lizard, iguana, gecko, monitor, chameleon, dragons, turtles, tortoises, leopard, butterfly, butterflies, moth, bees, flies, stick insects, beetles, wasps, hornet, roaches, ants, cricket, grasshopper, tarantula, scorpion, centipede, millipede"> When used to specify web page descriptions and keywords, the <meta> tag takes two attributes: name and content. In the preceding code, the first <meta> tag sets the description
  • 168. 148 How to Do Everything with JavaScript for the web page—usually a sentence or two that is often displayed by Internet search engines to give potential visitors an accurate description of what to expect from this page. The second <meta> tag in the example defines a number of keywords—words or phrases separated by commas that give search engines help in indexing the page. Some Internet search engines rank web pages with these <meta> tags higher than they would the same page without the <meta> tags. Format Text with HTML Elements HTML provides a number of elements to help web page developers format and style text. These tags fall into two broad categories: phrase elements and font style elements. Phrase elements are tags that structure text. The way these elements are presented to the user depends on the browser. Font style elements are tags that specify specific font properties for text. Since font style properties are fairly specific, developers can be more confident about the way browsers will present text to the user. The following are the phrase elements in HTML 4.01: ■ <abbr> indicates an abbreviated form ■ <acronym> indicates an acronym ■ <cite> indicates a citation or reference to other sources ■ <code> designates a fragment of computer code ■ <dfn> indicates the defining instance of a term ■ <em> indicates emphasis; usually displayed as italic text ■ <kbd> indicates text to be entered by the user ■ <samp> indicates sample output from programs, scripts, and so forth ■ <strong> indicates stronger emphasis; usually displayed as bold text ■ <var> indicates an instance of a variable or program argument Again, each of these elements indicates the type of text it contains, but gives only a hint as to how the browser should handle them. The following tags are the font style elements of HTML 4.01: ■ <b> bold text ■ <big> larger than normal text ■ <i> italic text
  • 169. CHAPTER 6: Embed JavaScript in a Web Page 149 ■ <s> strikethrough text (officially deprecated) ■ <small> smaller than normal text ■ <strike> strikethrough text; same a <s> (officially deprecated) ■ <tt> teletype or monospace text ■ <u> underlined text (officially deprecated) In the vast majority of HTML pages, phrase elements are not used. Many web page designers prefer to set fonts and styles for their pages explicitly. On top of the uncertainty of how different browsers will render these tags, using such predefined document structure elements limits designers’ design choices. Hundreds of millions of web pages exist that use only HTML elements like the ones listed here to style the text on their pages. For example, the following HTML code creates a web page 6 that uses many of the style tags discussed so far in this chapter. <html> <head><title>Sample document</title></head> <body> <h1>Traveling to the Caribbean</h1> <p><b>Barbados</b> - Barbados is a lovely island, with <i>wonderful weather</i> and a <i>constant cool breeze</i>. The locals are friendly, and one can clearly see that a British influence still exists, even today.</p> <p><b>St. Lucia</b> - St. Lucia is a lush, tropical paradise. Fewer tourists tend to visit St. Lucia than some of the other islands, which means it is easier to explore the local way of life.</p> <p><b>Bahamas</b> - Bahamas is <strike>frequently visited by</strike> <u>a popular spot for</u> Americans. The islands have a number of casinos, the most spectacular of which is the <i>Atlantis Hotel on Paradise Island</i>. The rumor is that one of their hotel rooms goes for <big>$40,000 a night</big>, which is about $39,800 more than most people can afford to spend on a place to sleep.</p> </body> </html>
  • 170. 150 How to Do Everything with JavaScript As you can see from the following screen capture, HTML elements style text to make the output easier to read. Text that should be boldface, italic, or crossed out is presented exactly as one would expect. Format Text with Style Sheets For years, web designers have wanted a more precise way to style and lay out web pages, similar to the tools desktop publishing software has provided for a long time. Finally, along came style sheets, which have alleviated most of the designer’s concerns about styling web pages. The W3C homepage for Cascading Style Sheets is http://www.w3.org/Style/CSS. Not surprisingly, that page is itself a great example of how style sheets can be used to format a web page. Style sheets, also sometimes called Cascading Style Sheets (CSS for short), have a number of benefits for web developers. They provide ■ The ability to separate style from content ■ The ability to apply a single style to an entire web site ■ A more fine-grained ability to control style
  • 171. CHAPTER 6: Embed JavaScript in a Web Page 151 ■ The ability to specify exact layout positioning ■ The ability to script and dynamically change styles using JavaScript (also called Dynamic HTML) ■ The ability to specify different styles depending on browser environment (e.g., PC versus mobile phone) In fact, the HTML specification is slowly phasing out the use of the HTML tags listed in the last section to define style in favor of style sheets. Using style sheets to define a document’s style is the present and future of the language. A style sheet is defined inside the HTML <style> element, which is usually defined inside the document head section. <html> 6 <head> <title>HTML Style Sheets</title> <style type="text/css"> // Style sheet goes in here </style> </head> <body> <h1>Traveling to the Caribbean</h1> <p><b>Barbados</b> - Barbados is a lovely island, with <i>wonderful weather</i> and a <i>constant cool breeze</i>. The <!-- Etc. --> </body> </html> In the case of our HTML document, we can define a custom style sheet that replaces some of the formatting we were using. <style type="text/css"> .island {font-weight: bold} .highlight {font-style: italic} .underlinethis {text-decoration: underline} .bigmoney {font-size: larger} </style> In fact, you could add some really interesting text effects to our boring document, as shown in the following example. And once the style sheet has been defined, you simply alter the HTML to use those styles.
  • 172. 152 How to Do Everything with JavaScript <html> <head> <title>Sample document</title> <style type="text/css"> .island { color: white; background-color: black; font-weight: bold } .highlight { font-style: italic; background-color: yellow } .underlinethis { text-decoration: underline overline } .bigmoney { color: green; font-size: xx-large } </style> </head> <body> <h1>Traveling to the Caribbean</h1> <p><span class="island">Barbados</span> - Barbados is a lovely island, with <span class="highlight">wonderful weather</span> and a <span class="highlight">constant cool breeze</span>. The locals are friendly, and one can clearly see that a British influence still exists, even today.</p> <p><span class="island">St. Lucia</span> - St. Lucia is a lush, tropical paradise. Fewer tourists tend to visit St. Lucia than some of the other islands, which means it is easier to explore the local way of life.</p> <p><span class="island">Bahamas</span> - Bahamas is <strike>frequently visited by</strike> <span class="underlinethis">a popular spot for</span> Americans. The islands have a number of casinos, the most spectacular of which is the <span class="highlight">Atlantis Hotel on Paradise Island</span>. The rumor is that one of their hotel rooms goes for <span class="bigmoney">$40,000 a night</span>, which is about $39,800 more
  • 173. CHAPTER 6: Embed JavaScript in a Web Page 153 than most people can afford to spend on a place to sleep.</p> </body> </html> The resulting web page would not win any design awards, but you can see that style sheets allow you to do things regular HTML does not. 6 Clearly, style sheets involve much more than the small glimpse I have been able to give you in this short section. I have listed a few web sites you can visit to learn more about style sheets at the end of this chapter. We will also revisit this subject in Chapter 12. Use <script> to Add JavaScript to a Web Page Now that you have been introduced to some basic HTML formatting elements, it’s time to tie that in to the use of JavaScript. The HTML <script> tag allows web developers to embed JavaScript commands in their web pages. There is no restriction as to the number of <script> sections a web document can contain, although for the sake of programming efficiency it is best to keep the number of scripts on a single page to a minimum. The HTML <script> element generally accepts only two attributes when you are working with embedded script content: language and type. The language attribute exists for backward compatibility. JavaScript is the only scripting language supported by all major web browsers, so if this attribute is omitted, "JavaScript" is the default.
  • 174. 154 How to Do Everything with JavaScript The type attribute specifies the MIME type for the embedded script, which is "text/javascript" for our purposes. MIME is a standard way to describe the contents of a file over the Internet, such as "text/plain: and "image/gif ". This gets around the problem of three-letter filename extensions (.htm or .txt) left over from MS-DOS, 20 years ago. The MIME standard, which originated with e-mail systems, allows a web server to tell a browser how to interpret the stream of bits being sent. For instance, the only way for a web browser to know that the file http://www.example.com/ is an HTML document is through its MIME type. <script language="JavaScript" type="text/javascript"> var a = 1; var b = 2; var c = a + b; document.write (c); </script> Later in this chapter, we will look at another use for the <script> tag that deals with external JavaScript content. Use <noscript> for Browsers That Don’t Support Scripting Even today, with all the technical advances made in web browsers and web programming languages, not every browser supports JavaScript. For instance, many mobile phones provide Internet access, but they are severely limited in screen size, color, audio, and scripting capabilities. There are also web browsers for PCs (like the one embedded in Microsoft Word) that do not support advanced capabilities such as JavaScript. And some pre-JavaScript browsers are still in use, such as Netscape Navigator 1.0. It is true, however, that supporting non-JavaScript-compatible devices is less important now than in 1995, when JavaScript first came out. But as the variety of computer operating systems and hardware devices increases over time, it may again become important to provide alternate content for some users. The HTML <noscript> tag is used to provide content to users whose browsers do not support JavaScript. It works because JavaScript-enabled browsers ignore any content between the <noscript> tag, for instance: <html> <head> <title>JavaScript Test</title> </head> <body> <h1>for Loop</h1> <script language="JavaScript" type="text/javascript"> <!-- // Begin
  • 175. CHAPTER 6: Embed JavaScript in a Web Page 155 var Fahrenheit; for (var Celsius = 10; Celsius <= 60; Celsius = Celsius + 5) { document.write (Celsius + "&deg;C = "); Fahrenheit = (Celsius * 9/5) + 32; document.write (Fahrenheit + "&deg;F<BR>"); if (Fahrenheit > 100) { // It's getting hot in here break; } } // End --> </script> 6 <noscript> You must have a JavaScript-enabled browser to visit this web page. </noscript> </body> </html> This code will show users with JavaScript-enabled browsers the following output.
  • 176. 156 How to Do Everything with JavaScript However, users whose browsers do not support JavaScript will see this message instead. The only reason the JavaScript is not output to the screen as well is the HTML comment tags, <!-- and -->, that surround the script. Inside the <noscript> tag, you can choose to simply inform the user that a JavaScript-enabled browser is required. But you could also provide replacement content for the JavaScript, as in this example: <noscript> 10°C = 50°F <BR> 15°C = 59°F <BR> 20°C = 68°F <BR> 25°C = 77°F <BR> 30°C = 86°F <BR> 35°C = 95°F <BR> 40°C = 104°F <BR> </noscript> This would allow users with a wide variety of browsers and hardware devices to view your web site properly. Of course, it is not always possible to replace JavaScript content with plain HTML text.
  • 177. CHAPTER 6: Embed JavaScript in a Web Page 157 Load an External JavaScript File JavaScript does not always have to be embedded inside the HTML file. Often it is convenient to have one file that contains the JavaScript and have multiple HTML files import it for their use. Using this technique, it would be easier to make changes to the JavaScript, since you do not have to change each of the HTML files. First, you must have a text file that contains nothing but JavaScript. Let us assume the following file exists on the web server, and is named sample.js. // SAMPLE.JS // // isFloat() function: // Checks a string to see if it contains a // floating-point number; returns true or false 6 // function isFloat (s) { // Format accepts "9", "9.", "9.9", and ".9" var reFloat = /^((d+(.d*)?)|((d*.)?d+))$/; return reFloat.test(s) } The .js file extension is commonly used in Windows systems to indicate that the file contains JavaScript, although any extension (such as .txt) can be used. We use the src attribute of the HTML <script> tag to import the external JavaScript file. <html> <head> <title>JavaScript Test</title> <script language="javascript" src="sample.js"></script> </head> <body> <h1>Check for a Floating Point Number</h1> <script language="JavaScript" type="text/javascript"> document.write("Is "12.345" a float? " + isFloat("12.345") + "<br><br>"); document.write("Is "Twelve" a float? " + isFloat("Twelve") + "<br><br>"); </script> </body> </html>
  • 178. 158 How to Do Everything with JavaScript We can then call the isFloat() function defined in our external JavaScript file in another <script> section elsewhere in the web page. In this manner, the isFloat() function can easily be shared among multiple web pages. HTML <script> tags that import an external JavaScript file cannot also contain JavaScript. They must be empty. The result of importing an external JavaScript file is shown in Figure 6.1. Call JavaScript Using Hyperlinks Not all JavaScript executes immediately after a web page is loaded. We will examine web browser events, which allow JavaScript to run in response to user actions, in Chapter 9. Another way to invoke JavaScript in response to a user event is as the destination of a hyperlink. <A HREF="javascript:alert('Hello')">Click me</A> FIGURE 6-1 Functions defined in external JavaScript files can be called elsewhere in the HTML page.
  • 179. CHAPTER 6: Embed JavaScript in a Web Page 159 Loading this HTML into a web browser causes a clickable hyperlink to be displayed along with the caption “Click me.” When the user clicks the link, a JavaScript alert() message box pops up, saying “Hello.” The secret is the special "javascript:" prefix inside the HREF URL. This informs the browser that what we really intend to do is invoke a JavaScript command instead. Several JavaScript commands can be appended in one string, if separated with a semicolon. <A HREF="javascript:alert('Hello');alert('Goodbye')">Click me</A> More commonly, JavaScript hyperlinks are used to call predefined functions, instead of embedding one or more JavaScript statements inside the HREF attribute value itself. <A HREF="javascript:submitform()">Click here to submit the form</A> In this example, when the user clicks the hyperlink labeled “Click here to submit the form,” JavaScript will call a function named submitform(), which we assume is defined elsewhere on 6 the web page. In the next chapter, we will examine the issues web developers face when creating cross- platform-compatible JavaScript. JavaScript programs that work in one web browser will not necessarily work in another, as there are dozens of combinations of browsers, hardware platforms, and operating systems. Knowing how to work around these differences is important in real-world web development. Learn More about the Topics in this Chapter The following are a few web sites where you can learn more about HTML and Cascading Style Sheets: ■ Webmonkey HTML Basics: http://hotwired.lycos.com/webmonkey/teachingtool ■ SitePoint: http://www.webmasterbase.com ■ Web Design Group CSS Reference: http://www.htmlhelp.com/reference/css ■ Dave Raggett’s Introduction to CSS: http://www.w3.org/MarkUp/Guide/Style
  • 180. This page intentionally left blank
  • 181. Create Scripts Chapter 7 That Work in Every Browser
  • 182. 162 How to Do Everything with JavaScript How to... ■ Understand browser differences ■ Detect what type of browser the user is running ■ Query the document model ■ Stick to web standards ■ Write cross-browser code In the early days of JavaScript development, handling irregularities between the different browser makers and versions was a difficult task. After all, some browsers did not support JavaScript at all (like Netscape 1.0). Even if you had a browser that supported JavaScript, the underlying document model (DOM) was different between different browsers, which meant JavaScript errors were a common sight. This difficulty of developing JavaScript code that worked correctly in every browser was caused primarily by several factors: ■ New browser releases every few months ■ An ongoing contest between browser companies to add new features ■ Lack of an HTML or JavaScript standard It took some time, but eventually the problems started to go away as JavaScript stabilized. And as users began to gradually upgrade to version 4.0 browsers and beyond, JavaScript developers had an easier time developing cross-platform-compatible code. Unfortunately, some of the impending changes to JavaScript will force web developers to have to start coding for browser differences again. The reasons for this new period of instability are likely to include: ■ Inconsistent support for JavaScript 2.0 ■ New browser releases every few months (particularly from Mozilla) ■ Inconsistent JavaScript support for new technologies, such as XML and CSS Only time will tell how much heartache these factors will cause web developers. Understand Browser Differences According to a recent survey, Microsoft Internet Explorer (IE) is used by approximately 94 percent of web surfers. Netscape and Mozilla have a combined usage of approximately 2 percent. The remaining 4 percent is divided among other companies such as Opera or is lost due to rounding.
  • 183. CHAPTER 7: Create Scripts That Work in Every Browser 163 These numbers are likely to change over the coming months and years. The largest Internet service provider (ISP) in the United States recently announced it would start using Netscape as its default browser, and that could potentially have a large impact on these numbers. Looking at recent browser popularity statistics a little closer, as in Table 7-1, we can see that half of surfers have not yet upgraded to the most recent versions of their preferred web browsers. Fully 54 percent of all web surfers are using browsers that are not the latest release from either Microsoft or Netscape. So be careful when creating JavaScript programs that rely too much on proprietary or recently added features. Using those features without taking proper precautions can cause errors for a significant portion of your audience, even if the application works fine in the browser installed on your PC. What Kind of Errors Can Occur? When designing any computer program, it is important to keep in mind that errors are likely to occur despite the programmer’s best efforts to avoid them. This is especially true of JavaScript programs that are used across a wide variety of browsers and operating systems. When developing 7 JavaScript code, you are likely to find the following sources of errors: ■ Differences in the Document Object Model of each browser version ■ Client computers running old browsers (such as Netscape 3.0) that do not support certain JavaScript functionality ■ Client computers with certain technologies turned off, such as cookies or Java ■ New web-enabled technologies, such as hand-held devices, mobile phones, and even appliances, such as refrigerators In this chapter, we will take a look at some of the common techniques for avoiding these types of errors. Browser Usage IE 6 46% IE 5 44% IE 4 2% Netscape 4 2% Netscape 6, Netscape 7, Mozilla (collectively) 1% Older IE less than 1% Older Netscape less than 1% Source: TheCounter.com (http://www.thecounter.com) TABLE 7-1 Recent Web Browser Usage Statistics
  • 184. 164 How to Do Everything with JavaScript Detect What Type of Browser the User Is Running Running a modern or complex JavaScript program in an older browser is likely to cause numerous problems. Perhaps the easiest way to avoid these types of errors is to detect what type of browser the user is running and then either disable some of the program features or provide alternative code that performs the same task in a slightly different manner. Detecting the browser name and version information is often called browser sniffing. Much as a bloodhound can detect the unique scent of an individual, a browser sniffer attempts to detect and return the unique details of the browser software. To detect the browser manufacturer and version number, we will rely on the navigator DOM object. The navigator object has several methods and properties, but the three that we are interested in at the present time are appName, appVersion, and userAgent. var browserString = navigator.appName; var browserVersion = navigator.appVersion; var browserAgent = navigator.userAgent; alert (browserString); alert (browserVersion); alert (browserAgent); Specifying JavaScript Version Numbers The browser makers started off with the best of intentions. Both Netscape and IE allow developers to specify a JavaScript version number within the language attribute of the <script> tag. This prevents scripts from running in browsers that do not support the specified JavaScript version number. To create a script that will only run in browsers that support JavaScript 1.2, you would use the following code: <script language="JavaScript1.2"> The same can be done for all versions of JavaScript up to version 1.5. (A listing of JavaScript version numbers and how they relate to browsers can be found in Chapter 1.) Unfortunately, very few web developers knew that this could be done, and fewer still actually used this technique when creating cross-browser scripts. On top of that, this method does not help developers solve the DOM-related differences between the various browsers. So, although this technique is still available, it cannot be relied on to solve cross-browser scripting problems.
  • 185. CHAPTER 7: Create Scripts That Work in Every Browser 165 For Netscape web browsers (including the open-source Mozilla web browser), the navigator.appName property always returns the same value regardless of the version or operating system. For Microsoft Internet Explorer, the navigator.appName property also returns a predictable value, regardless of the version. 7 Therefore, if your web page needed to display different text depending on the browser a visitor was running, you could simply query the navigator.appName property, like so: var browserString = navigator.appName; if (browserString == "Netscape") { // Do something for Netscape/Mozilla here document.write ("Long live the lizard."); } else if (browserString == "Microsoft Internet Explorer") { // Do something for Microsoft here document.write ("You will be assimilated."); } else { // The browser is not one of the major two document.write ("Why must you always be so different?"); } However, navigator.appName is extremely limited in the amount of information it provides. Other navigator properties provide more useful information. For instance, the
  • 186. 166 How to Do Everything with JavaScript navigator.appVersion property provides more specific browser version information. For Netscape browsers, the string returned from that property is quite straightforward. This screenshot was taken from Netscape 7.0 running on Windows 98. Just to make life more confusing for web developers, both Netscape 6 and 7 return their version number as “5.0.” However, Netscape did not produce a version 5 (the version number jumped from 4.8 to 6.0), so this version number is inaccurate. Similarly, Microsoft Internet Explorer returns its version information in the navigator.appVersion string, as we can see from the following snapshot taken from Microsoft Internet Explorer 6.0. Recent releases of the Microsoft web browser always report the version number as 4.0 compatible. However, the actual version number is embedded later in the same string (in this case, MSIE 6.0). The Mozilla 1.x, Netscape 6.0, and Netscape 7.0 browsers are all based on the same source code, so their behavior is very similar. If you ever need to get the exact browser name and version number from these browsers, you can query the userAgent property of the navigator object. As you can see from the following illustration, it contains some very specific version number information, right down to the exact date the browser was compiled.
  • 187. CHAPTER 7: Create Scripts That Work in Every Browser 167 Using these three properties, we can create a JavaScript function that will detect the exact browser type the user is running: function getBrowserInfo() { // Define variables to contain the results var browserName = navigator.appName; var browserVersionNum = parseFloat(navigator.appVersion); var browserAgent = navigator.userAgent; // Boolean (true or false) variables to detect browser type var is_IE = (browserAgent.indexOf("MSIE") != -1); var is_NN = (browserName.indexOf("Netscape") != -1); // Based on browser type, retrieve version number if (is_NN) { if (browserVersionNum >= 5.0) { 7 var tempStart = browserAgent.indexOf("Netscape/"); if (tempStart == -1) { // "Netscape/" not found; must be Mozilla tempStart = browserAgent.indexOf("rv:"); tempStart += 3; browserName = "Mozilla" var tempEnd = browserAgent.indexOf(")", tempStart); } else { // "Netscape/" found; must be Netscape Gecko tempStart += 9; var tempEnd = browserAgent.length; } var browserVersion = browserAgent.substring(tempStart, tempEnd); } else { // version < 5.0; must be old Netscape var browserVersion = browserVersionNum; } } else if (is_IE) { var tempStart = browserAgent.indexOf("MSIE"); tempStart += 5; var tempEnd = browserAgent.indexOf(";", tempStart); var browserVersion = browserAgent.substring(tempStart, tempEnd); } // Create new property of navigator object based on real
  • 188. 168 How to Do Everything with JavaScript // version number navigator.appRealVersion = browserVersion; return; } getBrowserInfo(); document.write ("<h1>You appear to be running:<br><br>"); document.write ("<b>" + navigator.appName + "</b> <i>version</i> "); document.write ("<b>" + navigator.appRealVersion + "</b></h1>"); As you can see, we have to do a fair amount of coding gymnastics to figure out the actual version number of the various flavors of Netscape browser. For Netscape 4 and earlier, the navigator.appVersion property returns the correct value. Since Netscape 6 and 7 and Mozilla all return 5.0 as the navigator.appVersion, we have to start searching the navigator.userAgent property for the appropriate value. The preceding code has been simplified for the purposes of this example and thus does not cover all the possible browser types or versions. For an excellent example of a browser-detecting script, I recommend checking out Bob Clary’s Practical Browser Sniffing Script at http://bclary.com/xbProjects-docs/ua, which uses the properties of the navigator object to determine the browser type and version. That web site also contains a script (at http://bclary.com/xbProjects-docs/xbDOM) that allows you to use one standard set of DOM objects across all browsers. The following illustrations show how our little function runs in Netscape 2.0 and Netscape 7.0.
  • 189. CHAPTER 7: Create Scripts That Work in Every Browser 169 7 Microsoft Internet Explorer has always provided its version number in the exact same way. It reports itself as Netscape 4.0 compatible in the navigator.appVersion property and leaves the actual software version number embedded elsewhere in the same string. It is relatively easy to search for it using the indexOf() method of the JavaScript String object. Query the Document Model The problem with relying on code that checks for browsers by name and version is that it’s not foolproof. Currently, about 96 percent of web surfers use one of the two major browsers— Netscape or IE. But what about the other 4 percent—surfers who choose another brand, such as Opera or Konqueror? New browsers are being developed, and web sites will not work reliably if they are only coded to work with the top two brands. The other problem is that as new versions of IE and Netscape are released, support for different features changes. For instance, Netscape 4 supported a layout method called layers, but support was later dropped when Netscape 6 came out. (We will discuss layers more in the section entitled “Write Cross-Browser Code.”) The easiest way to get around the problem of the wide variety of available browsers (both in the present and in the future) is to write code that checks to see if a DOM method exists before attempting to use it. The first official version of the Document Object Model (known as DOM 1) defines a method of the document object called getElementById(). Recent browsers (such as IE 5 and Netscape 6) support it, but older browsers do not. Simply calling the getElementById() method in a browser that does not support it will cause an error: var objptr = document.getElementById("carname");
  • 190. 170 How to Do Everything with JavaScript So if you wanted to check to see if the current browser supports the getElementById() method before using it, you would simply query the document object to see if it has a member by that name before calling it: if (document.getElementById) { var objptr = document.getElementById("carname"); } The preceding code will work in any browser, since browsers that do not support that method will not execute the code inside the if statement. Of course, in those browsers, the variable objptr would not be set, so it is best to have alternate code to handle those situations: if (document.getElementById) { var objptr = document.getElementById("carname"); } else { alert ("Sorry, this web page will not work in your browser."); } Of course, if you have to surround each and every call to a DOM method with its own if statement, your program will be long and inefficient. So the best approach may be to combine the browser sniffing method with the DOM detection method to get the best of both worlds. Stick to Web Standards In the early days of web development, the two largest browser makers were competing aggressively for market share—perhaps too aggressively. One of their favorite tactics was to try to outdo each other in terms of features. Consumers would download and install the newest release of their favorite browser, and within days the next release would be available for download. Large companies, who sometimes require months to test and approve new software for use, found themselves up to two full versions behind the current release. Of course, this led to two HTML standards instead of one, which made the web developer’s job a lot more complicated than it had to be. Luckily for us, both Microsoft and Netscape eventually decided that they would hold off implementing new HTML and JavaScript features until they were approved by a standards committee. However, as a result of the early “wild West” mentality, there are a number of nonstandard coding practices that should be avoided in order to achieve cross-platform compatibility. Table 7-2 contains a list of elements that are not part of the HTML 4 standard. These proprietary markup tags should be avoided if you wish to create web pages that work consistently in any browser. If you want to check your web page to see if it conforms to the official standards, the W3C web site provides an HTML validation service at http://validator.w3.org. This tool is the easiest way to see how far your web page deviates from the official standards. It even identifies any HTML code that contains problems.
  • 191. CHAPTER 7: Create Scripts That Work in Every Browser 171 Proprietary Markup Supporting Browser(s) <layer> Netscape 4 (only) <marquee> IE <bgsound> IE <embed> IE, Netscape <noembed> IE, Netscape <multicol> Netscape <spacer> Netscape <nobr> IE, Netscape <wbr> IE, Netscape <blink> Netscape <xmp> IE, Netscape <listing> IE, Netscape 7 <plaintext> IE, Netscape <keygen> Netscape <layer>, <ilayer> Netscape <nolayer> Netscape <server> Netscape TABLE 7-2 Proprietary Markup Tags, Not Part of Official HTML Standard Write Cross-Browser Code Earlier in this chapter, we played with some JavaScript code that could be used to detect the exact name and version number of the client browser. In this section, we will put similar code to use with dynamic HTML. Dynamic HTML (or DHTML for short) is an extension of the HTML standard that allows JavaScript programs to change and modify a web page after it has been loaded in the browser, without having to go back to the web server for a new page. For the most part, JavaScript accomplishes this through the manipulation of methods and properties in the browser’s DOM. Dynamic HTML is used regularly by Internet sites to provide fancy drop-down menus, images, and text that change when you move the mouse cursor over them and e-commerce shopping carts that recalculate the total cost of an order every time a check box is selected or cleared. In recent months, advertisers have caught the DHTML bug and are creating dynamic advertising that travels across the web page (and can’t be turned off or avoided). Cross-browser DHTML is difficult to code, however, since the JavaScript code required for Netscape and Microsoft browsers is quite different. While standardization has made programming HTML and basic JavaScript much easier, compared with only a few years ago, the implementation of vastly different DOMs among the browsers is one of the last remaining wilderness areas.
  • 192. 172 How to Do Everything with JavaScript Figure 7-1 shows an example of a web page that uses DHTML. The hierarchical tree on the left side of the screen can be expanded and contracted with a simple mouse click. Menu items are displayed and hidden dynamically, without having to request new HTML from the web server. This type of DHTML menu gives a nice effect for visitors to your web page. One of the first difficulties you are likely to encounter is that Netscape 4 uses a method called layers to define areas of a web document that can have a style applied to them. <html> <head><title>Layers sample</title></head> <body> <h1>Netscape Layers Example</h1> <layer id="mylayer"> <font color="white"><b>A black square</b></font> </layer> <layer id="mylayer2"> <b>A gray square</b> </layer> <script language="JavaScript" type="text/javascript"> document.layers["mylayer"].bgColor = "black"; document.layers["mylayer2"].bgColor = "#CCCCCC"; document.layers["mylayer2"].moveBy (60, 10); </script> </body> </html> This HTML code is designed to work in Netscape 4.x web browsers only. Our code defines a Netscape layer named mylayer using the HTML <layer> tag. We define a second layer named mylayer2. Using JavaScript, we are able to change the background colors of the two layers, and move one of them so that they don’t completely overlap. The effect can be seen in Figure 7-2. Unfortunately, the preceding code does not work in any version of IE or in the newer Netscape 6 browsers. We will have to modify our code a little to detect the type of browser running, and perform different tasks based on that. First, we need to change the layers to work in all browsers. The following code does not properly conform to HTML standards (since the <layer> tag is not part of the standard), but it will work in both IE and Netscape.
  • 193. CHAPTER 7: Create Scripts That Work in Every Browser 173 7 FIGURE 7-1 An expandable tree menu using DHTML <layer id='mylayer'> <div id='mydiv' style='position:absolute'> <font color="white"><b>A black square</b></font> </div> </layer> <layer id='mylayer2'> <div id='mydiv2' style='position:absolute'> <b>A gray square</b> </div> </layer>
  • 194. 174 How to Do Everything with JavaScript FIGURE 7-2 Creating layers in Netscape 4 Notice how we use the HTML standard <div> tag nested inside the nonstandard <layer> tag. Browsers that do not support <layer> will ignore it, as browsers that do not support <div> will ignore that tag. Next we need to modify the script to detect the type of browser running. We could use the getBrowserInfo() script from earlier in the chapter, but our needs are much simpler than that. All we need to do is detect the difference between Netscape 4, Netscape 6, and IE. To do that, we can use the following JavaScript code. <script language="JavaScript" type="text/javascript"> var ua = navigator.userAgent.toLowerCase(); var ie4 = ua.indexOf("msie") != -1; if (document.layers) { // Netscape 4 code goes here } else if (document.getElementById && ie4) { // IE code goes here } else if (document.getElementById) { // Netscape 6 code goes here
  • 195. CHAPTER 7: Create Scripts That Work in Every Browser 175 } </script> This code works in a fairly simple fashion. Netscape 4 is the only browser whose document object has a layers property, so checking for that property’s existence confirms that the browser type is Netscape 4. We can do the same trick using the getElementById method of the document object, except we still need to differentiate between IE 4 and Netscape 6. The navigator.userAgent property allows us to do that. Finally, we add in the browser-specific DHTML code to manipulate the two <layer> or <div> tags on the screen to create a visual effect. <html> <head><title>Layers sample</title></head> <body> <h1>Cross-Browser Style Sheets Example</h1> 7 <layer id='mylayer'> <div id='mydiv' style='position:absolute'> <font color="white"><b>A black square</b></font> </div> </layer> <layer id='mylayer2'> <div id='mydiv2' style='position:absolute'> <b>A gray square</b> </div> </layer> <script language="JavaScript" type="text/javascript"> var ua = navigator.userAgent.toLowerCase(); var ie4 = ua.indexOf("msie") != -1; if (document.layers) { // Netscape 4 code goes here document.layers["mylayer"].bgColor = "black"; document.layers["mylayer2"].bgColor = "#CCCCCC"; document.layers["mylayer2"].moveBy (60, 10); } else if (document.getElementById && ie4) { // IE code goes here var div1 = document.getElementById("mydiv"); var div2 = document.getElementById("mydiv2"); div1.style.backgroundColor = "black"; div2.style.backgroundColor = "#CCCCCC";
  • 196. 176 How to Do Everything with JavaScript div2.style.pixelLeft = div1.offsetLeft + 60; div2.style.pixelTop = div1.offsetTop + 10; } else if (document.getElementById) { // Netscape 6 code goes here var div1 = document.getElementById("mydiv"); var div2 = document.getElementById("mydiv2"); div1.style.backgroundColor = "black"; div2.style.backgroundColor = "#CCCCCC"; div2.style.left = (div1.offsetLeft + 60) + "px"; div2.style.top = (div1.offsetTop + 10) + "px"; } </script> </body> </html> The resulting cross-browser compatible code can be seen in IE 6 in Figure 7-3 and Netscape 7.0 in Figure 7-4. The results are completely identical to those in Netscape 4. FIGURE 7-3 Microsoft IE 6 interprets the <div> tag and the DHTML JavaScript code correctly.
  • 197. CHAPTER 7: Create Scripts That Work in Every Browser 177 7 FIGURE 7-4 Even though Netscape 7.0 requires slightly different JavaScript, the same effect is created. This is a good example of the difficulties JavaScript programmers sometimes face when developing code that works in any browser. In the next chapter, we will take a look at one of JavaScript’s primary duties on the Internet— helping users fill out forms. You will learn how to build a form in HTML, learn about all the controls that can go into a form, and see how JavaScript can be used to validate the data entered before it is sent to the server for processing.
  • 198. This page intentionally left blank
  • 199. Manipulate Chapter 8 Web Forms
  • 200. 180 How to Do Everything with JavaScript How to... ■ Request user input using an HTML form ■ Retrieve and set form control values ■ Prepare form data for server submission ■ Handle multiple forms In previous chapters, we have seen how JavaScript can be used to provide dynamic web pages that contain animated menus or are slightly different depending on the web browser being used or the time of day. As time goes on, developers will find it easier than ever to include these special JavaScript tricks on their own personal home pages. What has made JavaScript indispensable as a development tool for most professional web developers is its ability to handle user input. JavaScript makes the gathering and processing of user information easier—for both the user and the web developer. JavaScript can assist in many ways: ■ Store and retrieve bits of information on the user’s computer (called cookies) ■ Verify that all mandatory form fields were provided ■ Validate the proper formatting of user-entered data ■ Provide instant feedback to the user without having to go to the web server And best of all, it is often very easy to do all these things—only a few lines of code are needed. By solving many more problems than it created, JavaScript quickly became an indispensable tool for serious web developers. Understand HTML Forms The best and most flexible way to ask for user input is with HTML forms. A form, in web programming, is a series of one or more user controls that are designed to capture user input. A user control is typically a text box, a list box, or a button of some sort that allows the user to provide information to the web browser. In fact, web forms are modeled after paper forms, like those you fill out for a job application or a survey. There are 13 user controls in HTML: ■ Text box Allows a single line of text input ■ Password box Allows a single line of text input, protected by asterisks ■ Text area Allows one or more lines of text input ■ Hidden Can contain a single line of text, hidden from the user ■ List box User can choose from one or more predefined choices ■ Radio button User can choose one of many predefined choices ■ Check box User can choose any number of many predefined choices
  • 201. CHAPTER 8: Manipulate Web Forms 181 ■ File User can upload a file from the local machine to the web server ■ Push button Causes a program-defined action to occur ■ Submit button Causes the form to be submitted ■ Image button Creates a graphical submit button ■ Reset button Causes the form to be cleared ■ Object Creates a special (user-defined) input control Each of these controls performs a special function in requesting user input. Which control you use depends a lot on the individual circumstances. For instance, when you need the user to select one of 50 choices (like selecting which state they live in), you would normally go with a list box control, which allows you to provide dozens of options in very little space. Choosing to display 50 radio buttons instead takes up a lot more space and may cause the rest of the form to scroll off the bottom of the screen. Request User Input Using an HTML Form To see what a typical HTML form looks like, let’s examine the web page in Figure 8-1. The 8 United States Postal Service (www.usps.gov) provides this online form to register address changes of families or businesses that move and would like their mail forwarded to their new location. FIGURE 8-1 The change of address form on the U.S. Postal Service web site
  • 202. 182 How to Do Everything with JavaScript The first form field on the screen, labeled “Prefix Title,” allows the user to select from a number of name prefixes (such as “Dr.,” “Mr.,” and “Mrs.”). If they do not use a prefix before their name, they can select “N/A” for not applicable. This control is called a list box, since by pressing the down arrow button, the user will see several options from which they can choose. The form field labeled “First Name” is a text box, allowing the user to enter one or more characters using the keyboard. Sometimes, programmers place restrictions on this field using JavaScript, but often the user can enter any combination of letters, numbers, or special symbols. Programmers can use HTML to specify a maximum length for this field. When the user has finished entering his or her personal data, they are asked to click on an HTML submit button. The submit button causes the data from the web form to be sent to a program waiting on a web server for processing. Using JavaScript, web developers can have the data validated before allowing the web server submission to proceed. Process Form Input with Client-Side JavaScript Once the form has been filled out and submitted, it is often sent to a web server for processing. It is important to note that it does not have to be sent to a web server—oftentimes web forms can be processed entirely on the client using JavaScript. You will often see these client-side forms in the form of online calculators and similar tools, where JavaScript is smart enough to calculate the desired result and perform the requested action without needing help from a web server.
  • 203. CHAPTER 8: Manipulate Web Forms 183 Figure 8-2 shows an example of such a client-side form. The web page displayed in the figure (http://javascript.internet.com/calculators/amortization.html) can calculate the monthly mortgage payments if you provide the amount of the loan, the interest rate, and the amortization term. This is calculated using a JavaScript function embedded in the web page. We will examine how to create JavaScript code that can respond to web forms later in this chapter, in the “Catch Web Form Submissions with onsubmit” section. Process Form Input on a Web Server Web forms that require complex processing—those that access a database, for instance—must be submitted to an application waiting on the server. There are many prominent technologies available to create these form-handling programs: ■ Server-side JavaScript ■ Application Server Pages (ASP) ■ Java Servlets 8 FIGURE 8-2 Calculating monthly mortgage payments using an HTML form
  • 204. 184 How to Do Everything with JavaScript ■ Java Server Pages (JSP) ■ Perl ■ PHP ■ A compiled binary written in almost any language (such as C) Once these programs accept the data submitted by the web form, they usually perform any processing required and then respond to the browser with another HTML page. The communication process between client and server is depicted in Figure 8-3. It shows an example of a user performing a search at one of the major search engine web sites. The web server accepts the keywords using an HTML form, checks its database for related web pages, and returns a new HTML web page with the results. Insert an HTML Form into a Web Page Forms are added to web pages in the same way that images, text, and other elements of the page are, with HTML markup. Developers can define all the parts of a form, including the controls it contains and how they are arranged, using standard HTML tags. Use the <form> Tag In HTML, forms are defined using the <form> tag. The <form> tag allows you to define the type of form you wish to create, including the URL of the program waiting to accept the user’s input (if any). These are specified using the <form> element’s attributes. An attribute is an element’s named parameter and associated data. Attributes are specified in the following manner: <element attribute1="value1" attribute2="value2" ... attribute3="value3"> FIGURE 8-3 Communication between client and server when an HTML form is submitted
  • 205. CHAPTER 8: Manipulate Web Forms 185 The <form> element has the following attributes: ■ id String that must be unique across the entire web page ■ class List of associated CSS classes ■ style Inline CSS style commands ■ title Advisory title ■ lang ISO language code ■ dir Direction of text (right to left or left to right) ■ action URI of program that will handle form data ■ method The way data will be transmitted to the server (either GET or POST) ■ enctype MIME encoding type ■ accept List of MIME types accepted for file upload ■ accept-charset List of supported charsets In addition to all those attributes, the <form> element can also contain a number of event 8 handlers. Events are actions usually initiated by the user, such as a mouse movement or certain keypresses. Event handlers are JavaScript code and functions that are designed to act when certain events happen. We will examine all the predefined HTML event handlers in more detail in Chapter 9. Have a Form’s Contents Mailed to You The <form> tag’s action attribute allows you to specify the web server URI for the program that will process the form. Typically, this program is an ASP page, Java servlet, or a Perl script running on the target web server. You can also direct the browser to e-mail you the contents of the form instead. This is done by providing an e-mail address using the mailto: protocol to the action attribute. To construct a URI using the mailto: protocol, you simply append the actual e-mail address to the mailto: string, like so: mailto:[email protected] If you used the preceding string as the URI for the action attribute, the contents of the web form would be mailed to the President of the United States. This technique is not guaranteed, however, since it uses the mail program installed on the user’s computer. The program might not be set up correctly for sending e-mail, or the user might cancel the e-mail from being sent.
  • 206. 186 How to Do Everything with JavaScript For now, we are only concerned with two possible events that can happen to a web form: ■ onsubmit JavaScript code that will be run before the form is submitted ■ onreset JavaScript code that will be run before the form’s data is erased Some HTML elements have mandatory attributes, that is, attributes that must always be present. The <form> element is one of those, as the action attribute must always be specified in order for the HTML to be valid. The most basic type of form is the following: <form action="#"> </form> This HTML code creates an empty form that does not contain any controls. Forms such as this are quite useless, of course, because they have no purpose. HTML <form> elements by themselves are invisible, in that they do not have a visual component. Form controls (buttons and text boxes, for instance) are the visual components of forms. Forms can also contain text, tables, and other HTML elements. It is common to use the pound sign (#) as the value of the action attribute of the <form> tag when none is needed, since the action attribute is mandatory and cannot be omitted. You might use this for forms designed to only exist on the client, which will never need to be submitted to a server. The pound sign (#) is one of the shortest valid URLs. Add Form Controls As we have seen, forms are pretty useless without controls. Form controls allow a web page to accept user input. Some controls allow users to enter text themselves, and some provide users several predefined options to choose from. Form controls are added to <form> elements with HTML of their own. Table 8-1 lists the common input controls along with the HTML required to add them to a web page. Accept Text Input with a Text Box Perhaps the most common type of form control is the text box. In fact, the text box control is the default type of the <input> element. The following HTML code will create a web form with a single text box inside. <form action="#"> <input> </form>
  • 207. CHAPTER 8: Manipulate Web Forms 187 Control Name HTML Code Text box <input type="text"…> Password box <input type="password"…> Text area <textarea…> </textarea> Hidden text <input type="hidden"…> List box <select…> </select> Radio button <input type="radio"…> Check box <input type="checkbox"…> File upload <input type="file"…> Push button <input type="button"…> Push button <button…> Submit button <input type="submit"…> Image button <input type="image"…> Reset button <input type="reset"…> 8 Object control <object…> </object> TABLE 8-1 A List of HTML Form Controls Of course, creating a form like that has several drawbacks. First, anyone who encountered that form in their web browser would not know what to do with it—the control is unlabeled. It’s just a text box sitting on a page by itself. Second, web developers looking at that code might find it a bit confusing, since the <input> control has so many forms. It might be better to explicitly set the control type. A better example of a web form would be the following: <form action="#"> Please enter your age: <br> <input type="text" name="age"> </form> This type of web form is easier to use for both the web developer and the web page visitor. The text box control has several attributes that give developers more control over the look and behavior of the control: ■ id String that must be unique across the entire web page ■ class List of associated CSS classes
  • 208. 188 How to Do Everything with JavaScript ■ style Inline CSS style commands ■ title Advisory title ■ lang ISO language code ■ dir Direction of text (right to left or left to right) ■ name The name of the control ■ value The default value ■ size The size of the control on the screen, in characters ■ maxlength The maximum number of characters that can be entered ■ readonly Locks the control so its value cannot be modified by the user ■ accesskey Sets the keyboard shortcut key ■ tabindex Sets the order in which controls receive focus on a form ■ disabled Locks the control so that it cannot receive focus or be modified by the user In web programming, we say a control has focus when it is the currently active control. The browser often lets us know which control has focus by using a flashing vertical line for text boxes or some other highlight for buttons and other controls. Most browsers draw a temporary dotted box around nontext controls that have focus. Besides the preceding attributes, our input control can also capture a number of events as well. We will examine all the predefined HTML event handlers in more detail in Chapter 9. For now, we will only concern ourselves with the following HTML events: ■ onfocus JavaScript code that will be run when a control receives focus ■ onblur JavaScript code that will be run when a control loses focus ■ onchange JavaScript code that will be run when a control loses focus and the value of its contents has been altered By using some of these attributes on our text box, we can improve the look and behavior of our control: <form action="#"> Please enter your <u>a</u>ge: <br> <input type="text" name="age" size="5" maxlength="3" value="" accesskey="A"> </form>
  • 209. CHAPTER 8: Manipulate Web Forms 189 We have reduced the horizontal length of the control to five characters wide by using the size="5" attribute on the <input> control. By specifying maxlength="3" we are restricting input to a maximum of three characters in length. Since we are asking for an age, it is reasonable to assume three digits will be enough. The value="" attribute sets the default contents of the field to an empty string. The accesskey parameter, which is set to "A" in our example, allows users to jump to the control by using the ALT-A key combination in most versions of Windows, or the CONTROL-A key combination for most Mac systems. The key combination required to activate an access key is dependent on both the browser type and operating system, so check your browser documentation if you cannot get it to work. 8 Provide a List Box Control A list box is a convenient control to use when you need the user to select one of multiple choices. In HTML, list boxes are created using the <select> element, and items in the list are defined using the <option> element. There are two types of list boxes you can use inside your web-based forms: the drop-down list box and the scrolled list box.
  • 210. 190 How to Do Everything with JavaScript Privacy and the Internet HTML forms are commonly used to allow visitors to log in to a web site. Users must normally supply a valid user ID and password to the server before being allowed into the restricted areas of the site. From a developer’s point of view, a text box should be used to request the user ID from the user. As an added level of security, a password box control should be used to request a user’s password. The password box replaces the characters typed in with asterisks, so that password becomes ********. This is done so that other individuals looking at the same computer monitor (from over the user’s shoulder, for instance) will not be able to read the password. You should know, however, that this is a very weak type of security. Unless the form data is encrypted using Secure Sockets Layer (SSL), typically using HTTPS protocol, the password will be sent over the Internet as plain text, which can be easily read by anyone along the path or by anyone with access to the web server’s activity logs. The drop-down list box appears as a text box with a small arrow button next to it. Clicking the arrow causes the control to create a scrollable pop-up window in which the user can select one of multiple choices, as you can see here.
  • 211. CHAPTER 8: Manipulate Web Forms 191 Users cannot type their own text into the text box—they must select one of the predefined items. This type of control is best used when there are at least three options to choose from, such as when asking the user to select their home state or country. Other controls, such as radio buttons and check boxes, are better for having the user select from only two or three options. The scrolled list box appears as a combination of a multiline text box attached to a vertical scroll bar, as you can see here. 8 A scrolled list box is created by specifying the number of items to be displayed at once using the size attribute of the HTML <select> element. Users may select more than one option from a scrolled list box if the developer has specified the multiple attribute. A user can select multiple options by holding down the CTRL (PC) or COMMAND (Mac) key on the keyboard when selecting items from the list. The following HTML will create a form with a single drop-down list box inside it. <form action="#"> What would you like for dinner?<br> <select name="dinner"> <option selected value="1">Chicken</option> <option value="2">Beef</option> <option value="3">Pork</option> <option value="4">Fish</option> <option value="5">Vegetables</option>
  • 212. 192 How to Do Everything with JavaScript </select> </form> By specifying the size attribute, we can modify the drop-down list box to become a scrolling list box. Since our size attribute only allows three items to display at once, the user will be able to see the remaining two items by using the scroll bar. <form action="#"> What would you like for dinner?<br> <select name="dinner" size="3"> <option value="1" selected>Chicken</option> <option value="2">Beef</option> <option value="3">Pork</option> <option value="4">Fish</option> <option value="5">Vegetables</option> </select> </form> The HTML <select> element has several attributes that give web developers more control over the look and behavior of the list box control: ■ id String that must be unique across the entire web page ■ class List of associated CSS classes ■ style Inline CSS style commands ■ title Advisory title ■ lang ISO language code ■ dir Direction of text (right to left or left to right) ■ name Name of the control ■ size Number of rows to display at once ■ multiple Allows the control to accept multiple selections ■ tabindex Sets the order in which controls receive focus on a form ■ disabled Locks the control so that it cannot receive focus or be modified by the user Beside the preceding attributes, our list box control can also capture a number of events as well. We will examine the predefined HTML event handlers in more detail in Chapter 9. The list box can capture the following three events: ■ onfocus JavaScript code that will be run when a control receives focus ■ onblur JavaScript code that will be run when a control loses focus ■ onchange JavaScript code that will be run when a control loses focus and the value of its contents has been altered
  • 213. CHAPTER 8: Manipulate Web Forms 193 The HTML <option> element has several attributes of its own: ■ id String that must be unique across the entire web page ■ class List of associated CSS classes ■ style Inline CSS style commands ■ title Advisory title ■ lang ISO language code ■ dir Direction of text (right to left or left to right) ■ selected Defines this list item as the default ■ disabled Locks the control so that it cannot receive focus or be modified by the user ■ label Defines a label for the list item ■ value The string returned to the server when a user selects the item The <option> element can also receive a number of events. We will examine all the predefined HTML event handlers in more detail in Chapter 9. 8 Accept Text Input with a Text Area One variation of the text box is the text area. The text area control accepts multiple lines of input and is defined using the HTML <textarea> element. One drawback of the text area control is that you cannot easily restrict the amount of data a user adds to that control. The most common attributes for the <textarea> element are rows, cols (columns), and name. As you would expect, you specify the height of the control using the rows attribute, and the width of the control using the cols attribute. For example, the following text area will hold 5 rows that are 60 characters wide. <form action="#"> <textarea rows="5" cols="60"> This is my example text area. </textarea> </form> Default text is inserted between the <textarea> and </textarea> tags. Add a Push Button Control to a Form Unlike other controls, push buttons (or just buttons) are generally not used to provide user input. Their purpose is to cause the browser to execute some JavaScript code through the button’s onclick event handler. There is a special type of push button control called a submit button that can be used to provide user input. We will examine submit buttons in the next section.
  • 214. 194 How to Do Everything with JavaScript In HTML, there are two ways to create a simple push button: with the <input> element and with the <button> element. The <input> element is used to create the most basic type of push button, as follows: <form action="#"> <input type="button" value="Push me" onclick="dothis()"> </form> The push button defined in this form will call a JavaScript function named dothis() when pressed. The value attribute defines the button’s caption, or the text label on the button. The <button> element allows developers to create a more complex type of push button. The <button> element accepts complex HTML input (including text and images) as its caption. For example, the following push button displays a check mark image next to the word OK, which is in bold print. It too will call the JavaScript dothis() function when clicked. <form action="#"> <button onclick="dothis()"> <img src="checkmark.gif"> <font size="6"><b><i>OK</i></b></font> </button> </form> Here is how this special type of push button looks in a browser window.
  • 215. CHAPTER 8: Manipulate Web Forms 195 Add a Submit Button Submit buttons are a special type of form control, in that they cause a form to submit itself to the server. The variables and data defined in the form are sent to the web server application defined in the action attribute of the <form> element, using the method defined in the method attribute. For instance, the following code defines a form that submits itself to an ASP web page. The ASP web page is responsible for processing the data and sending a new web page for the browser to display. <form action="http://www.example.com/scripts/myscript.asp" method="GET"> Full Name: <input type="text" name="fullname"><br> Age: <input type="text" name="age" size="5"><br> Date of Birth: <input type="text" name="DOB" size="10"><br> <input type="submit" value="Submit Form"> </form> When the user clicks the Submit Form button, the three other form controls on the form 8 (fullname, age, and DOB) will be sent to the ASP web page, along with whatever text the user entered in those fields. Only named form fields will be submitted to the server for processing. Fields without an assigned name attribute, even text fields, will not be submitted to the server. It is common to omit the name of submit buttons. The only time it would be useful to name them would be if there were more than one submit button on a form and the server needed to know which button was used to submit the form. Catch Web Form Submissions with onsubmit Previously in this chapter, in the section entitled “Use the <form> Tag,” we saw that the HTML <form> element has a number of predefined event handlers. Handling an event is known as catching it, and in this section we will take a brief look at one of the <form> element’s events and how to catch it. The onsubmit attribute allows us to specify some JavaScript code that will be executed before the web form is submitted to the web server. This JavaScript code is usually stored inside a function, and so the event handler only refers to that function. But sometimes the JavaScript code will appear directly in the event handler attribute. <script language="JavaScript" type="text/javascript"> function checkname() { alert("Your name is " + document.forms[0].fullname.value); } </script> <form action="http://www.myserver.com/formhandler"
  • 216. 196 How to Do Everything with JavaScript method="GET" onsubmit="return checkname()"> What is your name? <br> <input type="text" name="fullname"> <br> <input type="submit" value="Submit Form"> </form> In the preceding HTML code, we have specified a JavaScript function that will be called at the time the form is submitted to the web server using the onsubmit event handler attribute of the <form> element. The function that will be called is checkname(), which we have defined just above the form. Once the checkname() function finishes, the form data will be sent to the URL http://www.myserver.com/formhandler for processing. Here you can see the HTML form that is created. I have already typed in the five letters of my first name as an example. The button labeled “Submit Form” is actually a submit button, which will cause the form to be sent to the web server. Before it is submitted, however, the checkname() function is called. That function simply retrieves the contents of the text box and displays it in a JavaScript alert box. Once the alert box is accepted by the user, the form sends its data to the web server for processing.
  • 217. CHAPTER 8: Manipulate Web Forms 197 Our onsubmit event handler actually has the ability to stop the web form from being submitted. Returning the Boolean value false from the function causes processing to stop without the form being submitted to the server. <script language="JavaScript" type="text/javascript"> function checkname() { var username = document.forms[0].fullname.value; if (username != "Scott") { alert("Sorry, " + username + ". I cannot let you proceed."); return false; } else { return true; 8 } } </script> The preceding JavaScript function, when called by the same HTML form, will not submit to the web server if the user does not type Scott into the name field. Catch Events on Form Controls Like the HTML <form> tag, form controls can also have programmable events. A program can define a JavaScript function or code that will be executed when a certain event occurs. For instance, JavaScript can detect when the mouse cursor passes over a control, when it has gained or lost focus, or when its value has changed. For example, the following code demonstrates how some of the text box control’s events can be captured. <html> <head> <title>Capture Form Control Events</title> <script language="JavaScript" type="text/javascript"> <!-- // Begin function modifylayer(changetext) { var lefield = document.getElementById("lastevent"); lefield.innerHTML = changetext + "<br><br>&nbsp;";
  • 218. 198 How to Do Everything with JavaScript } // End --> </script> </head> <body> <h1>Capture Form Control Events</h1> <form action="#" method="get"> Move the mouse in and out of this field, or change its contents.<br> <textarea name="samplefield" rows="10" cols="30" onmouseover="modifylayer('mouseover')" onmouseout="modifylayer('mouseout')" onchange="modifylayer('change')" onkeypress="modifylayer('keypress')" >Sample text</textarea><br><br> Last event captured: <div id="lastevent" style="background-color:#CCCCCC; font-weight:bold"> <br><br>&nbsp; </div> </form> </body> </html> The body of the HTML document has an HTML <form> that contains a single control— a multiline text box called a <textarea>. We have also defined an HTML <div> area, which contains text that we can change using JavaScript. The <textarea> also defines a number of event handlers. The web browser will call a JavaScript function named modifylayer() if any of the following events occurs for this control: ■ onmouseover When the mouse cursor enters the control ■ onmouseout When the mouse cursor leaves the control ■ onchange When the contents of the control have changed and the control has lost focus ■ onkeypress When a keyboard key has been pressed We define the modifylayer() function using the <script> tag inside the document header section. That function will write the name of the event out to the <div> area we have defined.
  • 219. CHAPTER 8: Manipulate Web Forms 199 You can see a list of all the browser events supported by Internet Explorer on Microsoft’s web site at http://msdn.microsoft.com/workshop/author/dhtml/reference/ events.asp. We also discuss web browser events more thoroughly in Chapter 9. Of course, there is also a way to capture the name of the event without having to pass it to the function explicitly using the window.event DOM object. We could modify our JavaScript code to the following to take advantage of this technique. function modifylayer() { var lefield = document.getElementById("lastevent"); var ename = window.event.type; lefield.innerHTML = ename + "<br><br>&nbsp;"; } With this type of function, we would no longer need to pass the name of the event inside each event handler. The modifylayer() function can handle all four events on its own. <textarea name="samplefield" rows="10" cols="30" onmouseover="modifylayer()" 8 onmouseout="modifylayer()" onchange="modifylayer()" onkeypress="modifylayer()" >Sample text</textarea><br><br> We can see from the following screen capture what this web page will look and act like in a web browser.
  • 220. 200 How to Do Everything with JavaScript Retrieve and Set Form Control Values in JavaScript One of the code samples from the preceding section demonstrated one of the many possible ways of retrieving values from a web form. The DOM provides JavaScript programs several ways to access the controls on a form and their values, including: ■ As a property of the forms array ■ As key values in the elements array ■ Using one of three different methods of the document object Not all of these techniques work in older versions of the major browsers, so you may have to employ some of the cross-browser scripting techniques discussed in Chapter 7. Access Form Values Using the forms Array One technique that will work in all JavaScript-enabled browsers is accessing form controls using the forms array. The forms array is a property of the DOM document object; it contains an indexed list of all the forms on a web page. Indexes in JavaScript start at zero. We start by creating a variable that refers to the form itself. var myform = document.forms[0]; We can then access any control on the form by name. For instance, the following code allows you to access the contents of a text box called fullname: var fullname = myform.fullname.value; As in “Accept Text Input with a Text Box,” earlier in this chapter, value is a property of the text box control. The preceding code placed the contents of that text box in a variable we called fullname. Using this technique allows us to access any control on the form, as long as it is named. The following code demonstrates a form that contains a text boxes, a list box, and a group of radio buttons. Before the form is submitted, a function named checkform() verifies that the user entered text or made a selection in each of the fields. <html> <head> <title>JavaScript Test</title> <script language="JavaScript" type="text/javascript"> <!-- // Begin function checkform() { var myform = document.forms[0]; // Accessing text boxes is easy
  • 221. CHAPTER 8: Manipulate Web Forms 201 var fullname = myform.fullname.value; var emailaddr = myform.email.value; // Which drop down item is selected? var ageIdx = myform.age.selectedIndex; var age = myform.age.options[ageIdx].value; // Which radio button is selected? var hearObj = myform.hear; var hear = ""; for (var i = 0; i < hearObj.length; i++) { if (hearObj[i].checked) { hear = hearObj[i].value; } } // Check if any fields are blank 8 if ((fullname == "") || (emailaddr == "") || (age == "None") || (hear == "")) { alert("Some information appears to be missing."); return false; } else { return true; } } // End --> </script> </head> <body> <h1>JavaScript forms Array</h1> <form action="#" onsubmit="return checkform()"> <center> <table width="400" cellspacing="12"> <tr> <td align="right"><b>Name:</b></td> <td><input type="text" name="fullname"></td> </tr> <tr> <td align="right"><b>Email:</b></td>
  • 222. 202 How to Do Everything with JavaScript <td><input type="text" name="email"></td> </tr> <tr> <td align="right"><b>Age:</b></td> <td><select name="age"> <option value="None">-- Please select --</option> <option value="16-32">16-32</option> <option value="33-49">33-49</option> <option value="Over 50">50+</option> </select></td> </tr> <tr> <td align="right"><b>How did you<br> hear about us?</b></td> <td valign="top"> <input type="radio" name="hear" value="t"> TV<br> <input type="radio" name="hear" value="r"> Radio<br> <input type="radio" name="hear" value="n"> Newspaper<br> <input type="radio" name="hear" value="o"> Other</td> </tr> <tr> <td align="middle" colspan="2"> <input type="submit" value="Send to server"></td> </tr> </table> </center> </form> </body> </html> Figure 8-4 shows how this form would look in a typical web browser. If we were to try to submit this form without filling out one of the fields, the checkform() function would catch it, and report this error: Access Form Values Using the elements Array Another way to access the controls on forms is through the elements array. The elements array is a sequential list of all the form controls that appear on a web page. To access the value of
  • 223. CHAPTER 8: Manipulate Web Forms 203 8 FIGURE 8-4 A web page that contains various form controls a specific control, you need to know its position in the array beforehand. This array is convenient if you need to access all the controls in an array or search the array for a specific control. var earray = document.forms[0].elements; for (var count = 0; count < earray.length; count++) { alert(earray[count].name); } The preceding code demonstrates how the elements array can be queried. It successfully finds the first control on the form.
  • 224. 204 How to Do Everything with JavaScript Access Form Values Using getElementById() Both the techniques we have just examined (forms array and elements array) are the old way of using the DOM. The main problem with those methods is that they are specific to forms. If you wanted to access the contents of the <h1> element (the document heading) and change it, you could not. The getElementById() DOM method is the new preferred way to access any object on a web page—whether it is a form control, a <div> tag, or even a Java applet embedded in the page. To retrieve the value of the fullname text box, we would use the getElementById() function as follows: var fullname = document.getElementById("fullname").value; This code looks for an element with an ID of fullname anywhere inside the current document. JavaScript does not know (or care) at this point what type of object it is—it could be any HTML element. As its name implies, this function attempts to look up an element by its ID. Most HTML elements have an ID attribute (id=""), and in order to use this function on an element, you should set the ID attribute accordingly. <input type="text" id="fullname" name="fullname"> Most browsers will also search for elements by their name attributes if they cannot find an ID that matches. Access Form Values Using getElementsByName() Just as the getElementById() function will search for elements by ID attribute, the getElementsByName() function will search for elements by their name. The one difference between the two functions is that getElementsByName returns an array of elements. Thus, it can return more than one element. var hearObj = document.getElementsByName("hear"); This code will return an array of all the elements named hear on the web page. Earlier we created some HTML that included a set of radio buttons named hear—there were four elements named hear on the page (see “Access Form Values Using the forms Array”). Using this code on that form would return an array of four elements. The JavaScript code we used would then correctly determine which of the four radio buttons were selected. for (var i = 0; i < hearObj.length; i++) { if (hearObj[i].checked) { hear = hearObj[i].value; } }
  • 225. CHAPTER 8: Manipulate Web Forms 205 Access Form Values Using getElementsByTagName() The final method provided by the new JavaScript DOM is getElementsByTagName(). This method is very helpful in retrieving elements that are not named, such as the submit button on our previous form example. This function allows us to look up objects on a web page by their HTML element name. var mybutton = document.getElementsByTagName("input"); mybutton[6].value = "Please wait..."; mybutton[6].disabled = true; By adding this code to the beginning of our checkform() function, we can disable the submit button to stop the user from submitting the form more than once. The getElementsByTagName(“input”) function returns an array of all the <input> elements on a web page. We know the submit button is the seventh element on the web page created using the HTML <input> tag—the other six are two text boxes and four radio buttons. Since the array starts at index zero, the submit button is located in the sixth index in the array. 8 Button has been disabled and caption set to “Please wait.”
  • 226. 206 How to Do Everything with JavaScript So as you can see, the DOM provides a number of different methods for accessing the contents of a form. In the next chapter, we will examine the ins and outs of browser events. We will start off by looking at the different types of events in HTML and how to write event handlers to deal with them. And we will look at some of the special cross-browser compatibility issues that arise when dealing with events.
  • 228. 208 How to Do Everything with JavaScript How to... ■ Write JavaScript event handlers ■ Handle events using the event property ■ Trigger events in JavaScript ■ Overcome browser incompatibility The dictionary defines an event as “something that takes place” and that is exactly what it means in web programming as well. An event handler is JavaScript code that is designed to run each time a particular event occurs. Of course, this means that your JavaScript code may execute dozens of times, or not at all, depending on the circumstances. There are 18 events officially defined in the HTML 4.01 specification. In addition, browsers that support the official DOM Level 2 Events specification need to provide several more events for programmers to work with. However, Microsoft and Netscape have gone beyond the events listed in the official specifications and provide many more: IE supports more than 75 events, and Netscape supports at least 50. The DOM Level 2 Events specification can be found on the official W3C web site at http://www.w3.org/TR/DOM-Level-2-Events. The key to knowing how to write appropriate event handlers is understanding what the events are and when they occur. For instance, the following events are just three of the official 18 HTML 4.01 events: ■ load event Occurs when the HTML document has finished loading in the browser window ■ click event Occurs when the left mouse button has been clicked ■ keypress event Occurs when a keyboard key has been pressed JavaScript can be used to intercept these events when they occur and take certain actions (sometimes it is allowed to cancel the event). Intercepting an event is called capturing the event, and it is done by writing event handler code. If no event handling code is written, the browser will continue to process the event as normal using default behavior. In this chapter, we will examine the various events provided by most HTML elements and how event handlers should be written for each. We will also see how a JavaScript program can cause these events to occur manually, and we’ll look into the differences in event handling between the various browsers. Write JavaScript Event Handlers You saw some examples of event handlers in the previous chapter, in the “Catch Web Form Submissions with onsubmit” section. Writing an onsubmit event handler enabled our JavaScript program to check that all the fields on a form were filled out before the form submission was allowed to continue.
  • 229. CHAPTER 9: Handle Browser Events 209 Events fall into four major categories: ■ User interface events ■ Mouse events ■ Key events ■ HTML events User interface events happen as controls or other objects on a web page gain and lose focus. These events are often caused by other user actions (such as a tab key press or a mouse click), but they can happen programmatically as well. Mouse events occur when the user moves the mouse or presses one of the mouse buttons. These events allow a web page to respond to mouse movements by, for example, highlighting an image when the mouse moves over it. Key events occur when the user presses and/or releases one of the keyboard keys. Only certain HTML elements can capture keyboard events, as we will see later in this chapter. Finally, there are several events specific to certain HTML elements. They often relate to the browser window itself or to form controls and other objects embedded in a web page. The onsubmit event handler discussed in the last chapter falls into this category. 9 Handle User Interface Events User interface events deal exclusively with the transfer of focus from one object inside the web page to another. There are three user interface events defined in most web browsers. Event Name Event Handler Name Defined In focus onfocus HTML 4.01 blur onblur HTML 4.01 activate onactivate DOM Level 2 For example, let’s assume we have a web page with two text boxes. <form action="#"> <input type="text" name="box1"><br> <input type="text" name="box2"> </form> Say the active cursor is presently inside the text box named box1. When we hit the keyboard TAB key, we expect focus to transfer to the second text box, box2. Ignoring for a moment the keyboard events, the three user interface events fire (occur) in a predictable order. First, the activate event fires on box2. Next, the blur event fires on box1. Finally, the focus event fires on box2. We can modify the web page slightly to see that the events always fire in a predictable order.
  • 230. 210 How to Do Everything with JavaScript <script type="text/javascript" language="javascript"> function upd(instr) { document.forms[0].statusbox.value += instr + "; "; } </script> <form action="#"> <input type="text" name="box1" onblur="upd('blur box1')"><br> <input type="text" name="box2" onfocus="upd('focus box2')" onactivate="upd('activate box2')"><br><br> Event firing order: <input type="text" name="statusbox" size="40"> </form> In the preceding code, we have added a third text box called statusbox to the screen, to display the results of our event firing test. We have provided JavaScript to the three event handlers (onblur, onfocus, and onactivate) that will append the event and control names to the end of the statusbox text box. The results of the test are shown in Figure 9-1. As you can see, the events listed in the status box match the order we expected. FIGURE 9-1 User interface events are fired in a predictable order.
  • 231. CHAPTER 9: Handle Browser Events 211 Handle Mouse Events The seven mouse events listed in the following table all relate to actions taken by the user using the mouse. JavaScript programs have the ability to track mouse movement and button clicks as they relate to the web page and controls inside. Event Name Event Handler Name Defined In mousedown onmousedown HTML 4.01 mouseup onmouseup HTML 4.01 mouseover onmouseover HTML 4.01 mousemove onmousemove HTML 4.01 mouseout onmouseout HTML 4.01 click onclick HTML 4.01 dblclick ondblclick HTML 4.01 Tracking these mouse events is often done to enhance the user’s experience by highlighting menu items as the mouse pointer rolls over them or by updating screen text to provide more information about the element beneath the pointer. 9 For example, the following HTML code inserts an image into an web page using the <img> element. By capturing the mouseover and mouseout events, we can cause the image to change when the mouse pointer is over the image and change back to the original image once it leaves. <script type="text/javascript" language="javascript"> function changeimage(num) { var img = document.getElementById("SampleImage"); if (num == 1) { img.src = "NewImg.gif"; } else { img.src = "OriginalImg.gif"; } } </script> <img src="OriginalImg.gif" id="SampleImage" alt="Sample image" onmouseover="changeimage(1)" onmouseout="changeimage(2)" > The mouseover event fires the moment the mouse pointer enters the boundaries of the image. The onmouseover event handler calls the changeimage() function with a parameter of 1. The changeimage() function starts off by assigning a reference to the image to a variable based on its id, SampleImage. The src attribute of the image allows us to dynamically modify the image displayed in the browser.
  • 232. 212 How to Do Everything with JavaScript The mouseout event fires once the mouse pointer leaves the boundaries of the image. The changeimage() function handles this event as well, causing the image to go back to its original source. We can see the effects of this image rollover in Figure 9-2. Handle Key Events JavaScript programmers rarely use key event handlers to catch key events. While there are a few situations where you might want to use them, this type of event handling is more commonly found in Windows applications (such as Visual Basic programs) than in web-based programming. Like the user interface events, key events fire in a predictable sequence. There are three main key events in HTML. Event Name Event Handler Name Defined In keypress onkeypress HTML 4.01 keydown onkeydown HTML 4.01 keyup onkeyup HTML 4.01 By slightly modifying the code found in the “Handle User Interface Events” section, we can see the predictable order the events fire in. <script type="text/javascript" language="javascript"> function upd(instr) { document.forms[0].statusbox.value += instr + "; "; } </script> <form action="#"> <input type="text" name="box1" onkeypress="upd('keypress')" onkeydown="upd('keydown')" onkeyup="upd('keyup')"><br><br> Event firing order: <input type="text" name="statusbox" size="40"> </form> Before After FIGURE 9-2 The mouseover and mouseout events power image rollover effects.
  • 233. CHAPTER 9: Handle Browser Events 213 9 FIGURE 9-3 The order of the key events is keydown, keypress, and keyup. As you can see from the screenshot in Figure 9-3, the order of events is 1. keydown 2. keypress 3. keyup The keydown event occurs when almost any keyboard key has been pressed down, including nonalphanumeric keys such as HOME, ESCAPE, INSERT, and DELETE. The keypress event, on the other hand, only fires when certain alphanumeric keys are pressed, including punctuation, SPACEBAR, and ENTER. The keyup event is the complement to keydown, since it fires when almost any key has been released. Both the keydown and keypress events can be canceled. To cancel an event, you just need to make its event handler return false. Canceling a keydown or keypress event will cause the browser to ignore those keys. For example, if you wanted to restrict the types of characters entered into a form field, you could capture its keydown event and return false anytime a key is not in an acceptable range.
  • 234. 214 How to Do Everything with JavaScript <script type="text/javascript" language="javascript"> function checkkey() { var keycode = window.event.keyCode; if (keycode < 48 || keycode > 57) { return false; } else { return true; } } </script> <form action="#"> <input type="text" name="box1" onkeydown="return checkkey()"><br> </form> The preceding code shows how the keydown event can be captured. Since we want to be able to cancel the event, we include a return statement inside the event handler along with a call to the checkkey() function. The first 127 characters of the Unicode character set match the corresponding ASCII codes character for character. More information on the Unicode character set can be found at http://www.unicode.org. The checkkey() function gets the Unicode character code associated with the key by checking the keyCode attribute of the window.event DOM object. We compare the value of the keyCode against the range of values for numeric keys, which happen to be 48–57. If the keyCode we intercepted falls outside that acceptable range, we return false from the function to indicate that the key is to be ignored. Of course, we return true if the key falls inside the acceptable range. The keyCode property of the window.event object is only available in Netscape version 6 and later and Internet Explorer. This results in a text box that only accepts numeric input and ignores all other characters. The following table lists several common characters along with their keyCode values. keyCode Values Correspond To 48 through 57 0 through 9 65 through 90 A through Z (capital letters) 97 through 122 a through z (lowercase letters) 46 . (period) 44 , (comma) 40 and 41 ( and ) (parentheses) 36 $ (dollar sign) 35 % (percent sign) 34 " (quotation mark)
  • 235. CHAPTER 9: Handle Browser Events 215 Handle HTML Events In this context, HTML events means any events that do not belong in the user interface, mouse, or key event categories. Some HTML events are triggered directly by a user action, while others are fired only as an indirect result of a user action. The following table lists the HTML events, the event handler name, and the official specification that defined them. Event Name Event Handler Name Fires When (Event) Defined In load onload Browser finishes loading document HTML 4.01 unload onunload Browser about to unload document HTML 4.01 submit onsubmit Form about to be submitted HTML 4.01 reset onreset Form about to be reset HTML 4.01 select onselect Text box contents selected HTML 4.01 change onchange Form control contents changed HTML 4.01 abort onabort User aborts download of image DOM Level 2 error onerror Error occurs on object loading DOM Level 2 resize onresize Size of object about to change DOM Level 2 9 scroll onscroll User uses the scroll bar DOM Level 2 Let’s take a quick look at what these events do. ■ load event The onload event handler is called when the HTML document finishes loading into the browser window. This event is commonly relied on to do any initialization required in the document. For instance, if form fields need to be preloaded with text, and that was not covered by the HTML code itself, it is best to wait until the document is fully loaded before initializing those fields. ■ unload event The unload event fires when a browser is leaving the current document. This happens when the browser window is being closed or the user has moved on to another document. The main purpose of this event is to perform cleanup tasks before the document closes. The unload event is commonly used in some of the seedier web locations to provide final pop-up advertising before a user leaves a web site. This is generally considered bad etiquette. The unload event should be avoided unless absolutely necessary. ■ submit event The submit event occurs just before a form is submitted to a web server. It is common to capture this event to perform edit checking before allowing a form submission to continue. Since this event can be canceled, JavaScript can stop the form from being processed if everything is not in order. ■ reset event The reset event occurs when the reset button on a form is clicked. The reset button clears a form by resetting all the values back to their defaults.
  • 236. 216 How to Do Everything with JavaScript ■ select event The select event occurs when the user selects text inside a text box or text area. Text can be selected by holding the left mouse button down while dragging across the text or by holding the SHIFT key down while using the arrow keys to move the cursor across the text. ■ change event The change event occurs when a control loses focus (the user tabs out of it) and its value has been altered. This way, in text boxes the change event does not fire for each and every keystroke when a user is entering a value but only when the user leaves the field. This same event fires on radio buttons, check boxes, and select lists in the same manner. ■ abort event The abort event occurs when the browser stops trying to load an image on the web page. This can occur when the user hits the browser’s Stop button or clicks a link to go to another page. In my experience, this event is rarely used. ■ error event The error event occurs when an error happens while the web page is being loaded. This could be an error specific to a particular object (such as a Java applet’s failing to load) or a run-time error caused by poorly written JavaScript code. This is another event that is rarely captured in most web pages. ■ resize event The resize event fires when an object is being resized—for instance, if a browser window has been resized by the user, or a frame. There may be times when you would like to be able to resize the individual controls inside the window based on the available space, although capturing this event is still rare. ■ scroll event For web objects that scroll, such as the browser window or a text area form control, the scroll event is fired anytime the object’s scroll bar is changed. This can be done using the mouse to move the scroll bar manually, by using arrow keys, or by other means. The following code demonstrates how the load event can be captured using the onload event handler. Our web page contains a form, and the onload event handler code populates a list box on that form with some predefined values. <html> <head> <title>JavaScript Sample Web Page</title> <script language="JavaScript" type="text/javascript"> <!-- // Begin function initialize() { var lst = document.getElementById("samplelist"); var opn = new Array(20); var temp; var counter; for (counter = 1; counter <= 10; counter++) { opn[counter] = document.createElement("option"); lst.options.add(opn[counter]); temp = counter * 10; opn[counter].innerText = temp.toString();
  • 237. CHAPTER 9: Handle Browser Events 217 } } // End --> </script> </head> <body onload="initialize()"> <h1>Initialize a Form with onload</h1> <form action="#"> <select id="samplelist"></select> </form> </body> </html> In the preceding HTML code, the browser calls the JavaScript initialize() function as soon as it finishes loading into the browser window. This is done by programming the onload event handler in the <body> tag. Inside the initialize() function, the program adds 10 items to the empty <select> list box defined in the body of the web page. We can see the results of this function in Figure 9-4. 9 FIGURE 9-4 Ten items have been added to the drop-down list box.
  • 238. 218 How to Do Everything with JavaScript Handle Events Using the Event Property There are two ways to set the JavaScript event handler for an HTML tag: ■ Set the event handler property inside HTML ■ Set the event handler property inside JavaScript We have already seen how to set the event property in HTML: <img src="OriginalImg.gif" id="SampleImage" alt="Sample image" onmouseover="changeimage(1)" onmouseout="changeimage(2)" > In this code, we have set the JavaScript functions that will handle the mouseover and mouseout events using the corresponding event handlers. We could rewrite the code using JavaScript to set the event handlers: <img src="OriginalImg.gif" id="SampleImage" alt="Sample image"> <script type="text/javascript" language="javascript"> var img = document.getElementById("SampleImage"); img.onmouseover = changeimageover; img.onmouseout = changeimageout; function changeimageover() { img.src = "NewImg.gif"; } function changeimageout() { img.src = "OriginalImg.gif"; } </script> The HTML <img> tag has two attributes called onmouseover and onmouseout that can be set using HTML and JavaScript. Setting event attributes using JavaScript adds some flexibility, in that the JavaScript function used to handle the event can be changed dynamically, after the page has been displayed. But as you can see from the sample JavaScript code, you cannot pass parameters using this technique, so it is also less flexible in some respects.
  • 239. CHAPTER 9: Handle Browser Events 219 How Event Bubbling Works Let’s assume you have a web form that contains a push button. You have created JavaScript onclick event handlers for both the <form> tag and the <input type="button"> tag. When you click the push button control using the mouse, which onclick event handler do you think will be called—the one for the button or the one for the form? In fact, the browser will execute both event handlers. The onclick event handler for the button will be called first, since it is the innermost element. Next, the onclick event handler for the form will be called. If there are any other onclick event handlers eligible to handle this event (for instance, on the <body> tag), they will be called in turn as well. This process, where an event is first handled by the innermost element, followed by the next innermost element, and so on, is called event bubbling. Trigger Events in JavaScript There will be times when you would like to have your JavaScript program cause an event to 9 occur. This is called triggering the event, and many objects inside the web page provide methods you can call to trigger the event. There are two ways to cause an event to be triggered in JavaScript: ■ Call the method associated with the event ■ Call the fireEvent method to fire the event manually Call the Method Associated with an Event The first technique is to call the method associated with an event. Most events have a method that will simulate the activity that causes the event to fire. For instance, the HTML <form> object has a method called submit() that will attempt to submit the form, causing the submit event to fire. We can demonstrate this with the following HTML code. The code shows how to use a hyperlink to simulate a submit button. <script type="text/javascript" language="javascript"> function clickme() { document.forms[0].submit(); } </script> <form action="http://www.example.com/cgi-bin/entry.pl"
  • 240. 220 How to Do Everything with JavaScript method="get"> Please enter your full name: <br> <input type="text" name="fullname"><br> <a href="javascript:clickme()">Click here to <b>submit</b> the form</a> </form> When the user clicks the hyperlink inside the form, JavaScript calls the clickme() function. The clickme() function calls the submit() method on the form object, which causes the form to submit itself. The submit() method acts exactly as if the user clicked a submit button on the form, causing the submit event to fire. In IE, calling the submit() method will cause the form to submit, but will not call any submit event handlers attached to the form. If your <form> has an onsubmit attribute, you will have to call those JavaScript functions manually before calling the submit() method. Other events also have associated methods that cause the event to occur. For instance, the focus() method will cause a control to gain focus, while the blur() method will cause a control to lose focus. Similarly, there is a click() method that allows HTML objects to simulate being clicked with the mouse. Use the fireEvent Method The second technique is to call the fireEvent() method to trigger the event manually. In IE, fireEvent() is a method of most objects in the DOM, and it can be used to trigger events. For example, you can trigger the onclick event of a push button control in the following manner: var btn1 = document.forms[0].helpButton; btn1.fireEvent("onclick"); Unfortunately, this method is not very reliable. Although this technique is supposed to be able to trigger events on any object, I have found that it does not work for certain events or objects, such as the onsubmit event on a form object, or the onclick event on a submit button object. Given that it is not part of the official DOM standard and does not work in any browser other than IE, developers should be very careful when using this technique. Overcome Browser Incompatibility Browser events are a weak spot when it comes to cross-browser compatibility. Sure, HTML defined a small number of standard events, and the various DOM specifications (Levels 1 and 2) have taken events a step further. But browser manufacturers have added many more programmable events for JavaScript developers to use, as evidenced by the more than 50 events supported by both Netscape and IE. Some of the additional events are slight modifications of existing events. For instance, IE provides onbeforeactivate and onbeforeunload event handlers to allow programmers to capture
  • 241. CHAPTER 9: Handle Browser Events 221 the onactivate and onunload events before they fire. These additional events are cancelable, which means you can stop the activate or unload events from occurring, while the existing onactivate and onunload events fire after the event occurs, and therefore cannot be canceled. Other event handlers allow programmers access to events that are not specified by the standards: ■ onbeforeprint and onafterprint allow access to browser print events. ■ ondrag, ondragstart, and ondragend allow access to drag-and-drop events. ■ onmousewheel allows access to the mouse wheel movements. ■ oncut, oncopy, and onpaste allow access to copy-and-paste events. The problem is, of course, that these events are generally supported by only one browser and not another. They are also often supported only by newer versions and not by older browsers. Although having access to some of these interesting events might be tempting from a programmer’s point of view, you will have to take some of the precautions listed in Chapter 7 and use browser sniffing code before relying on these methods. Of course, one good thing about these proprietary events is that they will generally not cause the browser to crash if they are coded properly. For instance, the following code tries to capture the onpaste event on a text box control. <form action="#"> 9 <input type="text" name="myctl" onpaste="pasteevent()"> </form> Of course, since the onpaste event handler is being set inside the HTML element, the browser will simply ignore that code if it does not support the paste event on that control. The only consequence is that the paste event will not be captured in incompatible browsers. However, if you are absolutely relying on this event handler to perform some critical code, such as submitting the form, you will have to use browser sniffing code to provide alternate code for browsers that do not support it. In the next chapter, we will discuss browser frames. JavaScript programs face special challenges when dealing with a multiple-frame environment, and we will examine some of the issues and how best to work around them.
  • 242. This page intentionally left blank
  • 243. Communicate Chapter 10 Between Browser Frames
  • 244. 224 How to Do Everything with JavaScript How to... ■ Create a frameset ■ Define and name frames in a frameset ■ Call JavaScript functions from other frames ■ Handle synchronization between frames In web programming, a frameset is used to divide a single web page into two or more smaller pieces. Each of these pieces, or frames, is a separate HTML web page. Web developers can define several important properties for these frames, including the overall dimensions, location, and visibility of the borders. In this chapter, we will examine the use of framesets on the Internet today. In particular, we will see some the challenges faced by JavaScript programmers when using frames and look at some suggestions for overcoming them. Learn the Basics of HTML Frames Frames are extremely useful for displaying the static sections of a web site, such as menus, banners, and site-navigation tools. Since all the frames in a frameset are independent of each other, they provide several important benefits to web site developers and visitors. When used properly, frames can ■ Decrease the length of time required to navigate a web site ■ Make a web site easier and more intuitive for visitors to use ■ Make a web site easier for developers to maintain Figure 10-1 shows an example of a web page that uses frames. The figure contains three frames: a top frame with links to other areas of the site, a left frame that contains a menu, and a center frame (known as the main frame) that contains the key contents of the web site. As convenient as frames are for both web programmers and visitors, there are quite a few people who do not like them. A number of problems can be introduced when frames aren’t used properly: ■ Browser bookmarks can’t be properly set. ■ Web sites look awful at very small or very large monitor resolutions. ■ Search engines can’t accurately index the contents of a frameset. Adding to these problems is the increasing use of and browser support for Cascading Style Sheets (CSS). Style sheets can provide many of the same benefits as frames, including user-friendly navigation and even static banners and menus. Many popular web sites that once contained framesets now use DHTML menus and other more modern dynamic elements.
  • 245. CHAPTER 10: Communicate Between Browser Frames 225 10 FIGURE 10-1 Example of a web site (ZVON.org) that contains frames Create a Frameset in HTML In HTML, frames are created using a combination of two tags: <frameset> and <frame>. The <frameset> tag is used to define the dimensions and positioning of the frames inside the frameset. The <frame> tag is used to define the properties of the individual frames, such as the source HTML document, and the visibility of the frames borders. The <frameset> element has the following attributes: ■ id String that must be unique across the entire web page ■ class List of associated CSS classes ■ style Inline CSS style commands ■ title Advisory title ■ lang ISO language code ■ dir Direction of text (right to left or left to right) ■ rows A comma-separated list of row heights ■ cols A comma-separated list of column widths
  • 246. 226 How to Do Everything with JavaScript The <frameset> tag also supports the onload and onunload event handlers. The web page shown in Figure 10-1 consists of four separate HTML files. One HTML file contains the frameset layout—typically only a <head> section and the <frameset> and <frame> tags. The other three HTML files contain the individual contents of each of the three frames— each HTML file in this example relates to exactly one frame. Of course, this is not always true. More than one frame can relate to the same HTML file, and some frames can be dynamically generated using JavaScript, and so will have no file associated with them. The only way to tell is by looking at the code. The following code is a complete example of a frameset document. <html> <head> <title>Framesets</title> </head> <frameset rows="100, *"> <frame src="banner.html" name="banner"> <frameset cols="150, *"> <frame src="menu.html" name="menu"> <frame src="mainbody.html" name="bodyframe"> </frameset> </frameset> </html> The preceding HTML code defines a frameset with three frames. It uses a technique discussed later in this chapter, in the section entitled “Create Nested Framesets.” We can tell the number of frames in a document by counting the number of <frame> tags. Notice that the frameset document contains the usual <html>, <head>, and <title> tags, but it does not contain a <body> tag. This is because a frameset document cannot contain a <body> of its own—that is not allowed. We can, however, use all the valid contents of the <head> section, including JavaScript code, meta data, and style sheet definitions using the appropriate HTML tags. Handle Browsers That Do Not Support Frames Providing a site using frames may be convenient to many visitors to your site. The vast majority of web surfers today (more than 99 percent, by the latest estimates) have browsers capable of displaying frames. But there is still a small minority of web browsers that do not support them. Many early browsers, such as IE 2 for Windows or Netscape 2 for OS/2, do not. And other web-enabled devices, such as PDAs and mobile phones, often have difficulty rendering frames correctly. HTML provides the <noframes> tag to allow web developers to display content for users whose browsers do not support the <frameset> tag. Browsers that do support the tag will ignore the contents of any <noframes> sections.
  • 247. CHAPTER 10: Communicate Between Browser Frames 227 For instance, we can revise the HTML code we saw earlier to include a <noframes> tag; <html> <head> <title>Framesets</title> </head> <frameset rows="100, *"> <frame src="banner.html" name="banner"> <frameset cols="150, *"> <frame src="menu.html" name="menu"> <frame src="mainbody.html" name="bodyframe"> </frameset> <noframes> It appears you are using a browser that does not support frames. If you would like to view this site, you will need to upgrade your browser. I suggest either Netscape or IE. </noframes> </frameset> </html> According to the HTML 4.01 specification, the <noframes> tag must be contained inside 10 a <frameset> tag. Set Frame Size Values with the rows and cols Attributes As we saw earlier in the chapter, the size and positioning of frames inside the frameset are handled with the HTML <frameset> tag. The two main attributes of the <frameset> tag are rows and cols. The rows attribute is used to define the row heights of the horizontal frames of a frameset, and the cols attribute is used to define the column widths of the vertical frames. Each attribute accepts a list of one or more values, separated by commas. There are three ways to specify a size value in the rows and cols attributes: ■ Absolute size, in pixels ■ Relative size, as a percentage ■ A combination of absolute and relative sizes, using the asterisk symbol Both rows and cols are optional attributes. The default value for each is "100%"; this defines one frame that takes up all the available space in a browser window. Examples of the three types of size value and what they represent are shown in Table 10-1.
  • 248. 228 How to Do Everything with JavaScript Value Frame Size 250 250 screen or print pixels 25% 25 percent (1/4) of the total available screen or print pixels * An equal share of the available space, after the sizes of the other frames have been taken into account 3* An unequal share of the available space, after the sizes of the other frames have been taken into account TABLE 10-1 Examples of Size Values and How They Affect the Frameset The special asterisk value is explained in more detail later in this chapter, in the section entitled “Set Frame Size Values Using Both Absolute and Relative Values.” Both the rows and cols attributes accept one or more values, separated by commas. Each value you provide creates one frame inside the frameset. Set Frame Size Values Using Absolute Pixel Values HTML allows you to define the exact size of a frame, called its absolute size. The absolute size of a frame is set by specifying a positive integer value for the rows and/or cols attributes. For example, a frameset with two horizontal frames, one 200 pixels high and the other 280 pixels high, would be created with the following HTML code: <frameset rows="200, 280"> <!-- <frame> tags go here --> </frameset> Even absolute sizes are not always absolute. If the actual size of the browser window does not match the sum of the sizes of the frames, the browser will automatically resize the frames to fit into the available space. Of course, you’re not restricted to only two frames. You can set any number of frames in a frameset. The following code sample defines four horizontal frames: <frameset rows="200, 200, 400, 400"> <!-- <frame> tags go here --> </frameset> Although there is theoretically no maximum number of frames you can define in one frameset, for aesthetic reasons you might want to limit the number to three or four.
  • 249. CHAPTER 10: Communicate Between Browser Frames 229 Set Frame Size Values Using Relative Values There is another way to define the size of frames beside specifying their exact pixel measurements. Developers can specify the size as a percentage of total available space. This is called a relative size, because the size of the frame is based purely on the size of the browser window, which can vary between one computer and another. <frameset rows="50%, 50%"> <!-- <frame> tags go here --> </frameset> The preceding code will create two frames, each taking up 50 percent of the available vertical space in the browser window. In a window that is 480 pixels high, this would create two horizontal frames, each 240 pixels high. If the user’s browser window were taller than 480 pixels, the actual height of each frame in pixels would be adjusted to the proper relative size. Set Frame Size Values Using Both Absolute and Relative Values The third alternative is to combine the two approaches—to create some frames that are absolute in size and others with sizes relative to the available space. To create this useful effect, specify the absolute number of pixels for the fixed frames and use an asterisk (*) in place of the relative sizes. For example, if you wanted to make the first frame 200 pixels high and to let the second frame automatically resize to fit the rest of the window, you could use the asterisk (*) when setting the height: 10 <frameset rows="200, *"> <!-- <frame> tags go here --> </frameset> This results in a frameset that contains two frames, one 200 pixels high and the other which takes up all of the remaining vertical space. If you were to use the asterisk more than once, the web browser would automatically resize those frames equally to fill the available space after the fixed-height frames were taken into consideration. <frameset rows="200, 200, *, *"> <!-- <frame> tags go here --> </frameset> The <frameset> tag in the preceding code will create a frameset that contains four frames. The first two frames will each be 200 pixels high, for a total of 400 pixels. If the viewable area of the browser window is 480 pixels in height, the last two will split the remaining 80 pixels evenly, so they will each be 40 pixels high. And if the browser window’s height expands to 600 pixels, those two frames will have heights of 100 pixels each, since they will evenly split the 200 pixels left after the fixed-height frames are accounted for.
  • 250. 230 How to Do Everything with JavaScript There is also a way to instruct the browser to distribute available space unevenly when using asterisks, by providing an asterisk multiplier. An asterisk multiplier is a number that can optionally precede an asterisk, causing it to get more than an equal distribution of space. For instance, the following frameset defines four frames, two of which are automatically sized by the browser. But the remaining space will be allocated unequally. <frameset rows="200, 200, *, 3*"> <!-- <frame> tags go here --> </frameset> Prefixing the asterisk that defines the final frame with the number 3 will cause that frame to have a height that is three times that of the third frame. This means that the fourth frame will get three-quarters of the available space, while the third frame will only get one-quarter of the available space. So, if the browser window had a height of 800 pixels, the browser would split the remaining 400 pixels by assigning 100 pixels to the third frame and 300 pixels to the fourth frame. Define Horizontal Frames with Rows So far throughout this chapter, you have seen code like the following, which will create three horizontal frames. <frameset rows="80, 45, *"> <!-- <frame> tags go here --> <frame src="frame1.html"> <frame src="frame2.html"> <frame src="frame3.html"> </frameset> These are called horizontal frames because each frame spans the entire width of the browser window. Since we have used the rows attribute, horizontal lines separate the three frames in the preceding example. In Figure 10-2 you can see how these horizontal frames would look in a browser. Define Vertical Frames with Columns Defining a set of vertical frames is not much different than defining horizontal ones. The cols attribute of the <frameset> tag allows you to create frames that have a vertical border instead of a horizontal one. <frameset cols="165, *"> <!-- <frame> tags go here --> <frame src="frame1.html"> <frame src="frame2.html"> </frameset> The preceding HTML code will create a frameset that contains two frames. The first will have a width of 165 pixels, while the second will take up the remaining horizontal space in the browser window. Figure 10-3 shows how vertical frames look.
  • 251. CHAPTER 10: Communicate Between Browser Frames 231 FIGURE 10-2 An example of horizontal frames created using the rows attribute 10 FIGURE 10-3 Creating vertical frames using the cols attribute
  • 252. 232 How to Do Everything with JavaScript Define Frames with Rows and Columns Framesets need not be only horizontal or only vertical. Web developers can create framesets that contain both rows and columns, like a grid. This is done by specifying values for both the rows and cols attributes. For instance, to create a frameset that has three rows and two columns, you would use the following HTML code: <frameset rows="50, 100, *" cols="50%, 50%"> <!-- <frame> tags go here --> <frame src="frame1.html"> <frame src="frame2.html"> <frame src="frame3.html"> <frame src="frame4.html"> <frame src="frame5.html"> <frame src="frame6.html"> </frameset> The preceding code creates a frameset that contains six frames, arranged into three rows and two columns. Notice that the number of rows and columns does not have to be equal. Figure 10-4 shows how this complex frameset will look in a browser. FIGURE 10-4 A frameset with both rows and columns
  • 253. CHAPTER 10: Communicate Between Browser Frames 233 Create Nested Framesets Creating complex framesets using both the rows and cols attributes has its limitations. Specifically, the rows and columns are created in a grid pattern—all the columns in one row will be the same width, and all the rows will be the same height, as shown in Figure 10-4. It will always be a perfectly aligned grid, although the size of the cells in the grid can differ. What could you do if you wanted to create unequal rows and columns? How could you create a row that has only one column, but define several columns for the next row? The answer is nested framesets. A nested frameset is achieved by placing one or more framesets inside another, thus subdividing a single frame into smaller pieces. All nested framesets must begin with a single, outer frameset. <frameset rows="80, *"> <!-- <frame> tags go here --> <frame src="frame1.html"> <frame src="frame2.html"> </frameset> For instance, the preceding HTML code creates a simple frameset that contains two horizontal frames. Now let’s say we want to further subdivide the second frame into two columns. This can be done with a second frameset: 10 <frameset rows="80, *"> <!-- <frame> tags go here --> <frame src="frame1.html"> <frameset cols="150, *"> <frame src="frame2.html"> <frame src="frame3.html"> </frameset> </frameset> I have replaced the second frame in the original code with a second frameset. This nested frameset divides the second frame into two columns. You can see the effect of this type of frameset in Figure 10-5. Define and Name Frames in a Frameset Now that you understand how simple and complex framesets are created using the <frameset> tag, we should take a brief look at how the frames themselves are defined. Individual frames are defined using the <frame> tag. The <frame> tag has the following attributes: ■ id Documentwide unique ID ■ class List of associated CSS classes ■ style Inline CSS style commands
  • 254. 234 How to Do Everything with JavaScript ■ title Advisory title ■ longdesc Link to a longer description of the frame ■ name Internal name of the frame ■ src URI to the HTML document ■ frameborder Visibility of the frame borders ■ marginwidth Amount of space, in pixels, between the vertical border (or window frame) and the HTML contents ■ marginheight Amount of space, in pixels, between the horizontal border (or window frame) and the HTML contents ■ noresize Controls whether the user can resize the frame ■ scrolling Visibility of the scroll bar All of the preceding attributes are optional. However, the <frame> tag is rarely defined without an explicit src attribute. This is the attribute that allows you to specify the source HTML file for the frame. FIGURE 10-5 Using a nested frameset to subdivide frames into unequal pieces
  • 255. CHAPTER 10: Communicate Between Browser Frames 235 When using JavaScript in conjunction with frames, it is often handy to use the name attribute to assign a unique name to the frame. <frame src="/dir/subdir/myframe.html" name="frame1"> The frame’s source can be any valid URI—it does not even have to exist on the same web server as the other frames. <frame src="http://www.cnn.com/" name="frame1"> Using the contents of another web site inside your own site is known as web site framing, and that practice has some potential legal ramifications involving trademark and copyright law. There is a very good article on the topic at http://www.gigalaw.com/ articles/2000-all/kubiszyn-2000-04-all.html that you should read if you are interested in framing another web site without the owner’s permission. The default frame is created with resizable borders. You can easily create borders that cannot be resized by specifying the noresize attribute. <frame src="myframe.html" name="frame1" noresize> The noresize attribute does not need to have a value assigned to it—its presence inside a <frame> tag signifies a fixed border. In XHTML, the XML-compliant version of HTML, every attribute must be assigned 10 a value. In XHTML, you would assign noresize the value of its own name, such as noresize="noresize". By default, frames have visible borders separating one frame from the next. However, this is not always desirable, since these borders do not always match the style of a site. Fortunately, it is fairly easy to make the borders invisible, making the individual frames less noticeable. <frame src="myframe.html" name="frame1" noresize frameborder="0"> Of course, you will need to add this frameborder attribute to each of the frame tags in a frameset to remove all borders. Call JavaScript Functions from Other Frames As discussed in the first section of this chapter, a web page made up of three frames actually consists of four separate HTML files—one file for each of the frames and one master file for the frameset. These frames are independent of each other, but they are not ignorant of each other. It is possible for each frame to access the contents of any other frame, including any JavaScript variables and functions defined there.
  • 256. 236 How to Do Everything with JavaScript Access Another Frame Using JavaScript As discussed in Chapter 8, we can use the following JavaScript code to access the contents of a form: var myform = document.forms[0]; var fullname = myform.fullname.value; This code will create a variable named myform, which directly refers to the first form on a web page. It will then use the myform variable to access a control named fullname and its contents. But how would we access the contents of that form if it were in another frame? Let’s assume for a minute that we have a frameset that is defined with the following HTML code. <html> <head> <title>Framesets</title> </head> <frameset rows="100, *"> <frame src="banner.html" name="banner"> <frameset cols="150, *"> <frame src="menu.html" name="menu"> <frame src="mainbody.html" name="bodyframe"> </frameset> </frameset> </html> If we were in the second frame of that frameset (menu), how would we access the contents of a form contained in the third frame (bodyframe)? We do this by accessing the window object for the frameset. JavaScript provides several types of window objects for use in programs. The various JavaScript window objects, and their descriptions, are listed in Table 10-2. The window object and the Document Object Model in general are discussed in greater detail in Chapter 11. Object Name Description window The current frame or window top The topmost window parent The frameset that contains the current frame (not always the topmost window) self The current frame or window; same as the window object TABLE 10-2 The JavaScript Window Objects
  • 257. CHAPTER 10: Communicate Between Browser Frames 237 Each of the window objects listed in Table 10-2 contains an array named frames. When a window object refers to an entire frameset, that object’s frames array contains one element for each of the frames contained in the document. When a window object refers to a single frame, this array will normally be empty. Of course, if the individual frames are also framesets, the frames array will not be empty. To access the contents of the bodyframe frame from JavaScript code inside the menu frame, we start with the topmost window, using the top object. We then access the third element (index 2, since arrays start at index 0) in that array. var bodyframe = top.frames[2]; The bodyframe variable represents a reference to the third frame defined in our frameset. We can then access the document contained by that window using the document object from that frame. var bodyframe = top.frames[2]; var bodydocument = bodyframe.document; Finally, we can access the form, and the elements on that form, in the usual manner from the document object represented by bodydocument. var bodyframe = top.frames[2]; var bodydocument = bodyframe.document; var myform = bodydocument.forms[0]; var fullname = myform.fullname.value; 10 This code is broken into four lines for manageability and easy reading. If a program needed to reference more than a few elements on that form, or other objects on the bodyframe frame, having a local variable that refers to that frame would be handy. To save some unnecessary keystrokes, the preceding code can be written all on one line, like this. var fullname = top.frames[2].document.forms[0].fullname.value; This code is harder for the average programmer to read, however, and is slightly more confusing. Code that is difficult to understand can often be a source of errors. Instead of using the frames array, a frame can also be accessed by name. var fullname = top.bodyframe.document.forms[0].fullname.value; Accessing the frame by name makes the code a bit easier to read and allows frames to be resorted without large code changes. Call a JavaScript Function Located in Another Frame You’ve already seen how the contents of a frame (its forms and other HTML components) can be accessed from external frames, so it should be no surprise that JavaScript variables and functions can be accessed externally as well.
  • 258. 238 How to Do Everything with JavaScript To demonstrate, let’s assume we have a JavaScript function named sayhello() defined in the menu frame. function sayhello() { // This function says "hello" to the user alert("Hello!"); } We could define a button in the bodyframe frame that will call the sayhello() function from the menu frame when clicked. <form action="#"> <input type="button" value="Say Hello" onclick="top.menu.sayhello()"> </form> Figure 10-6 shows the result of clicking the Say Hello button in the browser window. As long as JavaScript variables are defined outside of any function, they too can be accessed from another frame. FIGURE 10-6 Calling a JavaScript function defined in another frame
  • 259. CHAPTER 10: Communicate Between Browser Frames 239 Cross-Frame Scripting Can Be Risky Cross-frame scripting occurs when a frame that originates in one domain (like www.myserver.com) attempts to access a frame that originates in a different domain (like www.example.com) using JavaScript. The problem with cross-frame scripting is that a web site could define a frame that points to a secure web site, such as Microsoft’s Hotmail. The originating web site could then access any cookies or other sensitive user information from the frame, allowing them to use that information in a malicious manner. Because this a security risk, all IE browsers from version 4 on do not allow cross-frame scripting. Handle Synchronization Between Frames In the last section, we saw some JavaScript code that relied on the existence of a JavaScript function in another frame. <form action="#"> <input type="button" value="Say Hello" 10 onclick="top.menu.sayhello()"> </form> But what happens if the user clicks the button before the menu frame has even finished loading? Most web browsers load frames in no particular order, and it is quite possible (actually, quite probable) that some frames will load slower than others. In this case, a JavaScript error will occur, since the sayhello() function could not be found. This problem can be described as one of synchronization. When dealing with frames that communicate with each other, we need a way to determine if all the frames are fully loaded before proceeding. There are several techniques a JavaScript programmer can employ to handle synchronization between frames. The first technique is to create a cascading effect between the frames, where each frame is responsible for loading the frames that depend on it. Using this method, we would have the menu frame load the contents of the bodyframe frame. top.bodyframe.document.location = "mainbody.html"; We could then be guaranteed that the menu frame has already loaded in the browser window by the time the bodyframe document has finished loading as well. The second technique is to create one or more Boolean JavaScript variables in the frameset document. Each of the frames can set its respective Boolean variable to true when
  • 260. 240 How to Do Everything with JavaScript it has completely loaded. For example, we can modify our frameset document to the following HTML and JavaScript code: <html> <head> <title>Framesets</title> <script type="text/javascript" language="JavaScript"> var banner_loaded = false; var menu_loaded = false; var body_loaded = false; </script> </head> <frameset rows="100, *"> <frame src="banner.html" name="banner"> <frameset cols="150, *"> <frame src="menu.html" name="menu"> <frame src="mainbody.html" name="bodyframe"> </frameset> </frameset> </html> We can then add the following JavaScript code to the end of the menu frame in order to set the appropriate variable to true. <script type="text/javascript" language="JavaScript"> var menu_loaded = true; </script> Inside the code for the bodyframe, we should move the call to the sayhello() function into a separate function, and add an if statement around it for safety. <script type="text/javascript" language="JavaScript"> function callhello() { // Check the variable named menu_loaded first if (top.menu_loaded == true) { top.menu.sayhello(); } } </script> <form action="#"> <input type="button" value="Say Hello" onclick="callhello()"> </form> In this example, the Say Hello button will not work until the menu frame has completely loaded.
  • 261. CHAPTER 10: Communicate Between Browser Frames 241 Lastly, we could use a technique similar to the DOM-based browser sniffing code from Chapter 7. We could simply test for the existence of the frame and the sayhello() function before accessing them. <script type="text/javascript" language="JavaScript"> function callhello() { // Check if the frame and function exist first if (top.menu) { if (top.menu.sayhello) { top.menu.sayhello(); } } } </script> <form action="#"> <input type="button" value="Say Hello" onclick="callhello()"> </form> This same technique can be used to test for the existence of JavaScript variables or web form controls. In the next chapter, we will investigate the various objects that make up the DOM. It is through the methods and properties of these objects that we are able to interact with the web browser. 10
  • 262. This page intentionally left blank
  • 263. Interact with the Chapter 11 Web Browser
  • 264. 244 How to Do Everything with JavaScript How to... ■ Manipulate the contents of a web page ■ Examine the entire browser window ■ Retrieve properties from the web browser software ■ Examine the operating system’s display settings ■ Access the web browser history list ■ Send the browser to a new location Although JavaScript has a powerful yet flexible core language syntax, it doesn’t have any built-in functions for reading data from file, database, or keyboard input, nor for writing data to a screen or printer. In each of its environments, JavaScript relies on an external object model to provide it basic input-output functionality. Table 11-1 lists some of the environments that provide support for JavaScript (or some version of it), and the object model that provides additional functionality beyond the core JavaScript functions. The object model used by web browsers is called the Document Object Model, or DOM for short. The DOM is a standard API (application programming interface) to the structure of documents. It allows JavaScript developers easy access to the document contents (such as forms, text, and style) as well as to browser-specific features (such as menus, scroll bars, and events). The DOM has evolved since the first browser was introduced many years ago, but the basic objects in a browser have not changed. The DOM specification is managed by the W3C, along with the HTML and XML specifications. Recent releases of the DOM standard now include methods and properties related to browser events, manipulation of style sheets, document validation, and XPath expressions. Many of the extensions to the DOM standard will not be covered in this chapter, as they either do not relate directly to HTML or are too advanced for our purposes. If you are interested in learning more about the new DOM, I encourage you to check out the specifications and other documents located on the W3C DOM web site: http://www.w3.org/DOM. JavaScript Environment Object Model Web browsers DOM .NET (JScript) .NET Framework ASP (JScript) ASP object model Server-side JavaScript Server-side extensions TABLE 11-1 JavaScript Environments and Their Respective Object Models
  • 265. CHAPTER 11: Interact with the Web Browser 245 Learn the Basics of the Document Object Model To understand the DOM, you must first understand how the specification has evolved. There were six basic objects in the original DOM, sometimes called DOM Level 0: ■ document ■ window ■ history ■ location ■ screen ■ navigator DOM 0 defines some other objects as well, such as forms, frames, and images. But to get to these objects, programs have to go through the top-level objects listed here. Objects could not be dynamically created, modified, or removed, since DOM 0 was static and the document could not be altered once rendered by the browser. Figure 11-1 is a good representation of the objects in the original DOM and how they related to each other. 11 FIGURE 11-1 The original Netscape DOM
  • 266. 246 How to Do Everything with JavaScript When the W3C adopted the DOM as a new web standard in 1998, it was called DOM Level 1, which is sometimes abbreviated to DOM 1. DOM 1 was the first attempt to adapt the object model for the emerging XML standard, which was set to revolutionize structured document formatting. Unlike subsequent versions of the DOM, DOM Level 0 was never an official standard. The DOM standard treats HTML (and XML) documents as hierarchies of data (called nodes). In DOM, the following parts of the document are all considered nodes: ■ Markup tags (elements) ■ Attributes ■ Text ■ XML character data (CDATA) sections ■ Entity references ■ Entities ■ Processing instructions ■ Comments ■ The document itself Nodes that are contained in other nodes are considered children of those nodes, while nodes that are at the same level as other nodes are considered siblings. DOM 1 allows programmers to access, add, delete, move, or modify almost any of the objects in the DOM tree. More specifically, DOM 1 separates a core set of API from an HTML-specific set. The HTML-specific API adds browser-related methods and properties to the objects defined in the core set. For example, let’s consider the following simple HTML code: <html> <head><title>My title</title></head> <body> This is <b>a test</b> of the <i>emergency broadcast system</i>. I repeat, this is only a test. </body> </html> Figure 11-2 shows how the preceding HTML code would look in a DOM 1 hierarchy. This hierarchy is also called the DOM tree. The next version of the DOM, known as Level 2, became an official W3C standard in November 2000. The core standard did not change much from the previous release, as DOM 2 only added a few new properties and methods to the interfaces already defined in DOM 1. Its
  • 267. CHAPTER 11: Interact with the Web Browser 247 FIGURE 11-2 How a simple HTML document would look in a DOM tree main purpose was to add support for views, events, and style sheets to the DOM API. It also defined a specification for DOM traversal, the ability to move forward and backward through a DOM hierarchy. DOM Level 3 was still in the W3C Working Draft stage at the time this book was published. 11 DOM 3 proposes to add two new interfaces to the core specification and will also add support for XPath. The Uses of XPath XPath is a simple yet powerful language for addressing parts of an XML document. For instance, you would use the following XPath expression to access the first <form> element on an XHTML web page. /html/body//form[1] This expression will match the first <form> element that is a descendant (but not necessarily a direct child) of a <body> element, which is itself the direct child of the root <html> element.
  • 268. 248 How to Do Everything with JavaScript The remainder of this chapter focuses on JavaScript programming for DOM 1, since the vast majority of browsers in use today support that version. Manipulate the Contents of a Web Page Perhaps the most useful of all the DOM objects is the document object. The document object provides access to the entire contents of a web page, as it is the root of all other objects in the HTML hierarchy. In Figure 11-2, the document object stands in place of the <html> element, at the top of the tree. The document object contains the following five arrays in JavaScript: ■ images ■ applets ■ links ■ forms ■ anchors Each of the document object’s arrays contains an enumerated list of the related elements on a web page. The images array contains a list of images, the applets array contains a list of Java applets, and so on. We have already seen how the forms array is a convenient way of accessing all the HTML <form> elements on a web page. In addition to the five arrays, the document object also provides JavaScript read and write access to any cookies associated with a web site (through the document.cookie property). A cookie is a piece of text a browser will store locally on behalf of a web site. Cookies are frequently used to store user ID and session information, so that a web site will be able to recognize known users when they return. The document object also contains the following six methods: ■ open() ■ close() ■ write() ■ writeln() ■ getElementById() ■ getElementsByName() The open(), close(), write(), and writeln() methods are used for printing raw HTML text to a web page. I have often used document.write() in this book’s sample code as a simple way of outputting results. The getElementById() and getElementsByName() methods allow us to quickly search a DOM for specific elements. This is a better approach than manually searching up and down the DOM tree for what we need, since these functions are optimized to return quickly.
  • 269. CHAPTER 11: Interact with the Web Browser 249 Should we wish to navigate the contents of the HTML document without the convenience of the various arrays (like the forms array) or the built-in search functionality (like getElementById), we can access the body property of the document object directly. The body property allows us to access all the HTML objects below the document object, starting from the HTML <body> element. This property is not typically used in JavaScript programming, as searching the DOM using the document arrays or using the built-in search functions is generally quicker and easier. Dynamically Modify the Contents of a Web Page One of the more interesting ways to use JavaScript and the DOM together is for creating web pages that can change themselves according to the user’s behavior. This can be done without having to get the web server itself involved. Let’s start by looking at a very basic web page. <html> <head><title>Basic Web Page</title></head> <body> <h2>The time now is: <span id="time">00:00:00</span></h2> </body> </html> As you can see in Figure 11-3, this HTML code creates a static web page. No matter what time of day, it will always report the time as 00:00:00 (midnight). 11 FIGURE 11-3 A simple web page, before adding JavaScript
  • 270. 250 How to Do Everything with JavaScript But what if we wanted to add a small JavaScript script to the page that will constantly keep the time updated to the correct time? We can use the DOM document object to modify the contents of the web page. <script language="JavaScript" type="text/javascript"> function update_time() { // The current date and time var rightnow = new Date(); // Capture the hours as a string, "00" thru "23" var hours = rightnow.getHours(); if (hours < 10) var hourstring = "0" + hours.toString(); else var hourstring = hours.toString(); // Capture the minutes as a string, "00" thru "59" var minutes = rightnow.getMinutes(); if (minutes < 10) var minutestring = "0" + minutes.toString(); else var minutestring = minutes.toString(); // Capture the seconds as a string, "00" thru "59" var seconds = rightnow.getSeconds(); if (seconds < 10) var secondstring = "0" + seconds.toString(); else var secondstring = seconds.toString(); // Put it all together, "00:00:00" var timestring = hourstring + ":" + minutestring + ":" + secondstring; // Manipulate the DOM, display it to the screen! var timeplace = document.getElementById("time"); timeplace.childNodes[0].nodeValue = timestring; } </script> By calling the update_time() function when the document first loads, we can get the browser to update the string "00:00:00" with the current time. <body onload="update_time()"> The screenshot in Figure 11-4 shows how the browser has replaced the original HTML string with the correct time.
  • 271. CHAPTER 11: Interact with the Web Browser 251 FIGURE 11-4 Using the document object to update the web page with the correct time Using browser timers, we can even get our web page to update with the correct time every 11 second. All we need to do is add the following code to the end of our update_time() function. setTimeout('update_time()', 1000); The setTimeout() function tells JavaScript that we would like to execute certain JavaScript code at a certain time in the future. In the preceding code, we are saying that we would like to call the function update_time() 1,000 milliseconds (1 second) from now. This will cause the update_time() function to be called once per second until the user leaves the web page. Change the Items in a Drop-Down List Box Not only can developers modify the contents of an HTML web page, even the items in a drop-down list box can change after the web page has loaded. How many calories does a cheeseburger contain?<br> <select id="listbox1"> <option>-- Please Select One --</option> </select> <script language="JavaScript" type="text/javascript">
  • 272. 252 How to Do Everything with JavaScript var counter; var listbox = document.getElementById("listbox1"); for (counter = 100; counter < 500; counter += 50) { listbox.options[listbox.length] = new Option(counter + " - " + (counter+49)); } </script> The preceding code creates an HTML drop-down list box with one item in it—“Please Select One.” Using JavaScript, it then adds eight more items to the list. Our JavaScript code starts by getting a reference to the list box and storing it in the variable named listbox. Using a for loop, we then create several new Option objects and add them to the end of the options array. You can see how the browser displays our dynamic list box here. (I do not, however, care to know how many calories a cheeseburger actually does contain.) Examine the Entire Browser Window The window object is not technically an official DOM Level 1 object. It provides access to other frames or open browser windows. In the last chapter, we discovered that there are four types of window objects in JavaScript. Table 11-2 summarizes those objects.
  • 273. CHAPTER 11: Interact with the Web Browser 253 Object Name Description window Current frame or window top Topmost window parent Frameset that contains the current frame (not always the topmost window) self Current frame or window; same as the window object TABLE 11-2 JavaScript Window Objects The four window objects may (or may not) point to different windows in the browser. Typically, for a web page that does not contain framesets, all four objects refer to the same underlying window. The window object provides access to three underlying DOM objects: ■ document ■ history ■ location We discussed document in the last section, and we will have a chance to look at history and location in the sections that follow this one. The window object also provides access to the browser status bar, using the status property. The status bar is the thin area below the main browser window that usually reports on the progress of a page load and shows the URL of a hypertext link when the mouse pointer moves 11 over it. The following JavaScript code modifies the browser status bar to a custom value: window.status = "Welcome to my web site!"; The following screenshot shows how this affects the status bar after our web page has loaded. In the last chapter you also learned that the window object contains an array named frames that enumerates all the frames in a frameset. It is through the frames array that we can access the HTML and JavaScript code located in another frame. The window object also provides several methods that can be used to communicate with the user or to open and close new browser windows. Table 11-3 lists some of the more interesting window methods.
  • 274. 254 How to Do Everything with JavaScript Method Description alert() Creates an alert dialog box blur() Causes the window to lose focus close() Attempts to close the browser window focus() Causes the window to gain focus moveBy(), moveTo() Repositions the browser window navigate() Loads a specific URL into the browser open() Opens a new browser window print() Attempts to print the browser contents to a printer resizeBy(), resizeTo() Resizes the browser window scroll(), scrollBy(), scrollTo() Causes the window to scroll setTimeout(), clearTimeout() Causes JavaScript code to be executed after a specified delay TABLE 11-3 Useful window Methods One interesting window method is open(). This method is used to create a new browser window when you do not wish to interrupt the current web page. Sadly, this is the technique used for most pop-up web advertisements. It is still quite useful, however, when you want to direct the user at their request to some online help, such as a user manual or online glossary. window.open("userhelp.htm", "_blank", "height=300,width=200,toolbar=no," + "status=no,menubar=no,location=no"); The preceding code will open a new browser window and direct it to the HTML file userhelp.htm. The code specifies a specific height and width for the window (300 by 200) and removes all toolbars, menu bars, and the status bar, leaving a sparse window. Figure 11-5 shows how this new HTML window will look in a typical web browser. Retrieve Properties of the Web Browser Software The programmers at Netscape probably still get some joy over the fact that the standard object for retrieving browser information is called navigator, named after what used to be the most widely used browser in the early days of the Web. You might recall that we talked about some of the properties of the navigator object in Chapter 7, when it was used to retrieve the name and version information from the user’s browser. The navigator object contains one array, called plugins. This array contains a list of browser plug-ins (although the contents of the list vary by browser maker). A browser plug-in is an application that runs inside the browser, usually to provide support for embedded multimedia. Shockwave Flash and RealNetworks RealPlayer are two popular plug-ins. In Netscape and Mozilla web browsers, the plugins array can be used to determine which browser plug-ins have been installed on the client PC. In Internet Explorer, the only plug-ins listed in the plugins array are the ones currently in use on the web page.
  • 275. CHAPTER 11: Interact with the Web Browser 255 FIGURE 11-5 A pop-up window can be used to provide quick online help. For example, the following code, for Netscape web browsers, checks to see if the Macromedia Flash plug-in is installed on the user’s computer. var flashinstalled = false; for (var i=0; i < navigator.plugins.length; i++) { 11 if (navigator.plugins[i].name == "Shockwave Flash") { flashinstalled = true; break; } } if (flashinstalled) { document.write ("I see you have Macromedia Flash installed!"); } else { document.write ("If you want to see the multimedia installed "); document.write ("on this web site, you will need to install "); document.write ("Macromedia Flash."); } The navigator object also supports several properties, such as the following. ■ appCodeName ■ appName ■ appVersion
  • 276. 256 How to Do Everything with JavaScript ■ userAgent ■ userLanguage These properties provide JavaScript with some important information about the exact browser type running on the client machine. For instance, you may wish to provide content formatted in a simpler manner for older browsers (version 4) and content that relies on style sheets for visitors using a newer browser. Examine the Operating System’s Display Settings Web programmers often develop web pages with a specific screen size in mind. For instance, some sites are developed for screens that are 800 pixels wide by 600 pixels high (often called 800 by 600 resolution). If a user’s resolution is smaller, say 640 by 480, they will be unable to see parts of the page. If a user’s resolution is bigger, say 1024 by 768, the web page will have a lot of blank space. The best-designed sites are frequently developed to expand or contract based on available space. We have seen this with frames using relative sizing, and it can also be done with HTML tables. Both these solutions allow the browser to automatically resize components based on the amount of available screen space. (You may sometimes hear available screen space referred to as real estate.) But when dealing with Dynamic HTML, where elements are frequently placed in specific X and Y coordinates on the screen, it is helpful to have some information about the screen resolution. The DOM provides the screen object to give JavaScript a little more information about the technical properties of the user’s display. The screen object was not part of the original release of JavaScript. It was added in version 4 of the IE and Netscape browsers. The following table lists some of the properties of this object. Property Name Purpose availHeight Returns the height of the working area of the system screen, excluding the Windows taskbar availWidth Returns the width of the working area of the system screen, excluding the Windows taskbar colorDepth Returns the number of bits per pixel used for colors height Returns the vertical resolution of the screen width Returns the horizontal resolution of the screen For example, the following JavaScript code will allow you to resize and then center the browser window on the user’s monitor. var newTopLeftX = (screen.availWidth - 640) / 2.0; var newTopLeftY = (screen.availHeight - 480) / 2.0; window.resizeTo (640, 480); window.moveTo (newTopLeftX, newTopLeftY);
  • 277. CHAPTER 11: Interact with the Web Browser 257 The code uses the window.resize() function to resize the browser to 640 pixels wide by 480 pixels tall. It then uses a common centering technique to place the window perfectly in the center of the screen, regardless of the resolution setting of the user’s monitor. Access the Web Browser History List JavaScript has limited access to the browser history list through the history object. The browser history list is an ordered list of web pages you recently visited, and it is stored internally by your web browser. You access the browser history list every time you use the back and forward buttons of your web browser. Through the history object, JavaScript has the ability to send a browser back to the previous web page—or back by an arbitrary number of web pages. For example, the following JavaScript code will send the browser to the web page most recently visited before the current one. history.back(); Programmers can also tell the browser to go back by any number of pages, by specifying an integer to the history object’s go() method. The following code will send the browser back five pages. history.go(-5); The history object only has one property, length. The length property will return the number of items in the history list. The history object has three methods. 11 Method Name Purpose back() Go back one item in the history list; simulates the Back browser button. forward() Go forward one item in the history list; simulates the Forward browser button. go() Go back or forward the specified number of items in the history list; a positive number goes forward and a negative one goes back. The history object is often used as an easy way to direct the user back to the previous page. <html> <head><tile>User Login Script</title></head> <body> <h1>Error: Unable to Log In</h1> I'm sorry, the password you supplied was incorrect. Please use the Back button on your browser to try again, or <a href="javascript:history.back()">click here</a> to
  • 278. 258 How to Do Everything with JavaScript be automatically sent there. </body> </html> For security reasons, the history object does not provide JavaScript access to the names or URLs of the web pages you have visited. Send the Browser to a New Location The location object gives JavaScript access to the browser address bar. Specifically, programmers can determine the URL of the current page, reload the current page, or send the browser to a new URL. The location object has eight properties. Property Name Purpose href Gets or sets the entire URL as a string hash Gets or sets the portion of the URL after the hash sign (#) host Gets or sets the hostname and port number portion of the URL hostname Gets or sets the hostname portion of the URL pathname Gets or sets the filename or path of the web page port Gets or sets the port number portion of the URL protocol Gets or sets the web protocol name of the URL (e.g., HTTP) search Gets or sets the portion of the URL after the question mark (?) The location object also has three methods. Method Name Purpose assign Loads a new web page reload Reloads the existing web page replace Replaces the existing web page by loading a new web page The location object is commonly used to redirect the browser to a new web page. location.href = "http://www.example.com/another/page.html"; But it can also be used just to reload the current page, similar to a browser refresh action. location.reload(); In the next chapter, we will examine how to perform some simple animation using JavaScript, CSS, and Dynamic HTML. Using a technique known as absolute positioning, we will be able to place text and images anywhere we wish inside a web page.
  • 280. 260 How to Do Everything with JavaScript How to… ■ Format a web page using style sheets ■ Control text and image positioning ■ Modify styles using JavaScript ■ Perform basic animation using JavaScript In Chapter 11, you saw how the browser DOM can be manipulated using JavaScript to modify the HTML in a web page after it has already been loaded into the browser. This technique is often used for allowing JavaScript to respond to user events or input without having to go back to the web server to re-create the page. As you’ll see in this chapter, Cascading Style Sheets (CSS) allow developers to specify the exact layout and positioning of elements on the web page. Style sheets can be dynamically modified in JavaScript as well, allowing elements to be given a different appearance or even moved to a different position on the screen. Animation is often nothing more than the repeated manipulation of the DOM and/or style sheets using JavaScript. An animated butterfly can appear to flutter across the screen with nothing more than the repeated swapping of a small number of images combined with the slow repositioning of those images across the page. In this chapter, we will examine how style sheets can be dynamically modified using JavaScript and how that technique can be used to create some simple animation effects. Learn the Basics of Cascading Style Sheets We have touched briefly on the topic of style sheets before, but in this section we will examine it in more detail to gain a better understanding of what style sheets can do for web developers and how JavaScript can be used to dynamically affect style. The style of a web page is the manner in which the contents of the web page, such as the text and graphics, are formatted and arranged. Style encompasses everything from how fonts and colors are used to the sizes and positioning of objects inside the browser window. When the Web was first developed in 1991, very little consideration was given to style— the emphasis was on content. The Web was used for the presentation and linking of related text documents. In fact, one of the overriding philosophies of its design was that web clients (generally browsers) should be responsible for rendering the web page in the manner they best saw fit. For instance, the <h1> tag simply defined a first level heading, and it was up to the browser to define the exact font type and size used for displaying the heading text. The content of <h1> tags could theoretically look completely different depending on the brand of browser you were using or the operating system you were running. Of course, many developers needed more precise methods to format the contents of a web page, so some pretty elaborate schemes were sometimes used to provide a complex page layout, such as the use of invisible images to help solve spacing problems.
  • 281. CHAPTER 12: Perform Simple Animation 261 Why CSS Are “Cascading” We say that style sheets cascade because, aside from a few exceptions, HTML elements inherit the style attributes of the elements they’re contained in. For example, assume you have an HTML <b> element that is inside a <u> element: <u>This is <b>some</b> text.</u> If you were to set the CSS font attribute of the <u> element, the <b> element would inherit that font setting as well. You can, however, override the cascading effect by assigning a different font setting to the <b> element. The W3C introduced the CSS Level 1 standard in late 1996. IE 3 was the first browser to include partial support for this new standard, and Netscape 4 soon followed with some partial (albeit extremely buggy) support for CSS as well. A style sheet is a group of definitions that describe the style for a set of HTML elements. Using style sheets, you can completely redefine the way a certain element is rendered inside the web browser, as each element exposes a number of attributes whose value can be changed. The W3C has a very good web site for learning more about style sheets; go to http://www.w3.org/Style. Assign Style to Web Pages Using HTML Elements 12 The original method of formatting the contents of a web page was by using HTML style-related elements and attributes. For instance, the <font> tag could be used to set the typeface, size, or color for text inside a document. The <b> tag could be used to make text bold, <i> would create italics, and so on. However, this was a very inefficient method for styling a web page, for a number of reasons: ■ The style and layout of a web page could not be easily reused between two or more HTML files, which created extra development work for web page authors. ■ Frames, nested tables, invisible images, and other complex and messy techniques needed to be used to place text or graphics in a particular spot. ■ Duplicate HTML style tags, such as the <font> tag, needed to be repeated many times on the same web page. ■ It was a lot of work to change the style of a web page or of an entire site. ■ Web pages were larger, which meant it took longer for them to download to browsers.
  • 282. 262 How to Do Everything with JavaScript How to Specify Colors in HTML There are several places in HTML, CSS, and JavaScript that require a programmer to specify a color. For instance, the HTML <font> tag has a color attribute with which you can specify the font’s color. Colors can be specified by name or by RGB (red-green-blue) value. Several colors have predefined names in HTML, such as black, white, yellow, and blue. There are dozens of predefined colors. If you would like to use a color that does not already have a name, you can specify an exact RGB value. RGB values start with the pound symbol (#) followed by three pairs of hexadecimal digits, such as #FF33C0. The first pair of hexadecimal digits represents the amount of red in a color, ranging from a value of 00 (darkest) to FF (brightest)— that’s 256 unique settings for red. The second pair represents the amount of green, while the third pair represents the amount of blue. So the color #FF33C0 represents a combination of bright red, dark green, and medium blue, which comes out looking a lot like fuchsia (a bright purplish-pink color). #FFFFFF represents pure white, and #000000 represents pure black. For example, the following HTML code defines a page with a moderately complex style. The HTML code is messy and difficult to read due to all the extra HTML tags and attributes that are required. <html> <head><title>Style sheets example</title></head> <body bgcolor="white" link="purple" vlink="green"> <center> <h1> <font color="#333399" face="Arial"> Introduction to XML </font> </h1> </center> <p><font color="#993333" face="Arial" size="3"> &nbsp;&nbsp;&nbsp;&nbsp;<b>XML is one of the most important new standards to come out of the W3C<br> &nbsp;&nbsp;&nbsp;&nbsp;since HTML.</b> All developers
  • 283. CHAPTER 12: Perform Simple Animation 263 should be aware of what XML is and how it<br> &nbsp;&nbsp;&nbsp;&nbsp;should be used. In this article, we introduce the basics of XML, including a<br> &nbsp;&nbsp;&nbsp;&nbsp;discussion on DTDs.</font></p> </body> </html> The preceding code includes a number of formatting tags such as <center>, <font>, and <b>. There are also a number of nonbreaking spaces (&nbsp;) to help indent the paragraph, and the <body> tag contains three style-related attributes. I also had to add manual line breaks (<br>) to artificially set the spot where the text wraps to the next line. Figure 12-1 shows how the browser is able to render a well-styled page from our sample HTML code. 12 FIGURE 12-1 The traditional method of formatting a page using HTML style tags
  • 284. 264 How to Do Everything with JavaScript Assign Style to Web Pages Using Style Sheets Of course, we can create the same effect shown in Figure 12-1 using style sheets. The style sheet solution, however, will be neater, easier to develop, and simpler to maintain in the future. We can even share this style definition with any number of other web pages, saving us valuable development time. We can also do some pretty cool things this way that HTML style tags just cannot do. First, we will take our web page example and remove the HTML style tags and attributes from it. We will use HTML <div> tags instead to mark the text that needs to be styled. <html> <head><title>Style sheets example</title></head> <body> <div id="heading"> Introduction to XML </div> <div id="summary"> <span id="boldintro"> XML is one of the most important new standards to come out of the W3C since HTML. </span> All developers should be aware of what XML is and how it should be used. In this article, we introduce the basics of XML, including a discussion on DTDs. </div> </body> </html> We can create a simple style sheet for this document, and insert it into the web page using the HTML <style> element. The <style> element belongs inside the <head> section of the document. <style type="text/css"> #heading { font: 24pt Arial; color: #333399; text-align: center; margin-bottom: 20pt; } #summary { font: 12pt Arial; color: #993333;
  • 285. CHAPTER 12: Perform Simple Animation 265 margin-left: 20pt; } #boldintro { font-weight: bold; } </style> We will examine the syntax of the style sheet itself later in the chapter. But even without knowing exactly what the style sheet means, you can see what it does. The resulting web page is almost identical to the one displayed in Figure 12-1, which was styled with traditional HTML, but the style sheet method is many times more flexible and powerful. Use <div> and <span> to Mark Dynamic Text HTML 4.01 provides two special elements to support the integration of CSS and HTML: <div> and <span>. The <div> element is a marker for text blocks. A text block is one or more complete paragraphs that must start and end on a new line. The <div> element makes it easier for a document to be styled using style sheets. <div id="FirstError">Error! You have entered an incorrect user ID and/or password. Please try again, and if you continue to have difficulty, please contact a system administrator for help.</div> The <span> element is very similar, except it deals with inline text. Inline text does not have to start or end on a new line, so <span> can be used for applying style to single characters, words, or sentences. 12 <span style="font-size:14pt">H</span>is main goal in life was <span style="font-weight:bold">world domination</span>, although tonight he was willing to settle for a nice steak and a cold beer. The primary attributes of <div> and <span> are id, style, and class. id allows you to specify a name for the enclosed text. This makes it easy to access the text using JavaScript or CSS. The style attribute allows you to specify CSS directly inside the HTML. The class attribute is similar to the id attribute, except several tags can have the same class attribute while the id attribute is unique to a single tag. Define Inline Styles The HTML standard allows CSS style syntax to be defined inside the body of the document using a technique called inline styles. Most HTML elements have an attribute called style that can accept CSS definitions, like so: <p style="font:Arial;font-weight:bold"> This is some text </p>
  • 286. 266 How to Do Everything with JavaScript Using this technique is quick and convenient, but you lose some of the benefits of using style sheets. Specifically, the body of the document remains complex, messy, and hard to maintain. The style sheet code is impossible to easily reuse. In fact, since the style is not separated from the content at all, this technique is equivalent to using HTML style tags and attributes. The one benefit you do get is the ability to use complex styles not available using the HTML style tag method. For small web pages or those with unique style requirements this might be an acceptable method. Define Embedded Style Sheets The next step up from inline styles is the use of embedded style sheets. An embedded style sheet is one defined using the HTML <style> tag inside the header section of the document. Styles defined in this manner are available to the entire web page, so it is entirely possible to define only one or two style definitions for a large and complex document. A style sheet is made up of one or more rules. A rule is a single definition for a style, in the following format: selector { attribute1 : value; attribute2 : value; … attributeN : value; } For example, in the previous section we had a style sheet with three rules. One of the rules was defined with the following code: #summary { font: 12pt Arial; color: #993333; margin-left: 20pt; } The rule has a selector (#summary) and defines values for three attributes (font, color, and margin-left). The selector determines which HTML tags have their attributes set to the specified values. By the way, the rule does not have to be spaced over several lines as I have been doing. You can place the rule all on one line, or break it up over several more lines to improve readability, if you wish. The following table shows how selectors work in CSS. Selector HTML Code Affected h1 Affects all <h1> tags in the document. #heading Affects the tag with an id attribute set to heading. .blue Affects all tags with a class attribute set to blue.
  • 287. CHAPTER 12: Perform Simple Animation 267 Selector HTML Code Affected p#heading Affects all <p> tags in the document with an id attribute set to heading. p.blue Affects all <p> tags in the document with a class attribute set to blue. h1, h2, h3 Affects all <h1>, <h2>, and <h3> tags in the document. pb Affects all <p> tags that are contained inside <p> tags; <b> tags not inside <p> tags are not affected. ul ul li Affects all <li> tags that are inside at least two <ul> tags. div .red Affects all tags with a class attribute set to red that are also inside a div attribute. As you can see, there are ways to set the style for the entire document all at once and ways to set the style of very specific elements within the document. You can ultimately create some very complex and comprehensive style sheets using sophisticated selectors. Import External Styles There are two ways to import a style sheet from an external file into an HTML document: ■ The HTML <link> element ■ The style sheet @import command This means that you can create a single style sheet file that can be applied to all the pages on a web site. And with a few simple keystrokes in a text editor, you can radically change the style of all the pages on your site at once. To use the <link> element, place the following HTML code in the <head> section of your web page: 12 <link rel="STYLESHEET" type="text/css" href="http://www.example.com/mystyle.css"> The preceding code will cause the style sheet which is located at http://www.example.com/ mystyle.css to be imported into the web page. The file extension .css is often used for style sheets. To import the same style sheet using the @import command, we actually need to add a <style> section to the document header. <style type="text/css"> @import url(http://www.example.com/mystyle.css); </style> All three types of style sheets (inline, embedded, and external) can be combined in a single document. If styles conflict, the inline styles have precedence, followed by the embedded styles, and lastly the external styles.
  • 288. 268 How to Do Everything with JavaScript Use Basic Style Attributes As mentioned in the “Define Embedded Style Sheets” section, a style sheet is made up one or more of rules, and rules are made up of a selector plus one or more attributes. In this section, we will look at the different types of attributes that can be used to set styles. There are literally dozens of attributes defined in the official CSS 1 specification—so many that I won’t even attempt to cover them all in this book. For more information on the available CSS attributes, I suggest the following two excellent sources: ■ The official W3C CSS 1 specification can be found at http://www.w3.org/TR/REC-CSS1. ■ The Microsoft MSDN web site has an excellent reference guide at http://msdn.microsoft.com/workshop/author/css/reference/css_ref_entry.asp. The MSDN reference guide is particularly well organized; CSS attributes are cross- referenced with their related HTML elements. In fact, I believe this web site to be the most complete web programming reference available on the Internet—not just for CSS, but for all web-related programming topics. Table 12-1 describes some of the most frequently used CSS attributes. Several of the attributes listed in Table 12-1 are compound attributes; that is, they allow you to set many properties of an element at once. For instance, the font attribute allows you to set up to 14 font-related properties in one string: BODY { font: italic normal bold 12pt Arial; } This convenient shortcut is equivalent to the following code: BODY { font-style: italic; font-variant: normal; font-weight: bold; font-size: 12pt; font-family: Arial; } So as you can see, compound attributes save time and effort but add additional complexity, in that they are more difficult to construct. Position Elements on a Web Page Some CSS attributes have nothing to do with text style and deal instead with layout and positioning. Setting the positioning of an element allows you to specify the exact size (height and width) of the object as well as its exact physical location (x and y coordinates) on the screen.
  • 289. CHAPTER 12: Perform Simple Animation 269 Attribute Name Purpose font Allows you to set up to a dozen font-related properties, including size and style color Allows you to set the foreground color of an element background Allows you to set up to five background-related properties, including color and image text-align Allows you to set left, center, or right alignment for text margin Allows you to set the size of the empty space around an element border Allows you to set the size, style, and color of the border around an element TABLE 12-1 Common CSS Attributes For example, let’s assume we have the following HTML code: <html> <head> <title>Style sheets example</title> <link rel="STYLESHEET" type="text/css" href="example.css"> </head> <body> <div id="special">This is a great example of separating content from layout. From an HTML perspective, this text is a pretty simple paragraph, with no formatting requirements. Browsers that do not support style sheets will render 12 this text to the screen in a plain and simple manner. </div> </body> </html> This HTML code contains no formatting instructions. All we have done is provide a paragraph of text surrounded by a <div> tag. The <div> tag does not do anything other than provide a way to name a block of text. (We examined the difference between <div> and <span> earlier in the chapter, in the “Use <div> and <span> to Mark Dynamic Text” section.) Our HTML code does, however, contain a <link> reference to a style sheet file. The file, example.css, will contain the formatting instructions we wish to use. In our case, it will define CSS positioning attributes. The example.css file will contain the following code: #special { position: absolute; top: 50px;
  • 290. 270 How to Do Everything with JavaScript left: 100px; width: 3in; background-color: #CCCCCC; padding: 15px; font: 12pt Arial; border: solid 2pt black; } The preceding style sheet contains four of the CSS size and positioning attributes: ■ position Tells the browser we wish to position the content ourselves ■ top Sets the position of the top edge of the element ■ left Sets the position of the left edge of the element ■ width Sets the width of the element In our case, the element is the <div> tag that surrounds our text. The <div> tag has an id attribute of special, which matches the #special selector assigned to the rule. There are a couple of additional positioning attributes that were not used, most notably height, which can be used to set the height of the element. In our case, we are allowing the browser to calculate the proper height for the element based on the size of the text contents. There is also an attribute named visibility, which can make an element invisible. Figure 12-2 shows how the text inside our HTML document has been positioned and sized exactly as specified in our style sheet. Modify Styles Using JavaScript Now that we have examined what style sheets are and how they can be used to format a web page, we can take a look at how JavaScript can be used to modify styles dynamically. The DOM provides JavaScript access to the style-related properties of almost any object on the page. For instance, assume we have a web form defined as follows: <form action="#" method="get"> <div style="position:absolute;top:50px;left:100px;"> Full Name:<br> <input type="text" name="fullname" id="fullname"><br><br> Email Address:<br> <input type="text" name="email" id="email"> </div> </form>
  • 291. CHAPTER 12: Perform Simple Animation 271 FIGURE 12-2 The browser has successfully interpreted our style sheet. 12 Our JavaScript program can access the text box control named fullname using the DOM and manipulate its style. var TextBoxes = document.getElementsByTagName("input"); for (var counter=0; counter < TextBoxes.length; counter++) { var myTextBox = TextBoxes[counter]; myTextBox.style.backgroundColor = "black"; myTextBox.style.color = "white"; myTextBox.style.font = "22pt Arial"; } The preceding JavaScript code will locate all the <input> elements on the page and alter their style properties. What we will end up with are two text boxes that have black backgrounds, white text, and a large, 22-point Arial font. You can see the results of this code in Figure 12-3.
  • 292. 272 How to Do Everything with JavaScript FIGURE 12-3 The styles have been altered dynamically using JavaScript. The names of the JavaScript properties are often different than the names of the corresponding CSS attributes. For instance, the CSS attribute background-color is set using the JavaScript property backgroundColor. Table 12-2 lists some of the CSS attribute names we have been using and the corresponding DOM style property names. As you can see, there is some consistency between the naming of CSS style attributes and the corresponding JavaScript DOM property, but occasionally the two names differ, so it is best to check whenever you are uncertain of the correct name. Understand Cross-Platform Issues CSS support used to be extremely inconsistent between the top two or three browser manufacturers. Today, the vast majority of browsers in use fully support CSS 1. Most browsers have at least partial support for the CSS 2 specification, and CSS 3 is currently under development.
  • 293. CHAPTER 12: Perform Simple Animation 273 CSS Attribute Corresponding DOM Property background background background-color backgroundColor border border border-bottom borderBottom border-left borderLeft border-right borderRight border-top borderTop color color font font font-family fontFamily font-size fontSize font-weight fontWeight margin margin margin-bottom marginBottom margin-left marginLeft margin-right marginRight margin-top marginTop text-align textAlign TABLE 12-2 The Relationship Between CSS and JavaScript DOM Styles 12 Internet Explorer was the first browser to contain support for style sheets, and Microsoft added several of their own attributes that were not part of the standard and do not work in other browsers. Obviously, if you want your style sheets to work in all browsers, stick to attributes and commands that are part of the official standard and avoid proprietary extensions. Netscape 4 contains a buggy, partial implementation of the CSS standard. It is quite difficult to get style sheets to work for that browser beyond a few basic attributes, so understand that a web page that relies heavily on style sheets might not look as intended in the Netscape 4 web browser. Fortunately, the market share for that browser has dipped below 3 percent, so the problem will eventually go away on its own. The W3C provides a CSS validator service. The CSS validator, located at http://jigsaw.w3.org/css-validator, will examine any HTML web page (or individual style sheet) you specify to ensure the style sheet is completely valid. The tool provides helpful feedback for finding out where problems lie, and so is very useful when developing CSS-enabled web pages.
  • 294. 274 How to Do Everything with JavaScript Perform Basic Animation Using JavaScript We have discussed how JavaScript can be used to change elements within the DOM as well as CSS style and positioning attributes. In this section, we will examine two of the most common techniques for creating animation on a web page using JavaScript. Dynamically Load Images The simplest type of animation in JavaScript is accomplished by just switching images. You see something similar to this all the time on the Web, where a graphical menu or button changes when your mouse moves over it. In fact, you saw an example of that effect in Chapter 9, in the discussion on mouse events: <script type="text/javascript" language="javascript"> function changeimage(num) { var img = document.getElementById("SampleImage"); if (num == 1) { img.src = "NewImg.gif"; } else { img.src = "OriginalImg.gif"; } } </script> <img src="OriginalImg.gif" id="SampleImage" alt="Sample image" onmouseover="changeimage(1)" onmouseout="changeimage(2)" > In the JavaScript function changeimage(), we used the document.getElementById() function to retrieve the image object defined in the body of the HTML document. Depending on the type of event (onmouseover or onmouseout), the src property of the image is pointed to a different file. Mouseover events are the shortest form of animation—sort of like a half-second movie. In order to create a longer effect, we need to do several rapid image switches in a row. For instance, let’s build a fairly simple animation effect that uses timer events: 1. Start with a set of related images that make up the animation.
  • 295. CHAPTER 12: Perform Simple Animation 275 2. Place the first image on a web page using the HTML <img> tag. Be sure to assign the <img> an id attribute. <img src="image1.gif" id="anim"> 3. Then create a JavaScript function called animate() that alternates between each of the three images at regular intervals, say every ¼ second. // The counter variable controls the animation var counter = 0; function animate() { var img = document.getElementById("anim"); // Proceed to the next image counter ++; // There are only four images, so restart when we're done if (counter > 3) counter = 0; if (counter == 0) { // Display the first image img.src = "image1.gif"; } else if (counter == 1) { // Display the second image img.src = "image2.gif"; } else if (counter == 2) { // Display the third image img.src = "image3.gif"; 12 } else { // Display the fourth image img.src = "image4.gif"; } // We need to call the animate function again in 0.10 seconds // Pause for 1 second between the fourth and first image if (counter == 3) { setTimeout("animate()", 1000); } else { setTimeout("animate()", 100); } }
  • 296. 276 How to Do Everything with JavaScript 4. We can start the animation by calling the function from within the <body> element’s onload event handler. <body onload = "animate()"> 5. The net result is that our graphic appears to be animated inside the browser window. Rapidly switching sequentially through the different graphics creates an animation that draws a circle in the browser window. Make Content Move Around the Screen The other way to perform basic animation is by moving an object around on the screen. We have already seen that JavaScript can access the CSS positioning attributes of any object on a page. It would be fairly easy, then, to use that same technique to create JavaScript animation. Let’s start with the image of a ball. The image is placed on a web page using the HTML <img> tag: <img src="ball.gif" id="ball" class="ballstyle"> <div class="boxstyle">&nbsp;</div> We should also create a style sheet for this page, so that the ball and box will start off with the correct style and positioning. <style type="text/css"> .ballstyle { position: absolute; top: 50px; left: 100px; } .boxstyle { position: absolute;
  • 297. CHAPTER 12: Perform Simple Animation 277 top: 50px; left: 100px; height: 250px; width: 400px; border: solid 1pt black; } </style> We will need a function, called moveball(), to animate the image by altering its top and left style attributes. // Set the starting coordinates var mytop, myleft; mytop = 50; myleft = 100; function moveball() { img = document.getElementById("ball"); mytop += 10; myleft += 2; if (mytop > 230) mytop = 50; if (myleft > 430) myleft = 100; img.style.top = mytop; img.style.left = myleft; 12 setTimeout("moveball()", 100); } We must start the ball moving by calling the moveball() function from within the onload event handler of the <body> element. As you can see in Figure 12-4, we have created a rather interesting effect. The image of the ball continues to move slowly down and to the right of the screen until it reaches the edge of the box. Once there, it switches back to the other side of the box and continues its motion. Text can also be animated using this same technique. Instead of moving the position of an image, we could surround some text with a <div> tag and move it around. Obviously, more complicated animations, such as animated objects that move in a random manner or change direction when they reach the edge of the window, require a longer and more complicated script.
  • 298. 278 How to Do Everything with JavaScript FIGURE 12-4 By modifying the CSS position attributes, we are able to make a ball move. In the next chapter, we will discuss the fundamentals of debugging JavaScript code. A bug is a software flaw, and debugging is the process of finding and repairing the bugs in a program. We will take a look at some of the tools available to developers who are looking to discover these errors, as well as some of the programming techniques for making bugs easier to find.
  • 299. Take JavaScript Part III to the Next Level
  • 300. This page intentionally left blank
  • 302. 282 How to Do Everything with JavaScript How to… ■ Understand JavaScript error messages ■ Add debugging code to your programs ■ Use the JavaScript console ■ Use a JavaScript debugger There is nothing more frustrating for a web surfer than to arrive at a web page and immediately be presented with error messages. The visitor will likely be wary of proceeding any further into the site and is less likely to want to return. Ensuring that the JavaScript scripts on your web page help your visitors rather than annoying them could be as simple as testing your web page using a variety of browser types, operating systems, and version numbers. Yes, it does sound like a lot of work, but there is no substitute for actual testing if you want to make sure your viewers will be happy with what you’ve done on the site. But what would you do if a web page you were working on displayed an error message? Or perhaps your code wasn’t working the way you had expected—or wasn’t working at all. How would you go about finding the source of the problem and fixing it? Several tools are available to help JavaScript developers with this task, and in this chapter we will discuss how to debug JavaScript programs. Understand the Possible Causes of Errors Finding an error message while you are testing a web page is like finding a $5 bill on the sidewalk— it’s worth the time to stop and pick it up. Not only does the error message tell you that there was a problem, it also shows you the first place you should look for the problem and even gives a brief description of what went wrong. Of course, the browser is only giving you its best guess about what the error might be. When you actually look at the code and figure out the problem, you might find that the error message hadn’t pinpointed the problem exactly. That’s understandable, since some errors have so many possible causes that it would be impossible for a computer to choose the correct one. Different browsers have different ways of reporting errors, and it is even possible to turn error reporting off. For instance, in IE, with error reporting turned on, a JavaScript error will cause the following message box to appear:
  • 303. CHAPTER 13: Debug JavaScript Programs 283 Even with error reporting turned off, IE still gives you a visual hint that the page did not load successfully. An error icon will be placed in the lower left-hand corner of the browser window, like so: Netscape always hides JavaScript errors from end users—it won’t even tell you that one occurred. You’ll need to load the JavaScript Console, which is discussed later, in the section “Use the JavaScript Console,” to see what if anything went wrong. There are three basic types of errors in JavaScript: ■ Syntax errors Errors in the basic programming syntax of the language, such as mismatched quotes or brackets ■ Run-time errors Errors that can be detected only at run time, such as attempting to use variables that do not exist ■ Logic errors Errors in your programming logic or algorithms that cause an incorrect result, such as a loop that exits one iteration too early Any of these types of errors can cause JavaScript to either stop running or return an incorrect result. There are dozens of possible reasons why an error would occur inside a JavaScript 1.5 program, including: ■ Calling a function or using a variable that is undefined ■ Attempting to modify the value of a constant ■ Passing a string to a function or operator that expects a number ■ Passing an incorrect number of parameters to a function ■ Using an unescaped quotation mark inside a string 13 ■ Using statements such as the for loop incorrectly Although JavaScript 2.0 attempts to retain the flexibility of previous versions, some of the new features have the potential to introduce new problems. In addition, JavaScript 2.0 gives programmers the option to enforce a stricter level of error checking (called strict mode). Potential errors for JavaScript 2.0 programs include: ■ Assigning an incorrect data type to a variable that’s expecting another data type ■ Trying to access variables or functions defined as private ■ Namespace issues ■ Running JavaScript 2.0 in a browser that only supports JavaScript 1.5 I have always felt that finding and fixing errors is like unraveling a mystery. You start with only a few clues and, with good detective work and perhaps a little luck, you eventually figure out exactly what went wrong.
  • 304. 284 How to Do Everything with JavaScript Turn on Error Reporting in IE Internet Explorer has two advanced options that affect the way JavaScript errors are reported and handled. The Advanced Options menu can be found by selecting Internet Options from the Tools menu and selecting the Advanced tab. On this tab, the first option setting we are concerned with is called “Display a notification about every script error.” This should be enabled in order to see the JavaScript error messages we are talking about in this chapter. The other option that may affect us is called “Disable script debugging.” Depending on the software installed on your computer, IE may give you the option of loading the web page into a tool called a debugger to find out more about the problem. Generally, this option should be enabled; that is, you do not want to be given the option to view the code in a debugger. (However, if you really do want to go into a debugger for every error and you have some experience in that software, then by all means disable the debugging option.) Find the Source of an Error Message When JavaScript encounters an error inside a script and the program does not handle it, then the user is notified of the error by an error message box. In IE, the details of the error are usually hidden, since they can be overly technical to the novice user. Instead, a somewhat friendlier message like the following is displayed. By clicking the Show Details button we can see some of the technical details about the particular error.
  • 305. CHAPTER 13: Debug JavaScript Programs 285 IE gives programmers a number of important details regarding the source of the error: ■ Line The line number where JavaScript first noticed the problem. This is not always the line that contains the problem, although it usually is. Having a text editor that shows line numbers will save you from having to manually count them out. Windows Notepad on XP can view line numbers by turning on the status bar (View | Status Bar). ■ Char The character number on the line where the problem might lie. ■ Error A string that tries to describe what JavaScript believes went wrong. ■ Code Some errors have an error code attached to them. ■ URL The web address of the HTML file that had the problem, in case there was any doubt. The line number listed in an error message includes any HTML lines that precede the 13 script, unless the script exists in a file by itself (an external script) in which case it is the actual line number of the script file. The line number referenced in the details of the error message is usually the best place to start looking for an error. You also want to read the description of the error provided by the message box, since that gives you the second clue needed to solve this mystery. Interpret Error Messages Perhaps the best way to see how closely (or not) the JavaScript error message relates to the actual source of the error is to look at an example. In this section, we will examine a piece of JavaScript code that has a serious bug in it and see how the two major browsers (Netscape and IE) report the error.
  • 306. 286 How to Do Everything with JavaScript To start the exercise, let’s take a look at the following HTML and JavaScript code. <html> <head><title>Interpreting error messages</title></head> <body> <script language="JavaScript" type="text/javascript"> function add (input1, input2) { return input1 + input2; } var result = ad (1, 2); </script> </body> </html> When we first run this code, we expect that after the add() function is called with the values 1 and 2, the result returned would be 3. Instead, we encounter a JavaScript error. IE gives the rather cryptic message “Object expected.” But it does give us a line number. Remember, the line number includes all the HTML code before the script on the web page. The ninth line of code points to a problem with the following line: var result = ad (1, 2); The Netscape JavaScript console does a better job of describing the error—although, as discussed earlier in this chapter, you have to open the console window in order to know that one exists. The console reports, more usefully, “ad is not defined.”
  • 307. CHAPTER 13: Debug JavaScript Programs 287 With careful examination, we can see that we have mistyped the name of the function; it should be add(), instead of ad(). Correcting the typo makes the error go away in both browsers. Use a JavaScript Validator One way to check your JavaScript code for strange bugs is to run it through a program that checks it to make sure it is valid—that it follows the official syntax rules of the language. These programs are called validating parsers, or just validators for short, and often come with commercial HTML and JavaScript editors. One limitation some validating parsers have is that they can only understand JavaScript language components that are part of the official ECMAScript specification. Some of these tools do not understand DOM function calls or some of the extensions to the language added by browser manufacturers that are not part of the ECMAScript specification. Perhaps the most convenient validator for JavaScript is Douglas Crockford’s JavaScript Lint, which is available free online at http://www.crockford.com/javascript/jslint.html. Simply visit that web page, paste your JavaScript code into the text area provided, and click the jslint button. 13 Voilà! The results appear onscreen in seconds. JavaScript Lint will parse through your JavaScript code, ensuring that any variable and function definitions follow the correct syntax. It will also check JavaScript statements, such as if and while, to ensure they too follow the correct format. This program will not catch all the errors in your JavaScript programs, but it will catch the obvious ones, such as missing brackets or undefined variables and functions. Add Debugging Code to Your Programs Often when a JavaScript script is not producing the desired results it’s not obvious why the problem exists. For instance, you may be expecting that after a series of mathematical operations a variable is going to come back with a specific value—but it doesn’t. There won’t be any JavaScript
  • 308. 288 How to Do Everything with JavaScript error messages to help you find the line that is causing the problem, and even a JavaScript validator may not be of any use. One thing programmers can do to help themselves is to add some debugging code to the program. Debugging code is code that exists purely to help the developer figure out what is going on behind the scenes while code is being modified. You would usually remove or comment out the debugging code once regular visitors to your page are using the script. Programmers commonly use the alert() or document.write() methods when adding debugging code to a program. For instance, the following script has a number of additional alert() message boxes that will give the developer an idea of what is going on inside the program. // Converts a number from "9999999" to "9,999,999" function convert_number(input) { var counter, output; alert("input = " + input); alert("input length = " + input.length); // Not long enough to get commas if (input.length < 4) return input; alert("length larger than 3"); // Empty output output = ""; // Loop through input string, three chars at a time for (counter = input.length-3; counter > 0; counter -= 3) { output = "," + input.substr(counter, counter+2) + output; alert("counter = " + counter + ", output = " + output); } // Final set of numbers output = input.substr(0, counter+3) + output; alert("counter = " + counter + ", output = " + output); return output; } In the preceding code, all the calls to the alert() message box are used for debugging purposes only. Their sole purpose is to provide the programmer with some clues about what is going on inside the function: what the original value is, what happens after each iteration of the loop, and the final result.
  • 309. CHAPTER 13: Debug JavaScript Programs 289 Again, once we are satisfied this function is working properly, we should remove or comment out those alert boxes to save our visitors from a lot of unnecessary mouse clicks. A similar debugging technique involves the careful and incremental use of comments. Let’s say you have a JavaScript function that does not appear to be working correctly. You have looked over the source code, and cannot figure out the source of the problem. // Converts a number from "9999999" to "9,999,999" function convert_number(input) { var counter, output; if (input.length < 4) return input; output = ""; for (counter = input.length-3; counter > 0; counter -= 3) { output = "," + input.substr(counter, counter+3) + output; } output = input.substr(0, counter+3) + output; return output; } 1. Start by commenting out the contents of the entire function. If the function is supposed to return a value, force it to return a hard-coded value that simulates what you are expecting. 13 Test the script to make sure it is now working correctly with the hard-coded value. // Converts a number from "9999999" to "9,999,999" function convert_number(input) { // var counter, output; // // if (input.length < 4) return input; // output = ""; // // for (counter = input.length-3; counter > 0; counter -= 3) { // output = "," + input.substr(counter, counter+3) + output; // }
  • 310. 290 How to Do Everything with JavaScript // output = input.substr(0, counter+3) + output; // return output; // ** Hard-coded return value ** return "1,234,567"; } 2. Next, uncomment a few of those lines. For instance, make the function return its input string instead of the hard-coded value. Again, test that this expected result (the input string) is working correctly. // Converts a number from "9999999" to "9,999,999" function convert_number(input) { var counter, output; if (input.length < 4) return input; output = ""; // for (counter = input.length-3; counter > 0; counter -= 3) { // output = "," + input.substr(counter, counter+3) + output; // } // output = input.substr(0, counter+3) + output; // return output; // ** Return the input value ** return input; } 3. Carefully uncomment more lines from the script. Know in advance what you expect the return value to be after each set of comments is removed, and then retest. 4. Repeat step 3 as necessary. At some point, you will discover that the return value is not the value you expected. The most recently uncommented lines are the most likely source of the problem! Adding debugging code and using comments are two of the most useful techniques for manually figuring out the source of errors inside scripts. Use the JavaScript Console The Netscape and Mozilla browsers include a useful utility called the JavaScript console. The JavaScript console opens in its own window, and this is the place where Netscape outputs any JavaScript errors it encounters. The console will continue to accumulate error messages from web pages until the browser is closed or the console is cleared manually.
  • 311. CHAPTER 13: Debug JavaScript Programs 291 FIGURE 13-1 The Netscape console shows JavaScript errors. To access the console in Netscape 7, go to Tools | Web Development, and choose JavaScript Console. (In Netscape 6, the JavaScript Console option is located in Tasks | Tools.) The console is empty when the browser is first opened, but will accumulate error messages as they occur for many different pages and sites as you surf. The console also allows developers to input JavaScript code for the browser to execute. Simply type the variable name into the console, click Evaluate, and the console will tell you the last value for that variable. Or you can have JavaScript manually call a function by typing in the function name along with any parameters. 13 Figure 13-1 shows what the console looks like in the Netscape 7 web browser. Use a JavaScript Debugger The final weapon in the programmer’s arsenal against bugs is to use debugging software. A debugger is a program that gives you complete access to the internal workings of the application. A JavaScript debugger will typically include a user-friendly interface and will allow a developer to step through the script one line at a time. The developer can see the current value of any variables and get more detailed feedback in order to help them find the true source of a bug. Debuggers are typically shipped inside HTML and JavaScript editors. For example, Microsoft FrontPage 2002 contains a JavaScript editor and debugger called Microsoft Script Editor. Macromedia Dreamweaver also contains a JavaScript debugger in its Dreamweaver MX product. There are also a number of third-party editors that contain debuggers, such as C Point’s JavaScript Editor (http://www.c-point.com).
  • 312. 292 How to Do Everything with JavaScript For those who don’t use a professional HTML editor, a number of free JavaScript debuggers are also available. Most prominent among them is the JavaScript Debugger available from the open-source Mozilla project. As you may know, the Netscape and Mozilla web browsers are based on the same core set of source code. Netscape, however, does not include the JavaScript Debugger with its version, while Mozilla does. So developers who use the Netscape 7 (and later) browsers will need to download and install the debugger as a separate tool. The latest Netscape web browser is available for download from http:// www.netscape.com. The latest version of the Mozilla JavaScript Debugger (code-named Venkman) for both Mozilla and Netscape browsers can be downloaded at http://www.hacksrus.com/~ginda/venkman. The Mozilla JavaScript Debugger is available on multiple operating systems (specifically Windows, Mac OS, and Unix), and does a great job helping developers step through their JavaScript programs. We can see a screenshot of this debugger in Figure 13-2. FIGURE 13-2 Stepping through a JavaScript program using the Mozilla debugger
  • 313. CHAPTER 13: Debug JavaScript Programs 293 To access the JavaScript Debugger in Mozilla 1 or Netscape 7, go to the Tools | Web Development menu, and choose JavaScript Debugger. Microsoft also provides a free debugger, the Microsoft Script Debugger. It is available for download at http://www.microsoft.com/script/debugger. Script Debugger supports many of the key debugger features, such as the ability to view and step through code, set breakpoints, and view and change variable values. No matter which browser you use, you are bound to find the ability to step through complex JavaScript programs very useful. For small scripts, adding debugging code may be all you need to find problems. But when your program contains a lot of functions and you need some of the advanced debugging features such as breakpoints, a good JavaScript debugger can be the programmer’s best friend. The next chapter deals with some of the important concepts around using try-catch statements to intercept system errors before the browser does. You will also see how to use exceptions in your own programs. What a Breakpoint Is In debugging, a breakpoint is a line of code designated by the programmer as the point where the debugger will pause (or break) the program. The programmer can perform a number of tasks inside the debugger before letting the program continue executing. The benefit of having a debugger that supports breakpoints is that instead of having to step through every single line of code in a script manually, you can let the debugger execute all lines automatically until it reaches its first breakpoint. Once you have checked the contents of some data variables, you can either step through the program manually or let it run 13 automatically until it reaches the next breakpoint.
  • 314. This page intentionally left blank
  • 315. Make Your Chapter 14 Program Errorproof
  • 316. 296 How to Do Everything with JavaScript How to… ■ Understand exceptions and how they are caused ■ Catch exceptions using the try and catch statements ■ Create exceptions using the throw statement ■ Design programs that are easy to debug from the start Designing and developing programs that are immune to errors is a difficult task when using programming languages such as Visual Basic and Java. But it is in some ways even more difficult when working with JavaScript. One of the reasons this is true is that, as a scripting language, JavaScript is generally distributed as source code. In normal circumstances, there is no compiler to catch syntax errors before users see the final program in action. With other languages, the compilation step provides a layer of protection against certain types of errors. Another reason for the difficulty is that JavaScript is often developed using nothing more than a basic text editor. Languages such as Visual Basic are created using integrated development environments (IDEs) that help developers create better code and include built-in debuggers. And yet another reason is that the number of target environments (browsers and operating systems) is so diverse—literally dozens of combinations—that it becomes practically impossible to test the program in all the possible environments. But there are some techniques developers can use to make sure the JavaScript programs they create will work properly in as many environments as possible. In this chapter, we will examine some of the most practical ways to ensure programming success. Learn the Basics of Exceptions In the early days of web programming, when JavaScript encountered a error while executing a program the result was always fatal: the browser would stop executing the code and report the error to the user. In effect, errors were always reported directly to the browser—the application had no opportunity to try and handle the error itself. You can imagine how impossible it was to create an errorproof program when you couldn’t even detect when an error occurred. In addition, JavaScript developers had to invent their own ways of returning errors back to the program. Take the following example: function simple_addition(a, b) { // This function will add two numbers, // but only if they both are between 0 and 9 if (a < 0 || a > 9) { return "First number is not between 0 and 9."; } else if (b < 0 || b > 9) {
  • 317. CHAPTER 14: Make Your Program Errorproof 297 return "Second number is not between 0 and 9."; } else { return a + b; } } Every place inside the program that made a call to this function had to have several extra lines of code (more if statements) to check the return value to see whether an error occurred before using the number. Other programmers might solve the same problem differently, with special return codes (like using the value –1) to return an error. JavaScript uses exceptions to pass system errors back to the program for handling. In addition, JavaScript programmers can use the same system of exceptions inside their code to return application-specific errors back from functions. For example, we can rewrite the source code from the previous example to use exceptions instead, by using the throw statement. function simple_addition(a, b) { // This function will add two numbers, but only if they are less than 10 if (a < 0 || a > 9) { throw "First number is not between 0 and 9."; } else if (b < 0 || b > 9) { throw "Second number is not between 0 and 9."; } else { return a + b; } } You will learn more about the statements that deal with creating and capturing exceptions in 14 the next two sections. Catch Exceptions Using the try and catch Statements The try-catch statement was introduced in JavaScript 1.4; it is modeled on similar statements in Java and C++. When JavaScript encounters a try-catch statement in code, it will begin to execute the block of code contained inside the try clause. If any of the statements inside that block cause an exception to occur, JavaScript will not execute any of the remaining statements inside that block and will jump immediately to the code contained inside the catch clause. Of course, if no exceptions occur inside the try clause, the code inside the catch clause will never be executed.
  • 318. 298 How to Do Everything with JavaScript The following code shows how the try-catch statement can be used to protect the code from exceptions. var isIE = (navigator.userAgent.indexOf("MSIE")) > -1; try { var a = 1; var c = a / b; alert("The result of a / b is " + c); } catch (e) { var msg = "JavaScript encountered the following error:nn"; // IE and Netscape pass errors differently to the catch clause if (isIE) { msg += e.description; } else { msg += e; } alert (msg); } IE and Netscape each has its own way of passing errors to the catch clause. IE passes the error as an Error object—in order to get the actual error message you have to access one of the properties of that object. Netscape passes the error as a string, which can be used like any other string. The preceding code attempts to use an undefined variable, b, inside the try block. As soon as our code attempts to use that variable in an expression, an exception occurs, and the rest of the code inside the block does not execute. The error message generated by the catch clause for IE looks like this. Netscape encounters the same error when executing the code inside the try block. Its error message is worded slightly differently, however:
  • 319. CHAPTER 14: Make Your Program Errorproof 299 Understand Exception Bubbling The try-catch statement can also capture errors generated inside function calls within the try clause. For instance, say we were to move some of the code from the previous example into a function of its own. var isIE = (navigator.userAgent.indexOf("MSIE")) > -1; function calculate() { var a = 1; return a / b; } try { var c = calculate(); alert("The result of a / b is " + c); } catch (e) { var msg = "JavaScript encountered the following error:nn"; // IE and Netscape pass errors differently to the catch clause if (isIE) { msg += e.description; } else { msg += e; } alert (msg); 14 } The try-catch statement will still receive notification of the error, even though it occurs inside the calculate() function. This is because exceptions, like events, bubble. Exception bubbling is the term that is used to describe the process of how an exception will seek out the first try-catch statement eligible to handle it. If there is no try-catch statement immediately surrounding the line of code with the error, control will jump back to the code that called the function containing the error. If there is no try-catch there, control will jump back to the code that called it, and so on, until either a try-catch is found or the browser handles the exception by displaying it to the user.
  • 320. 300 How to Do Everything with JavaScript For example, the following code generates an error after several levels of function calls have been made. The exception still manages to make its way back to the try-catch statement surrounding the first function call. var isIE = (navigator.userAgent.indexOf("MSIE")) > -1; function fn1 () { // The first function (fn1) calls the second (fn2) fn2(); } function fn2 () { // The second function (fn2) calls the third (fn3) fn3(); } function fn3 () { // The third function (fn3) calls the fourth (fn4) fn4(); } function fn4 () { // The fourth function (fn4) calls the fifth (fn5) fn5(); } function fn5 () { // The fifth function (fn5) contains an error return some_undefined_variable; } // MAIN program try { fn1(); } catch (e) { var msg = "JavaScript encountered the following error:nn"; // IE and Netscape pass errors differently to the catch clause if (isIE) { msg += e.description; } else { msg += e; } alert (msg); }
  • 321. CHAPTER 14: Make Your Program Errorproof 301 As you can see from the following screenshot, both Netscape and IE are able to pass the exception properly to our catch clause. You do not always have to respond to an exception by displaying a message to the user. You could always ignore the error and continue. Use the IE Error Object As we observed in the previous section, Internet Explorer passes an Error object to the parameter of the catch clause. The Error object contains two properties: ■ number A numeric value related to the error ■ description A string describing the error The code in this section will work only in Internet Explorer. IE automatically creates an Error object whenever an exception occurs, but you are also free to create your own error using the following new statement syntax: var myerr = new Error (1000, "Value falls outside acceptable range of 0-81."); Using this object allows your program to easily distinguish between different types of errors while also retaining the plain-English description to display to the user. 14 // Error 1000: Ignore, set return code to 0 if (e.number == 1000) { var returncode = 0; // Error 1001: Exit loop, set return code to 9999 } else if (e.number == 1001) { var returncode = 9999; // Other error code: Can't handle this, report to user } else { alert(e.description); }
  • 322. 302 How to Do Everything with JavaScript The only real problem with this method is that Netscape uses a different approach, which means you have to have browser-sniffing code in order to create cross-platform-compatible code. Use Netscape-Only catch Clauses Netscape has a special syntax for catch clauses that allows for more than one of them to exist in a try-catch statement. Netscape calls them conditional catch blocks. IE does not support this syntax, and it is not part of the official ECMA standard. Basically, Netscape allows developers to insert an if keyword to determine which catch block is called after an exception is thrown: try { var input = get_user_input(); edit_check (input); } catch (e if e == "Value too high") { // What do we do when the user enters a value that is too high? // ... } catch (e if e == "Value too low") { // What do we do when the user enters a value that is too low? // ... } catch (e if e == "No value entered") { // What do we do when the user does not enter a value? // ... } catch (e) { // Some other error occurred // ... } I recommend that this proprietary method be avoided if at all possible. Since adding an if-else statement into a single catch clause can generate the same effect, there is no benefit to coding it like this. Use Nonstandard finally Clauses Java and C++ programmers will recognize the optional finally clause in the try-catch statement, although those familiar with the official ECMAScript specification will not. Both Netscape and
  • 323. CHAPTER 14: Make Your Program Errorproof 303 IE web browsers support this clause, even though it does not exist in the official standard and therefore is not supported by all JavaScript environments. Basically, the finally clause contains code that will always be executed, regardless of whether an exception occurs in the try block or not. Even if there are return statements inside the try or catch clauses (which triggers an exit from the function), the finally clause is guaranteed to run. The only time the finally clause will not be executed is if an unhandled exception occurs inside the catch clause. An unhandled exception is an exception that has to be handled by the browser, since there are no remaining try-catch statements to handle it. For example, the following code triggers an exception inside the try clause, and both the code inside the catch clause and the code inside the finally clause are executed before the control is passed back outside the function. function function_that_will_fail() { var a = 1; var b = 2; this_function_does_not_exist(a, b); } function capture_error() { try { document.write("<b>try</b>: "); document.write("Calling the function.<br><br>"); function_that_will_fail(); } catch (err) { document.write("<b>catch</b>: "); document.write("An error has occurred.<br><br>"); return; } 14 finally { document.write("<b>finally</b>: "); document.write("This code is guaranteed to execute.<br>"); } } capture_error(); As you can see from Figure 14-1, even though there is a return statement inside the catch clause, the finally clause does indeed execute.
  • 324. 304 How to Do Everything with JavaScript FIGURE 14-1 The finally clause gets the last say: exception or no exception. Create Exceptions Using the throw Statement One thing that makes the try-catch statement more useful is the throw statement. The throw statement allows developers to create their own exceptions. This means that you can have a single set of try-catch statements to capture all system and application errors, which certainly saves a lot of coding effort. It also allows you to leverage the exception bubbling mechanism in order to pass an error message from deep inside a function up to the try-catch statement waiting several function calls back. Without this exception bubbling, we would have to write a lot of extra code in order to capture errors inside each function and then remember to diligently pass them back up to the next level. For example, the following code causes an exception to occur. By definition, processing inside the function stops immediately, and the exception is passed to the waiting try-catch statement one level back. function throw_an_error() { throw "Ouch! I stubbed my toe!";
  • 325. CHAPTER 14: Make Your Program Errorproof 305 } try { throw_an_error(); document.write("This line will never be executed."); } catch (myerr1) { document.write("The following error occurred: <br>"); document.write(myerr1); } Notice that I was able to use the myerr1 variable as a string and did not have to include browser-sniffing code to determine whether or not we need to use the IE Error object. The reason is that since we used the throw statement to pass a string literal, the catch clause receives only the string. IE does not automatically create an Error object for you if you choose to throw a string. You can, however, create your own Error object and throw it. How to Re-throw an Exception When the try-catch statement encounters an exception that it does not want to handle, it can use the throw statement to send the exception back to another try-catch defined elsewhere in the program. This is called re-throwing it. For example, the following code re-throws an error that it is not prepared to handle: function calculate_total() { try { var subtotal = get_item_amount(); } catch (e) { 14 if (e = "No items remaining") { return 0; } else { // must have been a system error, // let JavaScript handle it throw e; } } }
  • 326. 306 How to Do Everything with JavaScript function throw_an_error() { var eobj = new Error ( 0, "Ouch! I stubbed my toe!" ); throw eobj; } However, this code works only in Internet Explorer, since there is no Error object in Netscape. So with this approach we would need to introduce browser-sniffing code as well. The best approach is to throw a string, as you would expect. In the catch clause, test to see whether the parameter passed is a string or an object. catch (myerr1) { if (myerr1 instanceof Error) { var errstring = myerr1.description; } else { var errstring = myerr1; } document.write("The following error occurred: <br>"); document.write(errstring); } The preceding catch clause works in both IE and Netscape and will properly detect whether the parameter passed is an Error object or just a string. Design Programs That Are Easy to Debug from the Start Certain programming styles lead to less bugs (and less debugging hassles), while others have the opposite effect. Whenever your JavaScript program looks like it is going to be long and complicated, you may save yourself some time and headaches later if you take the right design approach from the start. We discussed the four programming styles in some detail in Chapter 3: ■ Unstructured Sequence of statements acting on global data ■ Procedural Main program that calls functions to perform certain tasks ■ Modular Main program that uses modules to group related functionality ■ Object-oriented Main program that uses objects to group related data and functionality Each of these methodologies has its pros and cons when it comes to writing errorproof programs. The unstructured technique is good for small scripts but terrible for large ones. Object-oriented is the opposite—good for large programs and poor for short scripts. Having a rough idea of the complexity of your program beforehand will help you decide on the best approach.
  • 327. CHAPTER 14: Make Your Program Errorproof 307 Avoid Unstructured Programming Unstructured methodology is usually best for short, simple scripts. Essentially, this program consists of a set of JavaScript statements that do not define or use any functions, modules, or objects. In some ways the unstructured technique is the simplest of them all, but when your program exceeds more than a page or two of code, you should think about breaking it up into more manageable pieces. The biggest problem you’ll encounter with a large program of this type is the complexity and number of interdependencies in the code. Statements later on in the program will rely on variables set several hundred lines earlier. Making a change to one part of the program might break the code in another area. Building a program in such a fashion is similar to building a house out of one large piece of wood. One small adjustment, such as relocating a window, becomes next to impossible without starting over completely. That is OK only if your house is very small. Break Code into Manageable Chunks There’s a reason houses aren’t made in one big piece, but one wall, roof, floor, and staircase at a time. That way, relocating a window does not affect other walls or other structural elements, and the worst thing that such an adjustment can do is cause you to have to rebuild a single wall. Houses are built of separate components, and computer programs generally should be as well. The easiest way to “componentize” a program is to organize it into several functions. It is best if these functions fall into separate areas of responsibility, if at all possible, so that two or more functions are not working at cross-purposes or doing the same task. For example, the following code snippet shows how using functions improve program organization and readability: function groceries () { var grocerylist = get_grocery_list(); drive_to_store(); for (var item in grocerylist) { get_item(item): } 14 pay_cashier(); drive_home(); put_food_away(); return; } We could have alternatively used an unstructured program that attempted to do all those tasks in order. But that program would have been harder to read, test, and make changes to.
  • 328. 308 How to Do Everything with JavaScript To test a function, we only need to make sure that it performs the tasks and returns the value that is expected of it. Most functions rely on the way the rest of the program is structured, so you can never be 100 percent sure that nothing will go wrong. Because functions are easier to test, you will find that procedural programming offers a higher sense of reliability than unstructured programming does. Reuse Code Using Classes and Objects The other way to componentize your code would be to break it into a number of classes and objects. Classes allow you to separate all related functions and variables into a single module. This allows you to create classes that can be easily reused in other applications. For instance, you can create a class that represents an item in the user’s online shopping cart. Since this item code is generic, the exact same code can be reused in other applications that need access to an item, say, an inventory program. class Item { var SKU : String; var productName : String; var size : String; var color : String; var retailPrice : Number; var wholesalePrice : Number; function Item(inSKU : String, inName : String, inSize : String, inColor : String, inPrice1 : Number, inPrice2 : Number) { this.SKU = inSKU; this.productName = inName; this.size = inSize; this.color = inColor; this.retailPrice = inPrice1; this.wholesalePrice = inPrice2; } // More methods would follow... } Classes and objects are much easier to test as well. You would only need to check once to make sure the object behaves the way it is expected to. As long as there are no code changes in the class, the object can be considered completely tested.
  • 329. CHAPTER 14: Make Your Program Errorproof 309 Test Your JavaScript Code Thoroughly The final key to ensuring that your program is immune from errors is to perform thorough testing on it. Testing involves running the program many different times under many different scenarios to make sure it operates as expected. For short scripts, testing does not have to be complicated. For instance, testing mouse rollover effects may just entail rolling the mouse across an image several times to make sure that it toggles as expected. For more complicated scripts, such as those involving DHTML or interframe communication, more rigorous testing may be required. Create a Testing Harness A testing harness is a program whose job it is to help test other programs. In JavaScript programming, a testing harness generally takes the form of a custom web page that exposes buttons and form fields used for testing the behind-the-scenes scripts. Figure 14-2 shows an example of a good testing harness. The web page allows a developer or tester to manually trigger certain events or to force-feed certain values to functions embedded on the page. 14 FIGURE 14-2 Use a testing harness to help test JavaScript programs.
  • 330. 310 How to Do Everything with JavaScript To see a testing harness in action, let’s start with a small JavaScript script that we wish to test. // This script will validate an e-mail address function validate_email (inputstr) { // The following complex regular expression pattern checks // for a valid e-mail address: [email protected] var pattern = /^[a-zA-Z0-9_-.]+@([a-zA-Z0-9-]+.)+[a-zA-Z]{2,3}$/; if (inputstr.search(pattern) > -1) { return true; } else { return false; } } Now we could just choose to use this straight in our program, but it would be a good idea to verify that it is completely working before doing so. By creating the following HTML testing harness that includes our script, we can test dozens of different e-mail addresses in an easy and straightforward fashion. <html> <head> <title>HTML Testing Harness</title> <script language="JavaScript" type="text/javascript"> // This script will validate an e-mail address function validate_email (inputstr) { // The following complex regular expression pattern checks // for a valid e-mail address: [email protected] var pattern = /^[a-zA-Z0-9_-.]+@([a-zA-Z0-9-]+.)+[a-zA-Z]{2,3}$/; if (inputstr.search(pattern) > -1) { return true; } else { return false; } } </script> </head> <body> <center> <h1>HTML Testing Harness</h1>
  • 331. CHAPTER 14: Make Your Program Errorproof 311 <h2>for E-mail Checker</h2> </center> <form action="#" method="get"> E-mail address: <br> <input type="text" name="email"> <input type="button" value="Test" onclick="alert(validate_email(document.forms[0].email.value))"> </form> </body> </html> The preceding HTML code exists only to test the JavaScript function validate_email(). It consists of a simple HTML form that contains a text box and a push button. Using this form, testers and developers can type in dozens of different test e-mail addresses to verify that our script is working as expected. If this process is repeated with each complex function in a program, you will reduce the likelihood of users discovering strange behavior when using your web page. Force Errors to Test Error-Handling Code One thing that occurs when developers test their own programs is what I call “Sunny Day Syndrome.” We tend to use only valid dates when functions are expecting a date in a parameter field or use only numbers when functions expect numeric values. But it’s important to see what happens when you send an invalid date (such as “02/29/2005” or “12/33/2005”) to such a field—or even to try sending something that’s not a date (such as the string “Boo”). How does your function respond to invalid inputs? How is your error-handling code? You might even have to modify the code to force such errors. For example, in the following code, I have hard-coded an array to be empty in order to see how the code handles empty arrays. This is only to test the error-handling capabilities of the code that called this function. function print_listing() { 14 var itemarray = get_product_list(); // BEGIN TESTING:: Empty array added just for testing // Forcing an error itemarray = new Array(); // END TESTING for (var item in itemarray) { // Rest of code ... } }
  • 332. 312 How to Do Everything with JavaScript We only modify the code to see what would happen were something to go wrong. This is a very easy way to test for things that rarely happen in real life. Try Your Program in Many Different Environments After you have used the try-catch statement to capture and handle errors and have designed your program in a modular, easy-to-test manner, there is only one thing left to do: system testing. System testing is the process of trying a program on all the different software environments it could possibly run on. JavaScript programs embedded in web pages still need to be checked in several different browsers and operating systems in order to be considered errorproof. You might not have that many operating systems at your disposal, but it isn’t difficult to download and install two or more web browsers so you can at least test your program in those environments. It is fairly difficult to get multiple versions of IE running on the same machine, but it can be done. It has always been much easier to get several versions of Netscape— all you have to do is install them in different directories. The web site http://browsers.evolt.org contains a copy of almost every browser ever produced. It’s a pretty impressive site. If you ever want to see what the Internet of today looks like in Netscape 0.9 , you can download and install it to find out. You probably don’t have to test every browser ever produced, but at a minimum you should check your scripts using IE 5, Netscape 4 and 7, and Mozilla 1. The next chapter is the final chapter of the book. It explores how JavaScript can be used to interact with multimedia objects on the page. JavaScript was originally developed to interact with Java, but it can also deal with movies and music embedded in web pages.
  • 333. Use JavaScript to Chapter 15 Manage Browser Plug-Ins
  • 334. 314 How to Do Everything with JavaScript How to… ■ Insert scriptable objects into HTML web pages ■ Include Sun Java applets ■ Embed movies and music in web pages ■ Use the Microsoft Calendar Control in web pages Since its initial release in December 1995, JavaScript has been primarily used for web site automation. Tens of thousands of useful scripts have been created for everything from handling web site navigation to running online shopping carts. The widespread adoption of JavaScript has meant that web pages now display information in a more interesting and dynamic manner. Over the years, many companies have created their own technologies to enhance the web experience for users even further. These companies have developed and distributed their own applications, called browser plug-ins, so that users of the various web browsers can view these enhancements. There are two standards for creating these browser enhancements: the Netscape Plug-In API and Microsoft ActiveX. These two standards are not compatible, so developers must create versions of their plug-ins for both. Throughout this chapter, I will refer to components developed under either architecture as “plug-ins,” for the sake of convenience. As you may have guessed from the way the two standards are named, browsers based on the Mozilla engine (including Netscape browsers) only support the Netscape Plug-In API standard, and Microsoft Internet Explorer only supports the ActiveX standard. Plug-in developers often need to support both types of plug-ins, since the browser companies do not appear to be settling on any one standard. You can download many ActiveX controls for IE from http://activex.microsoft.com. At http://home.netscape.com/ plugins Netscape also provides a place to download plug-ins. There are literally dozens of plug-ins available for download, and some browsers ship with several of the popular ones already loaded. The following list contains some of the most popular plug-ins and the URLs where they can be downloaded: ■ Macromedia Flash, http://www.macromedia.com/software/flash ■ Macromedia Shockwave, http://www.macromedia.com/software/shockwaveplayer ■ Sun Java, http://sun.java.com ■ RealNetworks RealOne Player, http://www.real.com ■ Apple QuickTime, http://www.apple.com/quicktime ■ Microsoft Windows Media Player, http://www.microsoft.com/windows/windowsmedia
  • 335. CHAPTER 15: Use JavaScript to Manage Browser Plug-Ins 315 Users are required to install plug-ins in order to view some content because browsers only know how to display two types of content without help: text and images. For web pages that include other types of content, such as movies, music, and 3-D virtual reality models, browsers must rely on external plug-ins to handle the content. In this chapter, we will examine how to add these different types of content to a web page and how to use JavaScript to control them. From Java applets to ActiveX controls, we’ll see how JavaScript can call the methods and functions that those objects provide. Insert Scriptable Objects into HTML Web Pages Web browsers treat content managed by plug-ins as they would any other content on the web page—like an object. The movies, music, and Java applets embedded on a page become one more node in the Document Object Model hierarchy. Since they often also provide properties and methods that can be manipulated by JavaScript, we call them scriptable objects. There are three HTML tags that are able to add these scriptable objects to a web page: ■ <applet> ■ <embed> ■ <object> Of the three, only <object> is part of the official HTML standard. Both <applet> and <embed> have been available in web browsers since Netscape 2, but the Internet standards body had decided that those tags were ill conceived, and instead encourages web developers to use the alternative <object> element. Include Sun Java Applets Java is an easy-to-use programming language that is used by many different types of developers— from serious corporate types to the home user. The Java Virtual Machine (JVM) was one of the first plug-ins ever released, and it was actually included with the Netscape Navigator 2 web browser. A version of the JVM is available for dozens of platforms, including: ■ Cell phones 15 ■ Personal digital assistants (PDAs) ■ Web browsers ■ Personal computers that run Microsoft Windows XP, Apple Mac OS, Linux ■ Business computers that run Sun Solaris, Microsoft Windows 2000, Unix Applets are small Java programs that are designed to run inside a web browser. On the Internet today, applets are frequently used to provide stock tickers, interactive charts and graphs, crossword puzzles, and chat rooms.
  • 336. 316 How to Do Everything with JavaScript To see how easy it is to include Java applets in a web page, let’s look at a simple example of some Java code. The following code needs to be saved in a text file named HelloWorld.java: /* My first Java program */ import java.applet.Applet; import java.awt.Graphics; public class HelloWorld extends Applet { public void paint(Graphics g) { g.drawString("Hello world!", 75, 75); } } Since Java programs are compiled, we first need to run this code through a compiler before it can be used inside a web browser. The process of compiling turns a plain-text .java code file into a binary .class file. This .class file can be executed on any computer with a JVM, since binary Java files are platform-independent code that does not rely on a specific operating system. In HTML, Java programs are added to a web page using the <applet> tag. Although <applet> is not part of the official HTML 4.01 specification, both Netscape and IE support it. For example, the following HTML embeds a Java applet into a web page: <applet code="HelloWorld.class" width="250" height="150" id="myapplet"> </applet>
  • 337. CHAPTER 15: Use JavaScript to Manage Browser Plug-Ins 317 Download the Java SDK Sun Microsystems provides several pieces of its Java platform free to anyone who wants to download them, including the JVM (which is part of the Java Runtime Environment, or JRE) and the Java compiler (which is part of the Java Software Development Kit, or SDK). In order to ensure you have the latest JVM, head over to the Sun Java web site at http:// java.sun.com/getjava/index.html. That page will make sure your web browser has the latest version of Java installed and ready to go. If you would like to download a compiler so that you can try your hand at creating Java applets, you can download your own SDK for free from http://java.sun.com/j2se/ downloads.html. There are several good tutorials available on the Sun Java web site to help you create your first Java program. Using this HTML code, the web browser will attempt to load the Java applet called HelloWorld.class and will reserve an area on the screen for it that is 250 pixels wide by 150 pixels tall. You can see how this Java applet will look in the web browser in Figure 15-1. The HTML <applet> tag has a number of optional attributes that can be used to further define the applet’s properties inside the browser. Table 15-1 lists these attributes. Attribute Purpose code The class file name codebase The class file subdirectory archive The name of the .zip file containing the class file alt Text that should be displayed by browsers that don’t support the <applet> tag align How the applet should be aligned with text and images placed beside it 15 height The height of the applet in pixels or as a percentage width The width of the applet in pixels or as a percentage hspace The amount of horizontal space to reserve around the applet in pixels vspace The amount of vertical space to reserve around the applet in pixels mayscript Permits the applet to access JavaScript name The name of the applet to be used in the DOM TABLE 15-1 Attributes of the HTML <applet> Tag
  • 338. 318 How to Do Everything with JavaScript FIGURE 15-1 A simple Java applet inserted into a web page Web page developers also have the option of passing in several parameters to the Java applet to help customize it using the HTML <param> tag. For instance, we can modify our Hello World Java applet to accept one parameter: /* My first Java program */ import java.applet.Applet; import java.awt.Graphics; public class HelloWorld extends Applet { String displayString; public void init() { // We are expecting a <param> named "display" displayString = getParameter("display");
  • 339. CHAPTER 15: Use JavaScript to Manage Browser Plug-Ins 319 } public void paint(Graphics g) { g.drawString(displayString, 75, 75); } } We can then use the HTML <param> tag inside the <applet> tag to pass a customized string to display to the applet, like so: <applet code="HelloWorld.class" width="250" height="150" id="myapplet"> <param name="display" value="This is my applet!"> </applet> Using this new parameter, we can change the string our Java applet displays without having to recompile the code. An applet can accept multiple parameters, so your Java applet can be designed to be completely configurable from outside the compiled code. Connect to Java Applets Using JavaScript As you would expect, JavaScript is able to call the public methods and set the public properties of any Java applet. The Java applet we created in the last section already has a number of public properties and methods, some of which are automatically provided by HelloWorld’s parent class—Applet. We can create a small JavaScript function that will modify the string being displayed and force the applet to refresh by calling the appropriate public properties and methods, as follows: <script language="JavaScript" type="text/javascript"> function displayString() { var applet = document.getElementById("myapplet"); applet.displayString = "String is set here"; applet.repaint(); 15 } </script> This JavaScript function starts by creating a variable that will point to the Java applet on our HTML web page using the familiar document.getElementById() function. We then modify the displayString property, which was defined inside the HelloWorld Java applet. In order to get Java to display our new string to the screen, we have to call the applet’s repaint() method.
  • 340. 320 How to Do Everything with JavaScript Of course, it would also be helpful to display a small button or other user control in order to trigger this JavaScript function with an onclick event. <applet code="HelloWorld.class" width="250" height="150" id="myapplet"> <param name="display" value="This is my applet!"> </applet><br><br> <form action="#"> <input type="button" value="Modify Applet" onclick="displayString()"> </form> This HTML code will add a small push-button control underneath the applet window. Clicking the button will cause the string displayed by our applet to be altered, as you can see in Figure 15-2. FIGURE 15-2 The applet has been modified as a result of our JavaScript function.
  • 341. CHAPTER 15: Use JavaScript to Manage Browser Plug-Ins 321 Embed Movies and Music in Web Pages Embedding movies and music in web pages is handled quite differently from embedding Java applets. First, the <applet> tag cannot be used to embed these types of files into a web page (unless you use a Java applet to display them, of course). The first way to insert a multimedia file into a web page is by using the <embed> tag. Using the <embed> tag is certainly easier than using the <object> tag, but when using it, remember that <embed> is not part of the official standard. <embed src="myMovie.avi" autostart="true" loop="true" width="160" height="120"></embed> With the <embed> tag, you pass all the parameters to the plug-in using attributes inside the tag itself. There is no <param> tag for <embed>. The <embed> tag supports three parameters for itself—src, width, and height. The source URL for the embedded content is passed using the src attribute. The amount of space reserved inside the browser is passed using the width and height attributes. Your computer would need a browser plug-in that could handle Windows AVI files in order to see the movie in our example. Most of the popular video players can, however, including Windows Media Player, Apple Quicktime, and RealNetworks RealOne Player. In the preceding example, the plug-in that is responsible for playing the movie is being passed the autostart parameter, as well as the loop parameter. It is up to the plug-in software, of course, to interpret what they mean and what to do with them. IE is currently the only browser that supports ActiveX controls such as Windows Media Player. We can also use the official <object> tag to embed the movie in our web page. The <object> tag is slightly more complex, particularly since plug-ins are referred to using an extremely long hexadecimal number. <object id="ActiveMovie1" classid="CLSID:05589FA1-C356-11CE-BF01-00AA0055595A" width="320" height="240"> 15 <param name="ShowDisplay" value="1"> <param name="ShowControls" value="1"> <param name="AutoStart" value="1"> <param name="PlayCount" value="10"> <param name="FileName" value="myMovie.avi"> </object> The preceding HTML code inserts an object using the Microsoft ActiveMovie control, which is identified using that long classid attribute. ActiveMovie is the ActiveX control installed with
  • 342. 322 How to Do Everything with JavaScript Embed a Windows Media Player 9 Object in a Web Page With the release of Windows Media Player 9, Microsoft has further enhanced the capabilities of its video and music playback application. Windows Media Player 9 also includes an ActiveX control that allows developers to embed music and movies in web pages. However, since not everyone has had an opportunity to upgrade to this new player yet, it might be better not to force your visitors to download it in order to see your content. But if you can be reasonably sure that your audience already has this software installed, you can easily include this new <object> tag in your web pages. Notice in the following HTML code that the classid value is different, as is the name of the parameter used to specify the name of the media file. <object id="Player" height="0" width="0" classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" width="160" height="120"> <param name="URL" value="myMovie.avi"> </object> Microsoft Windows Media Player 6.4 that manages the details of the display and playback of movies. Developers can pass the ActiveMovie control several properties to control the size, volume, balance, and position. You can see an example of the ActiveMovie control in Figure 15-3. If we do not want to rely on Windows Media Player to play our movie, we can use the classid attribute belonging to the Apple Quicktime Player, as follows: <object id="QuicktimeMovie1" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="320" height="240" codebase="http://www.apple.com/qtactivex/qtplugin.cab"> <param name="src" value="myMovie.avi"> <param name="autoplay" value="true"> <param name="controller" value="false"> </object> The preceding code will use the Apple Quicktime Player plug-in instead to display our movie. Again, this will only work in web browsers that support ActiveX controls. Connect to Music and Media Objects Using JavaScript Just as we could use JavaScript to reset the properties and call the method of Java applets, we can also use that same principle when handling other embedded objects. For instance, the following
  • 343. CHAPTER 15: Use JavaScript to Manage Browser Plug-Ins 323 FIGURE 15-3 Embedding a movie in an HTML page JavaScript functions can be used to stop and start the movie displayed in our ActiveMovie control. <script language="JavaScript" type="text/javascript"> var movie = document.getElementById("ActiveMovie1"); function startMovie() { movie.Run(); } 15 function stopMovie() { movie.Stop(); } </script> The preceding JavaScript code gets a variable reference to the element named ActiveMovie1, which happens to be our embedded movie control. We can then call the Run() and Stop() methods of that control to start and stop the movie. We can take advantage of these functions by adding two HTML push-button controls to the web page, allowing users to stop and start the movie themselves.
  • 344. 324 How to Do Everything with JavaScript <form action="#"> <input type="button" value="Start Movie" onclick="startMovie()"> <input type="button" value="Stop Movie" onclick="stopMovie()"> </form> Use the Microsoft Calendar Control in Your Web Pages Microsoft provides some interesting ActiveX controls that you can use in your HTML web pages. One such control is the Microsoft Calendar Control, which can be used to display a calendar and allows your users to choose a date. For choosing dates in the near past or future, this tool can be a valuable time-saver. IE is currently the only browser that supports ActiveX controls such as the Calendar Control. Figure 15-4 gives an idea of how the calendar control looks in a web browser. Of course, knowing the class ID of the calendar control makes adding it to a web page fairly easy, using the <object> tag. FIGURE 15-4 The predefined calendar control can be used to select a date.
  • 345. CHAPTER 15: Use JavaScript to Manage Browser Plug-Ins 325 <object id="myCalendar" width="480" height="190" classid="CLSID:8E27C92B-1264-101C-8A2F-040224009C02"> <param name="Year" value="2004"> <param name="Month" value="7"> <param name="Day" value="17"> </object> We can pass the current year, month, and date to be displayed using the familiar <param> syntax. Of course, the calendar control is scriptable, like most other objects embedded in the web page. So all we need is a variable that contains a reference to the object and then we are free to modify its properties and settings using JavaScript. The basic principles introduced in this chapter can be extended to almost any type of content you can imagine. Macromedia Flash animations, virtual reality 3-D models, and Adobe Acrobat PDF documents can all be handled inside the browser window using plug-ins. And most of those objects can be scripted using JavaScript. JavaScript has firmly implanted itself as a core technology in web site development. As the Internet moves into the age of XML and XHTML, and away from the age of HTML, we can trust that JavaScript will remain a popular standard, since there is no better technology to bring automation and interactivity to web pages. 15
  • 346. This page intentionally left blank
  • 347. Appendix A HTML 4.01 Tags
  • 348. 328 How to Do Everything with JavaScript The following table lists each of the HTML 4.01 tags and gives a brief description of its use. But note that Microsoft and Netscape have in some cases added their own tags, so their lists might not match this. <a> Creates a hyperlink, or defines a bookmark inside a page <abbr> Denotes an abbreviated form <acronym> Denotes an acronym <address> Denotes a mailing address <applet> Officially deprecated; embeds a Java applet <area> Part of the client-side image map syntax <b> Defines the enclosed text as bold print <base> Defines the base URI for the document <basefont> Officially deprecated; defines the base font size for the document <bdo> Internationalization (i18n BiDi override) <big> Defines the enclosed text as extra large print <blockquote> Defines the enclosed text as a block quotation <body> Indicates the body of the web page <br> Inserts a new line <button> Adds a command button to a form <caption> Adds a caption to a table <center> Officially deprecated; centers text horizontally <cite> Citation <code> Defines the enclosed text as code <col> Defines a table column’s properties <colgroup> Groups columns in a table <dd> Definition description for a definition list <del> Defines the enclosed text as deleted text <dfn> Instance definition <dir> Officially deprecated; creates a directory list <div> Defines a block of text as an entity <dl> Creates a definition list <dt> Definition term for a definition list <em> Defines the enclosed text as emphasis print <fieldset> Form control group <font> Officially deprecated; sets the font type for the enclosed text
  • 349. Appendix A: HTML 4.01 Tags 329 <form> Defines an HTML web form <frame> Defines framed content <frameset> Defines a group of frames <h1> Defines heading text, level 1 (largest) <h2> Defines heading text, level 2 <h3> Defines heading text, level 3 <h4> Defines heading text, level 4 <h5> Defines heading text, level 5 <h6> Defines heading text, level 6 (smallest) <head> Indicates the head section of the web page <hr> Inserts a horizontal rule <html> The parent tag of every other element <i> Defines the enclosed text as italic print <iframe> Defines a floating frame <img> Inserts an image <input> Adds a form control to a form <ins> Defines the enclosed text as inserted text <isindex> Officially deprecated; single line prompt <kbd> Defines the enclosed text as text to be entered by the user <label> Inserts a label into a form <legend> The legend for a fieldset <li> A list item for a list <link> A media independent link <map> Defines a client-side image map <menu> Officially deprecated; defines a menu list <meta> Inserts data related to the HTML document (called meta data) <noframes> Alternate content for browsers that do not support frames <noscript> Alternate content for browsers that do not support scripting A <object> Inserts an object into the document <ol> Defines an ordered list <optgroup> Defines a group of options <option> Defines an option for a select list <p> Indicates a paragraph <param> Provides a property to be passed to embedded content
  • 350. 330 How to Do Everything with JavaScript <pre> Defines the enclosed text as preformatted <q> Defines the enclosed text as a short inline quotation <s> Officially deprecated; defines the enclosed text as strikethrough <samp> Defines the enclosed text as sample program output <script> Defines an embedded script <select> Inserts a list box control into a web form <small> Defines the enclosed text as small text <span> Defines inline text as an entity <strike> Officially deprecated; defines the enclosed text as strikethrough <strong> Defines the enclosed text as strong text <style> Defines an embedded style sheet (CSS) <sub> Defines the enclosed text as subscript <sup> Defines the enclosed text as superscript <table> Creates a table <tbody> Defines the table body <td> Inserts a new cell into a table <textarea> Inserts a multiline text form control into a web form <tfoot> Defines the table foot <th> Inserts a new header cell into a table <thead> Defines the table head <title> Gives the document a title <tr> Inserts a new row into a table <tt> Defines the enclosed text as monospace (fixed-width) text <u> Officially deprecated; defines the enclosed text as underlined <ul> Creates an unordered list (bullet points) <var> Defines the enclosed text as a program variable
  • 351. JavaScript Appendix B Quick Reference
  • 352. 332 How to Do Everything with JavaScript This appendix lists the statements and system objects available for use in JavaScript. Table B-1 shows all the statements available for use in JavaScript 1.5. No new statements have been added to the list for JavaScript 2.0. Tables B-2 and B-3 list the system objects for JavaScript 1.5 and 2.0, respectively. Statement Description // Creates a single line of comments /* … */ Creates a block of comments break Jumps out of a loop or switch statement continue Starts a loop over at the next iteration do-while Creates a loop that executes one or more statements as long as the specified condition is true, but always executes it at least once for Creates a loop that executes one or more statements until a counter reaches a set value for-in Creates a loop that iterates over the properties of an object or the contents of an array if-else Only executes code if the specified condition is true label Allows break or continue statements to jump out of nested loops return Causes a function to exit, optionally returning a value switch Chooses to execute only one of several cases based on the value of the specified expression throw Causes an exception to be raised try-catch Intercepts an exception and handles it while Creates a loop that executes one or more statements as long as the specified condition is true with Allows access to the properties and methods of an object without having to use that object TABLE B-1 Statements Available in JavaScript 1.5 and 2.0
  • 353. Appendix B: JavaScript Quick Reference 333 Class Name Description Array Allows lists of data to be stored in a single variable Boolean A wrapper for Boolean values Date Lets you work with dates and times Function Allows you to define a function programmatically Math Contains convenient mathematical constants and functions Number A wrapper for primitive numeric values Object All objects derive from this data type RegExp Provides support for regular expressions in JavaScript String A wrapper for string values TABLE B-2 Built-in System Objects Available in JavaScript 1.5 Class Name Description Array Allows lists of data of type Object to be stored in a single variable; equivalent to the Array[Object] data type Array[type] Allows lists of data of type type to be stored in a single variable Boolean Supports variables that can store only the values true and false char Supports variables that can store only a single character ConstArray Allows lists of data of type Object to be stored in a single constant; is equivalent to the ConstArray[Object] data type ConstArray[type] Allows lists of data of type type to be stored in a single constant DynamicArray[type] Allows resizable lists of data of type type to be stored in a single variable Function The “data type” of functions Integer Supports variables that can only store integers Never Supports variables that cannot contain any value Null Supports variables that can only store the value null Number Supports variables that can only store numbers Object Supports variables that can contain any value B Prototype Supports variables that contain prototype-based objects (JavaScript 1.5’s way of handling objects) StaticArray[type] Allows writable lists of data of type type to be stored in a single variable String Supports variables that can only store strings Type The “data type” of data types Void Supports variables that can only store the value undefined TABLE B-3 Built-in System Objects Available in JavaScript 2.0
  • 354. This page intentionally left blank
  • 355. Index Symbols <!DOCTYPE> tag, 146-147 " (double quotes), for string literals, 74 <?xml?> declaration, 145 "" (empty string), 34, 73, 87 <applet> tag, 315-317, 319 # (pound sign) <applet> tag attributes, 317 as a valid URL, 186 <b> tag, 261, 263 for RGB values, 262 <body> tag/element, 19, 276-277 #special selector, 270 <br> tag, 263 $ (dollar sign), in regular expressions, 87 <button> element, 194 % (modulus) operator, 42 <center> tag, 263 ' (single quotes), for string literals, 74 <div> tag/element, 174-176, 198, 264-265, () (parentheses), for parameter lists, 52 269, 277 (...) rest parameter, 61 attributes, 265 * (asterisk multiplier), 229-230 with id attribute of special, 270 */ (asterisk slash), block comment ending, 44 <embed> tag, 315, 321-324 ++ operator, 35 attributes, 321 . (dot) operator, 73, 77-78 height attribute, 321 .class file (Java), 316 src attribute, 321 .css files, 267, 269-270 width attribute, 321 .java code file, 316 <font> tag, 261-263 .js file extension, 157 <font> tag color attribute, 262 .NET Framework (Microsoft), 14 <form> tag/element, 184-186 . (dot) operator, 73, 77-78 action attribute, 185-186, 195 .class file (java), 316 attributes, 184-185 .java code file, 316 event handlers, 195 .js file extension, 157 method attribute, 195 .NET Framework (Microsoft), 14 onsubmit attribute, 195-197, 220 / (forward slash) submit() method, 219-220 in HTML, 143 <frame> tag, 225-226 in regular expressions, 87, 89 attributes, 233-234 /* (slash asterisk), block comment beginning, 44 frameborder attribute, 235 // (double forward slashes), as comment markers, name attribute, 235 19, 44 noresize attribute, 235 : (colon) src attribute, 234 label ending, 43 <frameset> tag/element, 225, 229 separating properties and values, 122 attributes, 225 ; (semicolon) onload and onunload event handlers, 226 for appending JavaScript commands, 159 rows and cols attributes, 227-232 statement ending, 100 <head> tag, 18, 226 < and > (angle brackets), in HTML, 142 <h1> header tag, 19 <!-- and --> HTML comment markers, 19, 144, 156 <html> tag, 18, 145 335
  • 356. 336 How to Do Everything with JavaScript <i> tag, 261 Access key, key combination to activate, 189 <img> tag/element, 211, 276 Accesskey parameter, 189 attributes, 218 Activate event, 209 id attribute, 275 ActiveMovie control (Microsoft), 321-323 src attribute, 211 ActiveScript, 142 <input> element, 187, 194, 271 ActiveX controls, 321, 324 default type, 186 ActiveX (Microsoft), 314 maxlength attribute, 189 Address bar (browser), 258 size attribute, 189 Adobe Acrobat PDF documents, 142 value attribute, 189, 194 Adobe GoLive, 12-13 <layer> tag, 172-175 Alert box, 20-21, 197 <link> element, 267, 269 Alert message, displaying, 20-21, 288-289 <meta> tag, 147-148 Alert (message) box, 288-289 <meta> tag attributes, 147 Alert() method, 288 <noframes> tag, 226-227 Allaire Corporation, 11 <noscript> tag, 154-156 Ancestor, class as, 130 <object> tag/element, 315, 321-322, 324 Angle brackets (< and >), in HTML, 142 <object> tag classid attribute, 321-322 Animate() function, creating, 275 <option> element, 189, 193 Animating text, 277 <option> element attributes, 193 Animation, 259-278 <param> tag, 318-319 explained, 260 <script> tag/element, 16, 153-154, 158, 198 using JavaScript for, 274-278 attributes, 19, 153-154 using timer events, 274 in an HTML page, 17-18 API (application programming interface), 244 language attribute, 153 Apple Quicktime Player, 322 src attribute, 157 Applets (Java), 5, 315-320 type attribute, 154 Application error, defined, 46 <select> element, 189 Array of arrays, 110, 112 attributes, 192 Array class, 102 for a list box, 217 Array class subclasses, 111 multiple attribute, 191 Array elements size attribute, 191-192 accessing, 104-106 <span> element, 265 restricting to type, 113 <span> element attributes, 265 Array index, 96, 104-105 <style> tag/element, 151, 264, 266-267 Array literals, 100-101 <textarea> element, 193, 198 Array object, 96 <textarea> element attributes, 193 creating, 97-104 <title> tag, 147 index property, 101 ? (question mark), in expression matching, 34 input property, 101 [] (square brackets operator), 73, 96, 104-106 length property, 99, 101 ^ (caret), in regular expressions, 87 methods, 102-104 { and }, for enclosing statements, 32 properties and methods, 101-104 {} (curly brackets), for object literals, 122 Array of zero length, 97 (backslash), in regular expressions, 88-89 Arrays, 95-115 double backslash (escaped backslash), 89 creating empty, 97-99 d tokens, in regular expressions, 87-88 creating and initializing in one code line, 100 , (comma) creating using the Array class, 102 separating parameters, 52 JavaScript 2.0 enhanced, 111-112 separating property-value pairs, 122 of long lists, 100 multidimensional, 107-115 with numerical indexes, 106 A parallel, 109-110 Abort event, 216 setting and retrieving values in, 104-106 Absolute positioning, 258 specifying an initial length for, 99
  • 357. Index 337 As operator, 51 Browsers ASCII codes, 214 checking your code on, 312 ASP .NET platform, 14 detecting, 174 ASP (Application Server Page), 142 detecting the type running, 164-169 ASP web page, form that submits itself to, 195 DOMs of, 14, 162 Asterisk (*) multiplier, 229-230 first JavaScript-enabled, 6 Asterisk and slash (*/), block comment ending, 44 getting for testing your code, 312 Attributes, explained, 184 interacting with, 243-258 AVI files, 321 with no support for frames, 226-227 redirecting to a new web page, 258 reliance of on external plug-ins, 315 B sending back to previous page(s), 257 Backslash (), in regular expressions, 88-89 testing on all, 312 Block comments, 44 that don't support scripting, 154-156 Blur event, 209-210 using the latest release, 163 Blur event firing order, 210 web surfer use of, 162-163, 169 Blur() method, 220 Bug, defined, 278 Body section (HTML document), 18-19, 145 Button caption, 194 Boolean data type, 27, 91 Button controls (form), 193-194, 220, 320, 323 converting other data types to, 31 Buttons (form), 193 expressions that return, 50 Byte, 91 for loaded frames, 239-240 Boolean literals, 91 Break statement, 34, 40-41, 58 C Breakpoints, in debugging, 293 Calculators (online), 182-183 Browser address bar, 258 Calendar Control (Microsoft), 324-325 Browser compatibility issues, 162-170 Call stack, 102 of code, 171-177 Calling a function, 53 of DHTML, 171 Captions for push buttons, 194 of events, 220-221 Capturing an event, explained, 208 of styles, 272-273 Caret (^), in regular expressions, 87 Browser DOMs, 14, 162 Case clauses, 33-34 Browser error messages, interpreting, 282 Catch blocks, Netscape conditional, 302 Browser events, 158 Catch clause, 297-304 handling, 207-221 Catching, explained, 195 supported by Internet Explorer, 199 Change event, 216 Browser frames. See Frames (browser) Changeimage() function, 211-212, 274 Browser history list, 257-258 Char data type, 91-92 Browser market features competition, 170 Checkform() function, 200-202 Browser plug-ins, 254, 313-325 Checkkey() function, 214 Browser refresh, 258 Child classes, 131 Browser sniffing code, 221 Child nodes, 246 Browser software properties, 254-256 Class attribute of HTML elements, 265 Browser status bar, 253 Class inheritance, benefits of, 132-133 Browser support for methods, 169-170 Class members, 68 Browser timers, 251 public vs. private, 136 Browser type, detecting, 164, 167, 256 static vs. instance, 135-136 Browser usage statistics, 163 Class properties, 78. See also Properties Browser version accessing, 120, 128 detecting, 164 creating by assigning a value, 126 knowing the minimum needed, 15 defining in JavaScript 2.0, 127 Browser window, 252-254 inherited, 131, 134 resizing and centering, 256-257 Classes writing text to, 21-22 adding constructor functions to, 127
  • 358. 338 How to Do Everything with JavaScript adding methods and properties to, 123-125 Confirm box, 21 as ancestors, 130 Console (JavaScript), 283, 286-287, 290-291 attaching functions to, 124 Const keyword, 28 built-in, 63-93 Constants, 27-29, 67, 114-115 and code reuse, 308 ConstArray, creating, 114-115 containing multiple constructors, 131 ConstArray class, 114-115 creating, 117-137 Constructors (constructor functions), 72 creating methods using, 128 adding to classes, 127 defining functions in, 128 calling, 119-121 defining in JavaScript 2.0, 127-129 class containing multiple, 131 extending, 123-125 creating, 119 inheriting properties and methods, 131, 134 creating objects from, 121 instantiating using the new keyword, 128 Continue statement, 40-41 JavaScript 1.5, 70 Control focus, explained, 188 organizing using inheritance, 130-135 Control name, accessing a control by, 200 for shopping cart items, 308 Cookies, explained, 248 testing, 308 Copy and paste, code reuse by, 122 turning properties and functions into, 68-69 Counter variable, 28, 55-56 using as data types, 71 Cross-browser compatibility issues, 162-170 Classid attribute (<object> tag), 321-322 of code, 171-177 Click() method, 220 of DHTML, 171 Clickme() function, 220 of events, 220-221 Client, defined, 8 of styles, 272-273 Client-server analogy, 8 Cross-frame scripting, security risks of, 239 Client-server communication, 184 CSS attributes, 268 Client-side forms, 182-183 vs. JavaScript property names, 272-273 Client-side JavaScript list of, 269 defined, 8 reference guide to, 268 processing form input, 182-183 CSS (Cascading Style Sheets), 150-153. See also Client-side language, JavaScript as, 14 Style sheets Closing tags (HTML), 142-143 basics of, 260-273 Code reuse benefits of, 150 by class inheritance, 132 vs. frames, 224 by copy and paste, 122 selectors in, 266-267 using classes and objects, 308 sizing and positioning, 269-270, 276-277 Colon (:) why they are cascading, 261 label ending, 43 CSS Level 1 standard (W3C), 261 separating properties and values, 122 CSS positioning attributes, 270 Colors, specifying in HTML, 262 animation using, 276-277 Cols attribute (<frameset> tag), 227-232 defining, 269 Commas CSS validator service (W3C), 273 for separating parameters, 52 Curly brackets ({}) for separating property-value pairs, 122 for enclosing statements, 32 Comment markers, HTML vs. JavaScript, 19, 44 for object literals, 122 Commenting out a function (in debugging), Current date and time, retrieving, 64 289-290 Comments HTML, 19, 144, 156 D JavaScript, 19, 43-44 Data integrity, private class members for, 136 uses for, 44, 289-290 Data lists. See Array object; Arrays Compiler, defined, 9 Data storage, 26-29 Componentizing a program, 307 Data types (JavaScript 2.0), 28, 59, 69-71, 91-93 Compound attributes, explained, 268 converting to Boolean, 31 Conditional catch blocks (Netscape), 302 using classes as, 71 Conditional statements, 30-34
  • 359. Index 339 Date class, 64, 79-80 DOS/Windows environment, JavaScript in, 9 Date class constructor formats, 82 Dot operator (.), 73, 77-78 Date constructor, 80, 82 Dothis() function, 194 Date object, 79-80, 124 Double backslash (), 89 Date object getMonth() function, 99 Double forward slashes (//), for comment markers, Date object methods, list of, 80-82 19, 44 Date-handling functions, 79-82 Double quotation marks ("), for string literals, 74 Debuggers, 291-293 Douglas Crockford's JavaScript Lint validator, 287 Debugging code Do-while loop, 37 adding to programs, 287-290 Dreamweaver MX, 10-12, 291 explained, 288 Drop-down list box control, 189-190, 217, 251-252 Debugging (of JavaScript programs), 281-293 Dynamic list box, 251-252 defined, 278 Dynamic style modifications, 270-272 designing for easy, 306-308 Dynamic text, marking, 265 use of breakpoints, 293 Dynamically loading images, 274-276 using commenting for, 289-290 DynamicArray, creating, 114 Debugging software, 291-293 DynamicArray class, 114 Default clause (switch statement), 34 Default object, setting, 44-46 Deprecated HTML tags, 145-146 E Developers testing their own programs, 311 ECMA (European Computer Manufacturers Development environments, 7-13 Association), 5, 59 DHTML (Dynamic HTML), 151, 171-177 ECMAScript, 6 DHTML menu, 172 ECMAScript Edition 4 standard, 6 Display settings (operating system), 256-257 ECMAScript specification, 287 Document model, querying, 169-170 800 by 600 resolution, 256 Document object, 248-252 Elements array, for accessing form values, 202-203 arrays, 248 Else clause, 32 body property, 249 Else-if clause, 32 forms array, 200-202 E-mail, form contents in, 185 in Internet Explorer 6.0, 74 Embedded multimedia, plug-ins for, 254 methods, 248 Embedded style sheets, defining, 266-267 using to update the time, 251 Empty arrays Documentation, using comments for, 144 creating, 97-99 Document.write() function, 21-22, 42, 54, 58, testing for potential use of, 311 248, 288 Empty function, defining, 119 Dollar sign ($), in regular expressions, 87 Empty string (""), 34, 73, 87 DOM (browser), 14, 162 Environments, JavaScript versions in different, 142 DOM (Document Object Model), 5, 8, 244 Error checking, stricter level of, 283 basics of, 245-248 Error details in IE, 285 document parts considered nodes, 246 Error event, 216 explained, 244 Error handling, 46-49 objects in, 245 Error icon, 283 DOM (JavaScript), 7 Error message box (in IE), 284 DOM Level 1 (DOM 1), 169, 246 Error messages, 47 DOM Level 3, 247 finding the source of, 284-285 DOM Level 2, 246, 247 interpreting, 282, 285-287 DOM Level 2 Events specification, 208 in JavaScript console, 286-287 DOM Level 0, 245 line numbers listed in, 285-286 DOM methods, checking before using, 169-170 Error object (IE), 298, 301 DOM 1 hierarchy (DOM tree), 246 creating, 301 DOM standard (W3C), 8, 244 properties, 301 DOM traversal, 247 Error reporting, turning off and on, 282-284 DOM tree, 246-247 Error string (Netscape), 298
  • 360. 340 How to Do Everything with JavaScript Error types in JavaScript, 283 External JavaScript file, loading, 157-158 Error-handling code, testing, 311 External styles, importing, 267 Errorproofing a program, 295-312 Errors, 46 causes of, 282-287 F detecting programmatically, 48 F (float) suffix, 71 forcing to test error-handling code, 311 FactorString variable, 57 returning back to the program, 296 FIFO (first in first out) order, 102 sources of, 163 File, escaping, 85 things that can go wrong, 46 Finally clause in try-catch statement, 302-304 Escape() function, 85 Finally clauses (nonstandard), 302-304 Escaped character sequence, 85 FireEvent() method, 220 Escaping a file, explained, 85 Firing of events, order of, 209-210, 212-213 Event attributes, setting, 218 Flash files (Macromedia), 142 Event bubbling, 219 Float number (F) suffix, 71 Event firing test, 210, 212-213 Focus (control), explained, 188 Event handlers, 185, 208 Focus event, 209-210 <form> element, 195 Focus event firing order, 210 returning false, 213 Focus() method, 220 setting for HTML tags, 218 Font attribute, 268 using the event property, 218 Font style elements (HTML 4.01), 148-149 viewing, 218 For loop, 37-38, 252 writing, 208-217 For-in loop, 38-40, 61, 73, 105-106 Event handling (browser events), 207-221 iterating over an array, 106 Event names, capturing, 199 iterating over a hash table, 105 Event property, 218 Form control values, 200-205 Event triggering in JavaScript, 219-220 accessing with getElementById(), 204 Events specification (DOM Level 2), 208 accessing with getElementsByName(), 204 Events (web form), 185-186, 188, 192, 208 accessing with getElementsByTagName(), 205 and browser incompatibility, 220-221 accessing using an elements array, 202-203 cancelling, 213-214 accessing using a forms array, 200-202 capturing, 208 Form controls catching on form controls, 197-199 catching events on, 197-199 categories of, 209 currently active, 188 first handled by innermost element, 219 list of, 187 form control programmable, 197-199 programmable events, 197 intercepting, 208 testing for existence of before accessing, 241 invoking JavaScript in response to, 158 Form-handling programs, technologies to create, 183 order of firing, 209-210, 212-213 Forms array, 200-202, 248 that are not specified by standards, 221 Forms (web), 179-206 Exception bubbling, 299-301, 304 adding controls to, 186-195 Exceptions, 296-297 getting in e-mail, 185 catching using try-catch, 297-304 handling user input, 180 creating using the throw statement, 304-306 initializing, 217 re-throwing, 305 onfocus/onblur/onchange events, 188, 192 unhandled, 303 onsubmit and onreset events, 186 Expandable tree menu using DHTML, 173 processing with client-side JavaScript, Expressions, 27, 31-32, 38, 49-50 182-183 as parameters to function, 50 processing input on a web server, 183-184 list of types of, 49 requesting user input, 181-182 that return Boolean values, 50 submissions with onsubmit, 195-197 Extends keyword, 130
  • 361. Index 341 Fortran, 64 Functions (JavaScript), 27, 51-59, 68, 277 Forward slash (/) attaching to classes, 124 in HTML, 143 attaching to objects, 124-125 in regular expressions, 87, 89 calling, 53 Frame borders, making invisible, 235 calling from frames, 235-238 Frame size values in classes, 68-69 absolute, 228-230 commenting out (in debugging), 289-290 relative, 229-230 debugging, 289-290 setting, 227-230 defined, 27, 68 Frames array, 237, 253 defining, 52-55, 119, 128 Frames (browser), 223-241 defining inside classes, 128 absolute size of, 228-230 to detect browser type, 167 accessed by name, 237 empty, 54, 119 accessing in a different domain, 239 for error-checking, 297 accessing using JavaScript, 236-237 forcing to return hard-coded values, 289-290 assigning names to, 235 hyperlinks calling, 158-159 benefits of, 224 to improve organization and readability, 307 Boolean variable for loaded, 239-240 specific to version 2.0, 59-61 and browsers that do not support, 226-227 syntax of, 52 calling JavaScript functions from, 235-238 testing, 308 cascading effect between, 239 testing for existence of before vs. CSS, 224 accessing, 241 defined, 224 that cause the program to exit, 93 defining and naming, 233-235 that do not return a value, 92-93 horizontal, 230-231 triggering with onclick event, 320 limiting the number of, 228 problems of, 224 relative size of, 229-230 G synchronization between, 239-241 GetElementById() method, 169-170, 175, 204, 248, testing for existence of, 241 274, 319 vertical, 230-231 GetElementsByName() method, 204, 248 Frameset document HTML code, 226 GetElementsByTagName() method, 205 Frameset HTML, explained, 146 GetMonth() function, 99 Frameset layout, 226 GoLive (Adobe), 12-13 Framesets, 224 GUI (graphical user interface), 4 with both rows and columns, 232 creating in HTML, 225-233 defining and naming frames in, 233-235 H and frame size, 228 nested, 233-234 Hash tables, 104-105 FrontPage Explorer, 10-11 Header section (HTML document), 18-19, 145 FrontPage Server Extensions, 10 Height attribute, 270 FrontPage 2002, 10 Hexadecimal color values, 262 Function keyword, 52 Hierarchical tree, 130 Function parameters, 52, 54-56 History object, 257-258 expressions as, 50 History object go() method, 257 named, 60-61 History object length property, 257 passed by value, 56 History object methods, 257 unlimited number of, 61 HomeSite 5, 11-12 unnamed, 61 Horizontal frames, defining, 230-231 Function syntax, 52 HTML comments, 19, 144, 156
  • 362. 342 How to Do Everything with JavaScript HTML document for formatting a page, 261-263 body section, 145 for formatting text, 148-150 building, 145-146 proprietary, 170-171 in a DOM tree, 247 setting an event handler for, 218 head section, 145 start tag, 145 keywords in, 147-148 HTML testing harness, 310 parts of, 18-19 HTML validation service, 170 title for, 147 HTTPS protocol, 190 HTML editors, 10-13 Hyperlink HTML elements to simulate a submit button, 219 ID attributes of, 204 using to call JavaScript, 158-159 inheritance of style attributes, 261 style attributes, 261, 266 style/class/id attributes, 265 I using to assign style, 261-263 Id attribute of HTML elements, 204, 265 HTML event handling, 215-217 IDEs (integrated development environments), HTML events, 209, 215-217 7, 296 HTML files for frames and frameset, 235 IE (Microsoft Internet Explorer), 8, 162 HTML form controls, list of, 187 ActiveX controls for, 314 HTML forms, 180-199 browser events supported by, 199 adding controls to, 186-195 calling the submit() method, 220 client-server communication when error details, 285 submitted, 184 error message box, 284 with client-side JavaScript, 182-183 Error object, 298, 301 inserting on a web page, 184-199 JavaScript in, 5 onfocus/onblur/onchange events, 188, 192 navigator.appName property, 165 onsubmit and onreset events, 186 navigator.appVersion property, 166 processing input on a web server, 183-184 Object expected message, 286 requesting user input, 181-182 turning error reporting off and on, 282-284 HTML 4.01 IE 6.0 font style elements, 148-149 document object in, 74 phrase elements, 148-149 interpreting the <div> tag, 176 HTML 4.01 tags, complete list of, 328-330 IE web site, 16 HTML frames, 224-235 If keyword, 302 HTML (Hypertext Markup Language), 4. See also If statement, 31-32, 170, 240, 297 HTML elements; HTML tags checking the format of, 287 basic structure of, 142-153 forms of, 32 creating framesets in, 225-233 If-else statement, 32 testing JavaScript programs with, 16-19 If-else-if statement, 33 text formatting, 148-153 IIS web servers, 142 user controls in, 180-181 Image rollover effects, 212 viewing underlying, 144 Images HTML markup tags. See HTML tags dynamically loading, 274-276 HTML tag names, lowercasing, 146 inserting, 211 HTML tags, 142 switching to animate, 274-276 <A HREF>, 158 Images array, 248 <noscript>, 154-156 Incrementor section (for loop), 38 <script>, 153-154, 157 Index (array), 96, 104-105 <style>, 151 IndexOf() method, 78 to add scriptable objects, 315 Infinite loop, 35, 38 closing tags, 142-143 Inheritance, 130-135 complete list of, 328-330 benefits of, 132-133 deprecated, 145-146 of web page style attributes, 261 end tag, 145 Initialize() function, 217
  • 363. Index 343 Initializer section (for loop), 38 what it can and cannot do, 13-15 Inline styles, defining, 265-266 what it is, 4 Inline text, 265 what not to use it for, 15 Input-output functionality, 244 where it is today, 6-7 Instance members, 135-136 which version to use, 15 defined, 78 JavaScript Console, 283, 286-287, 290-291 vs. static members, 78 JavaScript debugger, 291-293 Instantiating an object, 72 JavaScript DOM, 5, 7 Integer data type, 91 JavaScript Editor (C Points), 291 Integers, range of values for, 28 JavaScript environments and object models, 244 Interfaces, 132 JavaScript file, loading external, 157-158 Internet, privacy and, 190 JavaScript Lint validator, 287 Internet search engines, specifying keywords for, JavaScript 1.5 147-148 complete list of statements, 332 Invalid date, testing for potential use of, 311 core classes, 70 Invalid inputs, testing for potential use of, 311 creating objects in, 118-126 IPlanet Web Server, 14, 142 list of system objects, 333 Is operator, 51 reasons for errors, 283 JavaScript releases, chronology of, 7 JavaScript templates, 16-19 J JavaScript 2.0 Java applets, 5, 315-320 added features, 13-14 Java compiler, 316-317 breaking code into manageable chunks, 307 Java language, 315 breaking long lines of code, 100 Java SDK (Software Development Kit), 317 browsers that don't support, 15 JavaScript (see also JavaScript 1.5; JavaScript 2.0) complete list of statements, 332 adding to a Web page, 153-154 creating objects in, 126-137 appending, 159 data types, 28, 59, 69-71 as a client-side language, 14 defining classes, 127-129 as a scripting language, 4 enhanced arrays, 111-112 as a server-side language, 14-15 extra spaces in code, 100 as an official standard, 5 functions, 59-61 calling using hyperlinks, 158-159 interfaces and, 132 comments, 19 list of system objects, 333 debugging, 281-293 new data types, 91-93 designing for easy debugging, 306-308 new operators, 51 developed using a text editor, 296 newline character in code, 100 development tools, 9-13 JavaScript versions, 7 distributed as source code, 296 in different environments, 142 errorproofing, 295-312 specifying version numbers, 164 for form control values, 200-205 Javascript: prefix (in HREF URL), 159 fundamentals of, 25-61 JavaScript-enabled web browser, the first, 6 history of, 4-7 JavaScript-enabled web pages, developing, 7 in DOS/Windows environment, 9 JRE (Java Runtime Environment), 317 in Internet Explorer, 5 JScript (Microsoft), 5-6, 9 managing browser plug-ins with, 313-325 JSP (Java Server Page), 5 origin of, 5 JVM (Java Virtual Machine), 315, 317 vs. other languages, 13 programming terms, 27 quick reference to, 331-333 K reasons for errors in, 283 Key event firing order, 213 replacing with HTML text, 156 Key event handlers, 212-214 testing using HTML, 16-19 Key events, 209, 212-214 types of errors in, 283 Key (index), 105
  • 364. 344 How to Do Everything with JavaScript KeyCode property of window.event object, 214 embedding a Media Player 9 object, 322 Keydown event, 213-214 Media Player 6.4, 322 Keypress event, 213 Members (class), 68 Keyup event, 213 Methods, 44-45 Keyword, defined, 27 adding to classes, 123-125 Keywords in HTML documents, 147-148 attaching to objects, 125-126 browser support for, 169-170 calling, 129, 137 L calling public, 137 L (long) suffix, 71 checking before using, 169-170 Label names, 43 of a class, 78, 123-125 Labeling a loop, 43 creating using classes, 128 Labels (named lines of code), 42-43 defined, 67 Language attribute (<script> tag), 19 inherited, 131, 134 Layers (in Netscape 4), 169, 172-174 private, 73 LIFO (last in first out) order, 102 Microsoft ActiveMovie control, 321-323 Line numbers in error messages, 285-286 Microsoft ActiveX, 314 List box controls (form), 189-193 Microsoft ASP .NET platform, 14 Lists, storing, 96 Microsoft Calendar Control, 324-325 Literal, defined, 27 Microsoft FrontPage, 10 LiveWire server-side language, 14 Microsoft IE web site, 16 Load event, 215-216 Microsoft IIS web server, 142 Location object, 258 Microsoft JScript, 5-6 Location object methods, 258 Microsoft .NET Framework, 14 Location object properties, 258 Microsoft Script Debugger, 293 Logic errors, 283 Microsoft Script Editor, 291 Long integer, 71 MIME standard, 154 Long lines of code, breaking, 100 MIME type, 154 Loops, 34-43 Modifylayer() function, 198-199 labeling, 43 Modular programming, 66 nested, 42 Modules, 66 uses for, 34 Modulus (%) operator, 42 Low-level data types, 71 Months, converting numeric to string, 99 Mouse event handling, 211 Mouse events, 209 M list of, 211 tracking, 211 Machine type suffixes, 71 Mouseout events, 211-212 Machine types in JavaScript 2.0, 71-72 Mouseover events, 211-212, 274 Macromedia Dreamweaver MX, 10-12, 291 Moveball() function, creating, 277 Macromedia Flash files, 142 Movies, embedding in web pages, 321-324 Macromedia Flash plug-in, checking for, 255 Mozilla JavaScript Debugger, 292 Macromedia HomeSite 5, 11-12 Mozilla web browser, 8 Mailto: protocol, 185 MSDN CSS attributes reference guide, 268 Main frame, 224 Multidimensional arrays, 107-115 Manual line breaks (<br>), 263 Music, embedding in web pages, 321-324 Master array, 110-111 Music objects, connecting to with JavaScript, Math class, 78 322-324 Math class static constants, list of, 79 Math object, 78 Math object static methods, list of, 79-80 N Mathematical functions, 78 Media objects, connecting to with JavaScript, Named keyword, 60-61 322-324 Named parameters, 60-61 Media Player (Windows), 321 NaN (Not a Number) constant, 71
  • 365. Index 345 Navigator 4.0 (Communicator), 8 accessing with [] operator, 73 Navigator object, 164, 254-256 attaching functions to, 124-125 appName property, 165 attaching properties and methods to, 125-126 appVersion property, 166, 168-169 and code reuse, 308 properties, 164-169, 255-256 creating, 117-137 userAgent property, 166, 168, 175 creating as object literals, 122 Navigator 6, 8 creating in JavaScript 1.x, 118-126 Navigator 2.0 browser, 5-6 creating in JavaScript 2.0, 126-137 Nested framesets, creating, 233-234 creating from one constructor, 121 Nested loop, 42 creating using the new keyword, 129 NetObjects Fusion 7, 13 creating using an object literal, 123 Netscape Browser Central, 16 defined, 67 Netscape Communications, 5 extending, 125-126 Netscape Enterprise Server, 14 setting default, 44-46 Netscape 4 web browser testing, 308 layers in, 169, 172-174 Officially deprecated, explained, 145 style sheets in, 273 Onblur event (form), 188, 192 Netscape Navigator 4.0 (Communicator), 8 Onchange event (form), 188, 192 Netscape Navigator 6, 8 Onclick event (button), 220, 320 Netscape Navigator 2.0 browser, 5-6 One-dimensional arrays, 107 Netscape Plug-In API, 314 Onfocus event (form), 188, 192 Netscape 7.0, interpreting the <div> tag, 177 Onload event handler, 215-217, 226, 276-277 Netscape web browsers Onmouseout <img> tag attribute, 218 error string, 298 Onmouseover <img> tag attribute, 218 navigator.appName property, 165 Onmouseover event handler, 211 navigator.appVersion property, 166 Onpaste event handler, 221 original DOM, 245 Onpaste event (text box control), 221 syntax for catch clauses, 302 Onreset event (form), 186 Netscape/iPlanet web servers, 142 Onsubmit event (form), 186, 195-197 Never data type, 93 Onunload event handler, 226 New keyword/operator, 69, 72, 78, 97, Operands,defined, 27 128-129, 301 Operating systems Nodes (hierarchies of data), 246 display settings, 256-257 Nonbreaking spaces (&nbsp), 263 testing on all, 312 Nonstandard coding practices, 170 Operators, 27, 50-51 Null data type, 93 JavaScript 2.0 new, 51 Number data type, 91 types of, 50 Number primitive, 91 Outer frameset, 233 Numbers, converting strings into, 82-84 Numeric literals, assigning to a variable, 71 Numeric to string conversion, 99 P Numerical indexes, arrays with, 106 Parallel arrays, 109-110 Parameter lists in parentheses, 52 Parameters (to functions), 52, 54-56 O expressions as, 50 Object arrays, 113 named, 60-61 Object data type, 92 passed by value, 56 Object instantiation with the new operator, 72 unlimited number of, 61 Object literal, 122-123 unnamed, 61 Object methods. See Methods Parent class, defining, 130 Object models, JavaScript environments and, 244 Parent object (window), 253 Object properties. See Properties Parent-child relationship, 130 Object-oriented programming, 66-69, 118 Parentheses (), for function parameter lists, 52, 54 Objects, 44, 64-69 ParseFloat() function, 82, 84
  • 366. 346 How to Do Everything with JavaScript ParseInt() function, 82-83 Password box with asterisks displayed, 190 Q Pattern matching (regular expressions), 86-87 Question mark (?), in expression matching, 34 PDF documents (Adobe Acrobat), 12, 142 Queue, 102 PDF (Portable Document Format), 12, 142 Perl language, 9 Phrase elements (HTML 4.01), 148-149 R Plug-ins Real estate, 256 defined, 314 RegExp object explained, 254 creating patterns with, 89-90 list of URLs for, 314 methods of, 89 managing with JavaScript, 313-325 Regular expression language, 87-88 Plugins array, 254 Regular expression literal, 89 Polymorphism, 92, 133 Regular expressions, 86-90 Pop-up dialog boxes, types of, 20 pattern matching, 86-87 Pop-up web advertisements, 254 special tokens, 88-89 Pop-up window, 254-255 syntax of, 88-89 Position attributes (CSS), animation using, 276-277 uses for, 87 Positioning elements on a Web page, 268-270 Reset event, 215 Pound sign (#) Resize event, 216 for <form> action attribute, 186 Rest parameter (...), 61 for RGB values, 262 Re-throwing an exception, 305 Practical Browser Sniffing Script, 168 Return statement, 53, 58-59 Primitives, 91 Return values (function), 58, 297 Privacy and the Internet, 190 RGB (red-green-blue) values, 262 Private class members, 136 Rows attribute (<frameset> tag), 227-232 Private keyword, 136 Rule selectors, 266-267 Private properties and methods, 73 Run-time errors, 283 Procedural programming, 65-66, 308 Procedures, 65 Program errors, catching, 48-49 Program flow, 29-30 S Programming methodologies, 65-68, 306 Screen object, 256 Programming terms, 27 Screen object properties, 256 Properties, 44, 67 Screen size, 256 accessing, 120, 128 Screen space, resizing components based on, 256 accessing with [] operator, 73 Script, defined, 4 adding to classes, 123-125 Script Debugger (Microsoft), 293 attaching to objects, 125-126 Script debugging, disabling in IE, 284 of a class, 68-69, 78 Script Editor (Microsoft), 291 creating by assigning a value, 126 Scriptable objects, inserting into web pages, 315 inherited, 131, 134 Scripting language, 14 private, 73, 136 Scroll bar (vertical), multiline text box with, 191 Property names (JavaScript) Scroll event, 216 case-sensitivity of, 122 Scrollable pop-up window of multiple choices, 190 vs. CSS attribute names, 272-273 Scrolled list box control, 189, 191 Proprietary events, 221 Search-and-replace, with regular expressions, Proprietary extensions, avoiding, 273 86-90 Proprietary markup tags, 170-171 Security, private class members for, 136 Prototype property, 123 Select event, 216 Prototyping, 123 Self object (window), 253 Public class members, 136 Semicolon (;) Public keyword, 136 for appending JavaScript commands, 159 Public methods, calling, 137 statement ending, 100 Push button control (form), 193-194, 220, 320, 323
  • 367. Index 347 Server, defined, 8 Style sheet @import command, 267 Server-based web applications, creating, 8-9 Style sheet rules, 266 Server-side JavaScript (SSJS), 8, 14-15, 142 Style sheets, 150-153, 261 SetTimeout() function, 251 advantages of, 264 Show Details button (IE error message box), 284 creating, 276 Sibling nodes, 246 defining embedded, 266-267 Signed scripts, 8 vs. frames, 224 Single quotation mark ('), for string literal, 74 in Netscape 4 web browser, 273 Slash and asterisk (/*), for block comment, 44 Styles, 260 Special data types, 92-93 assigning using HTML elements, 261-263 Square brackets ([]) operator, 73, 96, 104-106 browser platform issues of, 272-273 Src attribute changing for all pages at once, 267 of <embed> tag, 321 importing external, 267 of <frame> tag, 234 modifying using JavaScript, 270-272 of <img> tag, 211 precedence of, 267 of <script> tag, 157 for text boxes, 271 SSL (Secure Sockets Layer), 190 using style sheets for, 264-267 Standards. See W3C Submit button, 193, 195-196 Starting tags (HTML), 142 disabling, 205 Statement block, 32 hyperlink to simulate, 219 Statements, 27, 30-49 Submit event, 215 categories of, 30 Submit() method (<form> object), 219-220 lists of JavaScript 1.5 and 2.0, 332 Sun Microsystems, 14, 317 Static (class) members, 68, 135 Sunny Day Syndrome, 311 defined, 78 Switch keyword, 33 vs. instance members, 78 Switch statement, 33-34 Static keyword, 135 Syntax errors, 283 StaticArray, creating, 112-113 System classes, 63-93. See also Classes StaticArray class, 112-113 System errors, 46, 48 Status bar (browser), 253 System objects (see also Objects) Storing data, 26-29 in JavaScript 1.5, 333 Storing lists, 96 in JavaScript 2.0, 333 Strict HTML, explained, 146 System testing, 312 Strict mode (error checking), 283 String class constructor, 76 String data type, 76, 91 T String literal, 74-75 Tags (HTML). See HTML tags defined, 74 Templates (JavaScript), 16-19 throw statement passing, 305-306 body section, 19 String object creating in Notepad, 16-17 creating, 73-78 Testing harness, creating, 309-311 creating using string data type, 76 Testing your code, 282, 309-312 creating using a string literal, 74-75 Text indexOf() method, 169 animating, 277 length property, 75 marking dynamic, 265 methods, 76-77 preparing for sending to web server, 84-85 Strings, 27 writing to the browser window, 21-22 converting into numbers, 82-84 Text area control, 193 converting numbers to, 99 Text block with invalid characters, 85 explained, 265 using as array indexes, 104 naming, 269 valid, 73 Text box control events, capturing, 197 ways to create, 74 Style attribute of HTML elements, 265-266, 268
  • 368. 348 How to Do Everything with JavaScript Text box controls (form), 186-189 Variables, 27, 67 attributes, 187-188 assigning numeric literals to, 71 onpaste event, 221 in classes, 68 style of, 271 defined as machine types, 71 Text editor, 9-10 defining, 27-29, 55 Text formatting number of defined by a program, 96 HTML elements for, 148-150 scope of, 56-58 with style sheets, 150-153 testing for existence of before accessing, 241 This object, 119 VBScript (Visual Basic Script), 5, 9 Three-dimensional arrays, 107 Versions of JavaScript in different environments, 142 Throw statement, 48-49, 297, 304-306 Vertical frames, defining, 230-231 Time, keeping correctly updated, 250 Vertical scroll bar, multiline text box with, 191 Timer events, animation effect using, 274 Visibility attribute, 270 Today variable, 64 Visual Studio .NET, 14 Top object (window), 253 Void data type, 92-93 Transitional HTML, explained, 146 Triggering events, 219-220 Try clause, 297-304 W Try-catch statement finally clause, 302-304 Web advertisements (pop-ups), 254 Try-catch statements, 47-48, 297-304 Web browser address bar, 258 Two-dimensional arrays, 107-110, 112 Web browser compatibility issues, 162-170 Type attribute (<script> tag), 19 of code, 171-177 of DHTML, 171 of events, 220-221 U of styles, 272-273 UL (ulong) suffix, 71 Web browser DOMs, 162 Unhandled exceptions, 303 Web browser error messages, interpreting, 282 Unicode character set, 214 Web browser events Unload event, 215 explained, 158 Unnamed parameters, 61 handling, 207-221 Unsigned long (ulong/UL), 71 supported by IE, 199 Unstructured programming, 65, 307 Web browser frames. See Frames (browser) Update_time() function, 250-251 Web browser history list, 257-258 URL format, 84 Web browser market features competition, 170 URL string, characters in, 84 Web browser plug-ins, managing, 313-325 URLs (Uniform Resource Locators), 84 Web browser refresh, 258 U.S. Postal Service change of address form, 181 Web browser sniffing code, 221 User controls, in HTML, 180-181 Web browser software properties, 254-256 User ID and password, 190 Web browser status bar, 253 User information, gathering and processing, 180 Web browser timers, 251 User input, requesting using HTML forms, 181 Web browser type, detecting, 164-169, 256 User interface event handling, 209-210 Web browser usage statistics, 163 User-friendly message, 48 Web browser version User-input prompt box, 21 detecting, 164 Users, communicating with, 19-22 knowing the minimum needed, 15 Web browser window, 252-254, 256-257 Web browsers V checking your code on, 312 Valid JavaScript code, 287 detecting, 164-169, 174, 256 Validating parsers (validators), 287 DOMs of, 14 Value, defined, 27 first JavaScript-enabled, 6 Var keyword, 27 getting for testing your code, 312 Variable scope, 56-58 interacting with, 243-258 with no support for frames, 226-227
  • 369. Index 349 with no support for scripting, 154-156 resize() method, 257 redirecting to a new web page, 258 status property, 253 reliance on external plug-ins, 315 underlying DOM objects of, 253 sending back to previous page(s), 257 Window objects (JavaScript), 236 testing on all, 312 Window.event keyCode attribute, 214 using the latest release, 163 Windows AVI files, 321 web surfer use of, 162-163, 169 Windows environment, JavaScript in, 9 Web forms. See Forms (web) Windows Media Player, 321-322 Web page Windows Script, 9 adding JavaScript to, 153-154 With statement, 44-46 inserting HTML forms on, 184-199 WSH (Windows Scripting Host), 9 JavaScript-enabled, 7 W3C (World Wide Web Consortium), 8, 170 positioning elements on, 268-270 CSS Level 1 standard, 261 Web page content CSS standard, 150, 261 dynamically modifying, 249-251 CSS validator service, 273 manipulating, 248-252 deprecated HTML tags, 145-146 moving to animate, 276-278 DOM Level 2 Events specification, 208 Web page elements DOM standard, 8, 244 making invisible, 270 HTML validation service, 170 positioning, 268-270 XHTML standard, 144 sizing, 270 Web page style. See CSS; Style sheets; Styles Web server X preparing text for sending to, 84-85 XHTML, 144, 146, 235 processing form input on, 183-184 XML document, addressing parts of, 247 Web server programming language, JavaScript as, 14 XML (Extensible Markup Language), 144 Web site framing, 235 XPath, uses of, 247 Web standards. See W3C Web surfers, browsers used by, 162-163, 169 Website Pros, 13 Z While loop, 35-36, 287 While statements, checking the format of, 287 Zero length array, 97 Window object, 252-253 ZVON.org web site, 225 methods of, 254 open() method, 254
  • 370. INTERNATIONAL CONTACT INFORMATION AUSTRALIA SOUTH AFRICA McGraw-Hill Book Company Australia Pty. Ltd. McGraw-Hill South Africa TEL +61-2-9900-1800 TEL +27-11-622-7512 FAX +61-2-9878-8881 FAX +27-11-622-9045 http://www.mcgraw-hill.com.au [email protected] [email protected] SPAIN CANADA McGraw-Hill/Interamericana de España, S.A.U. McGraw-Hill Ryerson Ltd. TEL +34-91-180-3000 TEL +905-430-5000 FAX +34-91-372-8513 FAX +905-430-5020 http://www.mcgraw-hill.es http://www.mcgraw-hill.ca [email protected] GREECE, MIDDLE EAST, & AFRICA UNITED KINGDOM, NORTHERN, (Excluding South Africa) EASTERN, & CENTRAL EUROPE McGraw-Hill Hellas McGraw-Hill Education Europe TEL +30-210-6560-990 TEL +44-1-628-502500 TEL +30-210-6560-993 FAX +44-1-628-770224 TEL +30-210-6560-994 http://www.mcgraw-hill.co.uk FAX +30-210-6545-525 [email protected] MEXICO (Also serving Latin America) ALL OTHER INQUIRIES Contact: McGraw-Hill Interamericana Editores S.A. de C.V. Osborne/McGraw-Hill TEL +525-117-1583 TEL +1-510-549-6600 FAX +525-117-1589 FAX +1-510-883-7600 http://www.mcgraw-hill.com.mx http://www.osborne.com [email protected] [email protected] SINGAPORE (Serving Asia) McGraw-Hill Book Company TEL +65-863-1580 FAX +65-862-3354 http://www.mcgraw-hill.com.sg [email protected]