CS 328 - Week 11 Labs - 1:00 pm lab - 2016-04-08

*   these (I hope) are some reasonable JavaScript
    references/resources (as there are quite a few NOT so good
    JavaScript examples on the web...)

    *   The course textbook!

    *   Mozilla Development Network's JavaScript guide
        developer.mozilla.org/en/JavaScript/Guide

    *   JSLint syntax and style checker
        www.jslint.com

    *   and by the way, browsers have many JavaScript
        tools...
        and 3rd party extensions, such as Firefox's Firebug

    *   textbook authors have a twitter feed
        @webstepbystep

        *   ...they post links to interesting articles,
            many related to JavaScript!

----------
*   WHERE will we put our client-side JavaScript?
    *   our external JavaScripts will be in files
        on nrs-projects whose names have suffix .js

    *   within HTML5 pages (whether generated by PHP or
        plain HTML),

	we are going to try for a so-called UNOBTRUSIVE
	approach to our JavaScript;

	*   part of this is keeping it as separate from
	    the content of the page as we can by
	    keeping it out of the body element,
	    and trying to limit it to being within
	    our head element
  
    *   also: we will NOT modify the document (will not
        modify the Document Object Model, the DOM) until it
        is completed loaded;

    *   when we are referencing an external JavaScript,
        we're going to use (CS 328 style standard) the
	following element:

	<script src="my-file-or-url.js" type="text/javascript">
        </script>   

	<!-- yes, for strict-style HTML5, you DO need to
	     close the script element, and for an external
	     JavaScript, that script element will have NO 
	     content -->

    *   of course, when you are INSERTING JavaScript 
        in the head element,
	we'll still use a script element,
	BUT with no src attribute:

	<script type="text/javascript">
	    ...beautiful JavaScript within...
        </script>

    *   we will place our script elements for JavaScript
        at the END of our head element

        and use HTML5-added attributes (using strict-style HTML5)
	    async="async"
	    defer="defer"
        ...as appropriate

        *   these tell the browser that the JavaScript
	    is NOT modifying the DOM while the page is
	    being loaded,
            it is SAFE to continue parsing the HTML
            while the scripts are being downloaded;

        *   and add async="async" to the script element
   	    when it IS safe to continue parsing the HTML
	    while the scripts are being downloaded
	    and executed;

        *   and add defer="defer" to the script element
	    when the JavaScript depends on an earlier
	    JavaScript having been downloaded already,
	    and so you want to make sure these are
	    executed in order
            *  yes, with defer, the scripts are not executed until after
	       the entire document has been loaded --
	       BUT, the document will keep parsing the HTML
	       while downloading the scripts

        *   my favorite-so-far discussion of where-to-put-JavaScript:
            top answer at:
http://stackoverflow.com/questions/436411/where-is-the-best-place-to-put-script-tags-in-html-markup
            *   (have added a link to this along with today's in-lab
	        examples)
    
----------
*   our FIRST (but not last) discussion of the
    Document Object Model (DOM)

    *   Core JavaScript has a core set of predefined
        useful object

        Array
	Date
	Math
	String
	...many, many more
	
        Client-side JavaScript adds the Document Object Model
	which allows JavaScript to manipulate the HTML
	document...

        *   The ECMAScript specification does not
            include the Document Object Model (DOM)
            which is standardized by the World Wide
	    Web Consortium (W3C)

	    The DOM defines the way in which HTML
	    document objects are exposed to your
	    script

            ...since we want to use client-side
    	    JavaScript to affect our HTML documents,
	    we shall be VERY interested in the
	    DOM;

    *   of course, an object has methods and data fields;

    *   (Chapter 8, Section 8.1.4, pp. 281-283 of course
        text)

	JavaScript has a set of objects and functions
	for accessing, modifying the content of the
	current web page

	EACH element on the page is represented as
	a JavaScript object

        This set of objects (representing the page)
	is collectively referred to as the Document
	Object Model, or DOM.

	When you muck with the object representing
	that element, you CAN change its appearance
	and behavior

    *   The DOM "acts as the glue between web page
        content and JavaScript

    *   You get certain global JavaScript objects:
        window - this is the object representing the
	         current browser window

        *   ALL the code and variables you write in your
            client-side JavaScript become part of the
	    window object...!	

	document - is the object representing the
	         current web page

        *   (document is also a data field of the window object...)

        (and more!)

    *   each HTML element will be represented
	as a JavaScript object in the DOM
        *   each DOM element object has a BUNCH of
	    data fields --

	    id - the value of the element's id attribute

	    innerHTML - the content between the
	                start and end tag of that element

	    style - an object representing the element's
	            style attributes

            and also
	    each attribute of the element is also
	    a data field of its JavaScript object (if
	    I understand correctly), whose value is the
	    value for that attribute;

            *   so, an img element has a src attribute?
                its object has a src data field;

    *   oh, these objects have methods, too!

        document has a method called:
	getElementById

	expects the value of an id attribute,
        and it returns the object corresponding
	to the element with an id with that value

	(returns null if there is no element with
	that id)

*   we will often do event-driven programming
    in JavaScript --

    *   execution is not starting at a main function --
        it is driven by events and user interaction

    *   event: a user action, clicking a button,
        moving a mouse, checking an checkbox, etc.

    *   when an action happens, run this JavaScript function --

    *   to respond to an event using JavaScript:
        1. decide which element or control we want to
           respond to

        2. write a JavaScript function with the code we
           want to run when that event happens

        3. attach that function to the control's event

    *   HTML elements have event attributes
        that represent actions you can perform on them;

	they all start with on

	onclick onkeydown onchange onsubmit ETC!

        *   to listen for an event on an element,
	    you set a value for that element's
	    corresponding event attribute

            and by the way, here this value will 
	    be a JavaScript function

        *   BUT, to be unobtrusive,
	    we're going to attach these event attributes
	    to page elements
	    by adding them to the DOM in the head element
            (AFTER the document has been loaded!)

[ADDED AFTER LAB]
*   JavaScript function syntax:

    function desired_function_name(param_name, param_name, ... param_name)
    {
        action;
        ...
        return ret_expr;  /* optional */
    }

*   a first example: see please.js and js-play1.html

*   a few more JavaScript tidbits:
   
    *   JavaScript is loosely typed, but you can "declare"
        a variable by putting var followed by an
	assignment statement setting an identifier
	to a value ---

	var val = 13;  // you've now declared val

        *   FOR LOCAL VARIABLES, the PREFERRED (yes,
            CS-328-required) STYLE is to precede
            the new variable's name with var, as shown
	    above

    *   also because of its loose typing, it supports 2
        different equality-comparison operators:

	== means compare, but don't care about type
	=== means compare, but DO care about type

        *   remember document object method getElementById, mentioned
	    earlier?
            ...expects an id attribute's value, and 
            returns the object corresponding to
            the element that has attribute id with that value?

	    So, you can set a variable TO a particular element's
	    DOM object with something like:

            // nameField will reference the HTML element within
	    //     document that has id="enteredName"

            var nameField = document.getElementById("enteredName");

        *   once a variable contains a reference to an object
            representing an HTML element, you can grab that element's
            attributes' values by referring to the attributes like
            data fields

            (you can use them, you can set them);
 
            // nameField.value refers to the value attribute of 
	    //    the HTML element with id="enteredName"

            nameField.value = "Looky!";

    *   how do you make sure NOT to modify the DO until the
        page has been loaded?
        
        *   have a JavaScript in (or referenced in) the head
            element that sets the onload attribute of the
	    window object (displaying a document),
	    so that it is an (anonymous) function that sets
            the event handling for the desired elements
	    when this window exists

        window.onload =
            function()
            {
                ...
            };

    *   for example, once the document is loaded,
        you might use document's getElementById
        method to grab a button element, and then set its
	onclick attribute to a button-click event handling function 
        you'd like to be done when that button is clicked:

        window.onload =
            function()
            {
                var myButton = document.getElementById("magicButton");

                // NOTE: set these to a FUNCTION,
		//     NOT to the result of CALLING a function
		//     (NO parentheses after function name here!!)

                myButton.onclick = sayMagicWord;
            };

*   see posted examples js-play1.php, please.js