Lecture_3_Transcript
Lecture_3_Transcript
Having explored some fundamental concepts of the JavaScript language we will now “move to
the browser” which is the environment in which we will be writing our JavaScript code. As mentioned
previously, when programming in the browser we will be utilizing both “Core JavaScript” and “Client-
Side JavaScript” which will introduce several additional objects, properties and methods that are
supported by web browsers.
Slide 1
The information displayed in the web browser is constructed from the “Document Object Model,”
“DOM.” The “DOM” is a tree structured representation of the User Interface of a client-side web
application which is, initially, built from the HTML code passed to the client from a web server
application.
The construction and modification of the “DOM” using JavaScript, JavaScript APIs and JavaScript
libraries will be the focus of our work.
Slide 2
Events
Almost all JavaScript applications are “event-driven.” Most of the code is executed in the context of a
response to an event:
Network events – e.g., response to a web request is received from a web server.
Timers – timers are used for long-running tasks, e.g., web browser event loop, e.g., smooth
animations, we will explore an example in this lecture “Simple Animation.html” in the
“CodeExamples” folder, among other things.
User-generated events – mouse clicks and moves, keyboard presses, etc.
Browser API
The browser offers an API that allows us to access information about devices, store data locally or
communicate with remote servers, more about APIs on the next slide.
Window Object
The primary role of JavaScript is to provide a means for making a displayed web page “dynamic.” To
accomplish this the web browser provides an “API” through a global object that the JavaScript engine
can use to interact with and modify the web page.
“The primary global object that the browser exposes to the JavaScript engine is the window object,
which represents the window in which a page is contained. The window object is the global object
through which all other global objects, global variables (even user-defined ones), and browser APIs are
accessible. One of the most important properties of the global window object is the document, which
represents the DOM of the current page. By using this object, the JavaScript code can alter the DOM of
the page to any degree, by modifying or removing existing elements, and even by creating
and inserting new ones.”1
The document object is a property of the window object. The window object represents the browser
window. The document object represents the HTML document loaded in that window. ... When
JavaScript is run in a browser all variables and functions you create are properties and
methods of the window object.
foo = window.foo;
The above shows that the global variable “foo” is in fact a property of the “window global object.” Note
– using “var” to define a variable makes it global.
foo: “foobar”
function greeting() {
console.log(“Hi!”);
greeting();
window.greeting();
You can see that the function “greeting()” is in fact part of the “window global object.”
console.log(“Hi!”);
Slide 3
The key point here is that the “Window Object” has several methods which JavaScript can make use of.
If you open “WindowMethods.html,” found in the “CodeExamples” folder, in your browser, you will be
able to try out each of the described methods.
The function “setTO()” is the function that is called when the user clicks on the “SetTimeout” button on
the “WindowsMethods.html” page:
“Inside” the “setTO()” function is the “setTimeout()” method invocation. The format of the
“setTimeout()” method is:
“function()” – this function is referred to as a “call back” function which means that it is a
function which is defined to be called at a “later” time. The “later” time it will be called at is
when the “time interval,” the second parameter of “setTimeout(),” has elapsed.
“time interval” – this is the time interval in milliseconds that the time out of the “setTimeout()”
method is set for. When the time interval has elapsed the “call back” function in parameter 1, is
called.
So, in our “setTo()” function when the “SetTimeout” button is clicked the “setTimeout()” method will be
invoked. The invocation will start a 5, millisecond timer. When the timer reaches 0, the “call back”
function will execute, and the “alert” will be displayed as a “modal” popup in the browser.
There is another “Window” method which is like “setTimeout()” – “setInterval().” The “Window”
“setInterval()” method has the same parameters as “setTimeout().” The basic difference between the
two is that when the timer in “setTimeout()” elapses the “call back” function is executed and the
“setTimeout()” method completes while when the time interval in “setInterval()” elapses the “call back”
function is executed and upon completion of the “call back” function the “time interval” is reset to its
initial value and the process repeats. The “setInterval()” method will repeat this process until the it is
programmatically terminated.
The repeating nature of “setInterval” is handy for, among other things, creating smooth animations in
the browser. We will further explore this in the “SimpleAnimation.html” file which is part of this
lecture’s “CodeExamples.”
Slide 4
Should be self-explanatory.
Slide 5
The Web API Specifications & Interfaces is an excellent reference for all of the “things” we will be using
to manipulate the “DOM” with JavaScript.
The “DOM” Document Object Model is an overview of anything you might want to know about the
“DOM” itself. In the left-hand column of the web page you will find links to especially useful guides on
working with the “DOM,” see screen shot below.
The “EventTarget” is one of the available web interfaces and the one we will be using to create an event
listener in the “Code Samples” for this lecture.
Slide 6
This slide is a step-by-step description of how a web page is requested and retrieved. It is divided
vertically into three areas of action:
User actions
Browser actions
Server actions
The steps in the flow are from the user’s request for a web page to the display of the web page in the
user’s browser window are numbered and easy to follow so I will not elaborate further.
Slide 7
This slide “explodes” the “Browser actions” around receiving the “HTML” document containing “HTML”
and “JavaScript” from the server and rendering it on the user’s web page.
The browser parses the HTML document from top to bottom. It uses the various “HTML” elements to
build the “Document Object Model,” “DOM,” which is what we use JavaScript to interact with. Because
it parses the HTML document from top to bottom it will encounter JavaScript code “as it goes along.”
As soon as the browser does encounter JavaScript code it executes it – it does not simply look at it and
record information on what the JavaScript is doing, it actually immediately executes it. Because of this
one must be careful about where in an “HTML” document they place their JavaScript code.
If a block of JavaScript code gets placed before the definition of variables or “HTML” elements, e.g. a
“button,” that the code references, then the code will throw an exception because the code is
referencing constructs that do not yet exist. A simple solution to this possibility is to place all an HTML
document’s JavaScript code at the end of the HTML document with which it is associated. However, it is
generally more convenient to have all the JavaScript code at the start of the HTML document.
There are two events that can be used to ensure that JavaScript code on an HTML page does not begin
execution before any resources it requires are available:
window.onload – fires when the document’s window is ready for presentation; remember, the
“window” object “contains” the web page.
document.onload – fires when the “DOM” tree, created from the HTML markup, is completed.
An extensive discussion of all the differences is reserved for another time but one basic difference is that
“document.onload” fires before “window.onload” as “window.onload” waits for all of the resources
involved in displaying the completed web page, i.e. external files, while “document.onload” waits only
on completion of the “DOM” which is done by the browser.
Linking execution of JavaScript blocks to “document.onload” can be more efficient than using
“window.onload” as it takes place “behind the scenes” and incurs almost no CPU load. Completion of
“window.onload” can take a while to fire when there are a number of external resources needed for the
page.
Slide 8
This slide shows how the “HTML” document returned by the web server to the browser is parsed in
order to create the “Document Object Model” tree. As we will see, each node of the “DOM” tree
represents an “HTML” element. JavaScript can traverse these nodes, access their properties, modify
them, and add new nodes.
Slide 9, 10, 11
Slide 9
Slide 10
Go to next page
Slide 11
The above three slides are a presentation of event handling in the browser. JavaScript is “single
threaded” meaning it has only once call stack and one memory heap, see “Slide 11.” It is synchronous
so if a function is called that will take a while to complete no other activity can take place, this is
referred to as “blocking.” As an example, look at the “Window” methods we discussed earlier, e.g.
“alert().” Once the “alert()” modal popup is displayed in the browser our JavaScript code will stop
executing until the “OK” button is clicked by the end user.
To allow other activity to take place in the web browser while execution of JavaScript code is “blocked”
the JavaScript “engine,” “V8” in the Chrome browser, “SpiderMonkey” in the FireFox (Mozilla) browser,
“JavaScriptCore” in Apple’s Safari browser, all have a Web API that handles blocking tasks in the
background which results in a “non-blocking I/O model.”
After we look at the simple case of how the “Stack” interacts with the code shown on “Slide 11” we’ll
take a look at a more complex case where the code to be executed involves a Web API call that could
cause blocking.
The slide below shows how this code is executed on the “Stack.”
Slides 14 – 17
The above slides, upon which the narrative below is based, are taken from the “concurrency model and
event loop and why JavaScript is so WEIRD!” “YouTube” presentation I recommended on “Slide 12”
https://www.youtube.com/watch?v=8aGhZQkoFbQ
In the code below I changed the text in the last “console.log” statement to ‘Client Programming’ from
‘JSConfEU’ for localization purposes.
We will now look at a block of JavaScript code that contains a function that could “block.” To start, use
MS Visual Studio Code to open the “.html” file “EventLoop.html” in the “CodeExamples” folder.
When this “HTML” page loads and the browser starts parsing it, as soon as the <script> tag is
encountered the browser will start executing the JavaScript contained in it. As we would expect, things
would execute in the following order:
1.
2.
3.
Before going any further, open “EventLoop.html” in your browser. When your browser opens, open
“Developers Tools,” CTRL + Shift + I in Chrome. If not already selected, select the “Console” tab. At this
point you will probably already have the output of the above code showing. Just click on the browser
refresh button to start the code executing again and observe what happens in the console.
What you will observe is that “Hi” and “Client Programming” are written to the console immediately. A
short time after that, 5, seconds, the word “there” is written to the console. So, while the browser
executed the statements in the expected order the output we see is:
What happened here is that the Chrome browser “V8” engine, I’m using Google Chrome for my work
but you may use your browser of choice and you will get the same results, sees the “setTimeout”
method which, as we saw earlier, is not a JavaScript method but rather a “Window” method. As such,
“setTimeout” is “handed off” to the “WebAPI” to be executed asynchronously.
Once the “setTimeout” has been “handed off” to the “WebAPI” the call stack continues processing the
functions still on the stack and executes the “console.log(‘Client Programming’);” statement.
At this time there is nothing left on the stack so the “V8 engine’s” event loop checks to see if there are
any events to be pushed into it. Once the “setTimeout” time interval has elapsed the “console.log”
callback is executed, and the result is placed on the task queue by the V8 engine. If the stack is empty,
the “console.log” call back is placed on the Stack and executed, writing out “Client programming” to the
console.
Slide 18
On “Slide 4” we talked about “Browser APIs.” We identified adding an “Event Listener” as an example of
one. In fact, we will use this API extensively in our work so let us explorer it bit more.
To start, in MS Visual Studio Code open the “.html” file “DOMEventTargetInterface.html” from the
“CodeExamples” folder; below is a screen shot, it will be easier to read the code in MS Visual Studio
Code.
We have created an HTML page which contains the definition for an “HTML” button and two paragraphs
in the body.
In the script block we use the “document API” method “document.getElementByID” on the “id” of the
button, “myBouton1,” to return an “Element object” representing “myButton1” to the JavaScript
variable “myButton.” We can now use the variable “myButton” to perform a number of operations on
the HTML button.
We will use “myButton” to add “Event Listeners” to the HTML button “myButton1.”
On lines 17, through 20, of the HTML page we add an “Event Listener” for the “click” event.”
On lines 21, through 24, of the HTML page we add and “Event Listener” for the “mouseover event.”
In the functions associated with each event, they are call back functions because they run after the
event is captured, we again use the “document.getElementbyID” method to get “Element objects” for
the two paragraphs contained in the body. We “chain” to the “document.getElementByID” the
“textContent” property which will assign to the paragraph whose “Element object” we have obtained,
either “myPara1” or “myPara2,” a text string to be displayed. Note – always use “textContent,” never
use “innerHTML” even though you may see examples that use it. “innerHTML” can make your code
vulnerable to hostile scripts.
The code should be easy to read. Once you have spent time reviewing it, go back to the
“CodeExamples” folder and double click on the file name, “DOMEventTargetInterface.html,” which
should open it in your browser. Once it is open in your browser move your mouse over the button and
click on it.
____________________________________________________________________
There is an alternative method to binding an HTML control to an event which consists of adding the
event “inline.” From the “CodeExamples” folder open the file “DOMEventTargetInterface1.html” in MS
Visual Studio Code. Again, this code is more easily read in “VS Code.”
In the JavaScript block on line 19, I have assigned the “Element Object” for “myButton1” to the variable
myB1.
On line 20, I assign the “onclick” event to “myB1” and assign an anonymous function which calls the
“Window” method “alert(do some stuff #1’);
Similarly, on line 24, I again assign the “onclick” even to “myB1” and this time assign an anonymous
function which calls the “Window” method “alert(do some stuff #2’);
Notice that I am assigning the event “onclick” as opposed to the “click” event used
with”addEventListener.” The “onclick” event is referred to as an inline event. It is called “inline”
because it can be encoded right in the button element itself:
On lines 28, through 34, I am using instances of “addEventListener” to add the “click” event to B2, each
instance invoking a different function.
Open “DOMEventTargetInterface1.html” in your browser and first click on the button labeled “Button1
Click Me.” Notice that this is the alert we see:
Event Delegation
The second bullet point on “Slide 19” defines “Event Delegation” as “Assigning an Event Listener to an
HTML element containing other elements so that clicking on a contained element triggers an event on
the containing element”
In the body of the HTML document on line 8, there is a <div> element, id = “myDiv1” containing on line
9, the button “myButton1” and on line 10, the button “myButton2.”
In the script block we use the “document.getElementByID” method to assign to the “const div” the
“Object Element” for “myDiv1.”
We then apply to “myDiv1,” on line 23, the “addEventListener” for the ‘click’ event. Notice that rather
than having an explicit “function()” definition following ‘click’, I simply typed the word “event” followed
by “=>.” The “=>” symbol is formally referred to as a “lambda operator” although some writers
colloquially refer to it as the “fat arrow operator.” It was introduced with “ES6.”
The way you would read this part of the “addEventListener” is “event goes to the function {….” It is
important to note that “event” is not a JavaScript keyword or reserved word. Rather, event handler
functions are passed an argument known as the “event object.” The object holds additional information
about the event. Here we are using “event” to hold the “event object.” Instead of “event” we could
have just as easily written “greenEggs” and everything would work. However, the word “event” is
suggestive of what we are dealing with.
So, we have assigned defined an “EventListener” on the “myDiv1” element for the “click” event.
“myDiv1” has the “children” nodes “myButton1” and “myButton2.” Handlers registered on nodes with
children will also receive events that happen in the children. Thus, if a button inside of “myDiv1” is
clicked, the event handler on “myDiv1” will also see the click event.
It should also be noted that in creating the event listener I have specified the “useCapture” parameter
and set it to “true.” This means that the event handler will respond to events during the “capturing
phase,” i.e. as the go down the DOM tree - see the next slide.
As described above, when either “myButton1” or “myButton2” is clicked, the event handler on “myDiv1”
will see the event and because we are responding to events in the “capture phase” it will see the event
before “myButton1” or “myButton2.”
In this scenario “myDiv1” is referred to as the “event.currentTarget” since that is where the “Event
Listener” is defined and “myButton1” and “myButton2” is defined as the “event.Target” as they are the
elements that actually fire the “click” event when they are clicked; if “myDiv1” was clicked, it would be
both the “event.currentTarget” and “event.Target” however, we are discussing “Event Delegation” here.
Let us tie all this together by simply running “EventDelegagtion.html.” In the “Code Examples folder
double click on “EventDelegagtion.html.” When the browser opens, open “Developer Tools” by typing
“Ctrl, Shift, I.” Make sure the “Console” tab is selected.
Click on “Button1.” As expected, its background color changes to “red” and on the first line of the
Console we see
<button id="myButton1" style="background: red;" type="button">Button1</button>
</div>
printed out as the “event.currentTarget.” You can perform the same exercise with “myButton2.”
Slide 19
This slide is self-explanatory, and its implications are discussed in the previous section on “Event
Delegation.”
This code example shows how a timer can be used to create a smooth animation. Open the “html” file
“SimpleAnimation.html” from the “CodeExamples” folder in Visual Studio Code.
We explored the “setTimeout” “Window” method in the “EventLoop.html” file and in discussing it
mentioned the “setInterval” method as a similar method that will continuously repeat each time its
defined “time interval” elapses until it is programmatically ended.
Here we are using “setInterval” to update the “.style.left” property of the “div” elment “box1” by 1px
each time the defined “time interval” elapses.
On line 30, we have specified a time interval of 10 milliseconds. That means that when the “setInterval”
method starts running it will wait for 10 milliseconds to elapse, and then move “myBox1” 1 px to the
left. It will then reset the time interval to 10 milliseconds and start over. When the variable “tick” on
line 22, exceeds the value of 800, the “clearInterval” on “timer,” defined on line 23, will be executed
terminating the repeating of “setInterval.”
So, in its current form the box will move left 1 px every 10 ms. Try updating the code to increase and
decrease the number of milliseconds on line 30, and see the effect on the animation.