JavaScript III

Events

  • So far the programming we have been doing has focused on a set of instructions to be executed roughly in sequence
  • Instead of providing the order to execution when programming, we can define handlers that will be executed in response to a specific event
  • Events are sent from a dispatcher
    • In the case of web programming, the dispatcher is the web browser
    • The dispatcher could be hardware based too, like a sensor ( see NodeBots )
  • The alternative to using events would be to program an instruction to check the status of something through out your code

Event Basics

  • In the JavaScript event system, we need three pieces of information to handle an event
    • The object or objects on the page to get events from
      • The entire document, all paragraphs, a specific element, etc.
    • The event we want to handle
      • A mouse click, a key press, the copying of text, etc.
    • The function to call when the event happens, often called the handler

Event Propogation

  • For this discussion consider the following HTML:
    <div>
      <p>
          <input type="text"/>
      </p>
    </div>
    
  • One event we can listen to is called input that is fired when the input changes
  • This event can be captured from not only a listener on the input tag, but on the p and div tags as well
    • The event moving up the HTML tree is known as event propogation
    • It is also sometimes referred to as bubbling.
    • The order the handlers will be called in is always the element itself followed by its closest parents
  • We can prevent this behavior if we wish

Potential Issues with Event Based Programming

  • A webpage can generate hundreds of events a second
    • It is impossible to process them all as they come in
    • Events are stored in a queue for processing
  • Should all events be processed?
    • If you processed every change in the scrollbar position, your page would lock up
  • How are events refered to
    • In JS they are strings, so a mistyped event won't cause a syntax or error

The Event Object

  • When the handler is executed, it recieves at least one object, which contains properties about the event
  • The properties of this object depend on the event that produced it
  • The MDN page on events is a good resource for this
  • Some common properties are:
    • screenX and screenY for events involving the mouse
    • key or keyCode for events from the keyboard
    • clipboardData for copy, cut, and paste events

addEventListener

  • The addEventListener function can be called on any element
  • It takes two parameters
    • The event type as a string
    • The handler function
      element.addEventListener('eventString', function(event){
      doSomething();
      })
      

Click

  • One of the most commons events is responding to a mouse click
  • The event string for this is 'click'
In [ ]:
%%html
<html>
    <head>
        <script>
             function paragraphHandle(){
                    this.style.background = "green"
                }
            document.querySelector('#one').addEventListener('click',paragraphHandle)
            document.querySelector('#two').addEventListener('click',paragraphHandle)
            document.querySelector('#three').addEventListener('click',paragraphHandle)

            document.querySelector('.contain').addEventListener('click',
                function(){
                    this.style.background = "purple"
                })
        </script>
    </head>
    <body>
        <div class="contain">
            <p id="one"> A Paragraph</p>
            <p id="two"> A Second Paragraph</p>
            <p id="three"> A Third Paragraph</p>
        </div>
    </body>
</html>

querySelectorAll

  • Having to put an id on every element that we want to add an event listener to is cumbersome
  • document.querySelector only returns the first match
  • document.querySelectorAll will return a NodeList of the matching elements
  • NodeList is not an Array
    • It does not have forEach

querySelectorAll Example

In [ ]:
%%html
<html>
    <head>
        <script>
             function paragraphHandle(){
                    this.style.background = "green"
                }
            var paragraphs = document.querySelectorAll('p')
            for(var i = 0; i < paragraphs.length; i++)
            {
                paragraphs[i].addEventListener('click',paragraphHandle)
            }

            document.querySelector('.contain').addEventListener('click',
                function(){
                    this.style.background = "purple"
                })
        </script>
    </head>
    <body>
        <div class="contain">
            <p> A Paragraph</p>
            <p> A Second Paragraph</p>
            <p> A Third Paragraph</p>
        </div>
    </body>
</html>

querySelectorAll Pratice

  • Write the JavaScript to print out in the div with id clicked the paragraph that was clicked
In [ ]:
%%html
<html>
    <head>
        <script>
        </script>
    </head>
    <body>
    <p>First Paragraph</p>
    <p>Second Paragraph</p>
    <p>Third Paragraph</p>
    <div id="clicked">
    </div>
    </body>
</html>

Input

  • The input event is fired when ever the value of on input changes
In [ ]:
%%html
<html>
    <head>
    
        <script>
        document.querySelector("#theText").addEventListener('input',
            function(event)
            {
                var lastChar = this.value[this.value.length -1]
                var out = document.querySelector("#output")
                if(lastChar == 'a' || lastChar == 'e' ||
                   lastChar == 'i' || lastChar == "o" ||
                   lastChar == 'u')
                {
                    out.innerHTML = "You typed a vowel"
                }
                else{
                    out.innerHTML = "You typed a consonant"

                }
            })
        </script>
    </head>
    <body>
        <input id="theText" type="text" />
        <p id="output"></p>
    </body>
</html>

Keyboard Events

  • To respond to whats typed on they keyboard at any time, not just when the user is in an input field, keyboard events are used
  • There are many keyboard events, including keyup, keypress, keydown.
  • The implementation of these events is one of the less standardized parts of JavaScript to this day

Keyboard Event Example

In [ ]:
%%html
<html>
    <head>
    
        <script>
        addEventListener('keydown',
            function(event)
            {
                var output = document.querySelector("#output2")
                if( event.keyCode == 77 && event.ctrlKey == true)
                {
                    output.style.border = "3px solid black"
                }
                else if(event.keyCode == 77 && event.altKey == true)
                {
                    output.style.border = "3px dashed black"
                }
                else{
                      output.style.border = "0px solid black"
                }
            })
        </script>
    </head>
    <body>
        <p id="output2">Watch This Space</p>
    </body>
</html>

Blur and Focus

  • Certain HTML elements are meant for the user to interact with: buttons, input fields, radios, etc.
  • Theoretically all HTML elements can recieve focus, but this is browser dependent
  • There are several visual cues in the default styles of browsers to show what event is in focus

Blur and Focus Example

In [ ]:
%%html
<html>
    <head>
    <script>
        function getInputType(event)
        {
            document.querySelector("#inputType").innerHTML = this.type
        }
                
        document.querySelector("input[type='text']").addEventListener('focus',getInputType)

        document.querySelector("#aSelect").addEventListener('focus',getInputType)
        
        document.querySelector("input[type='email']").addEventListener('focus',getInputType)
    </script>
    </head>
    <body>
        <h3>A Simple Form</h3>
        <p id="inputType">The Input Type Will Go Here</p>
        <p>
            <label>Name:</label> <input type="text"/>
        </p>
        <p>
            <label>Class Standing:</label>
        <select id="aSelect">
            <option>Freshman</option>
            <option>Sophmore</option>
            <option>Junior</option>
            <option>Senior</option>
        </select>
        </p>
        <p>
        <label>Email: </label> <input type="email"/>
        </p>
    </body>
</html>

Mouse Movement

  • It is possible to fire an event when a mouse enter or leaves an element, or just moves over it in general
In [ ]:
%%html
<html>
    <head>
        <style>
            #trackHere{width:100px;height:100px; border:1px solid blue}
        </style>
        <script>
            document.querySelector('#trackHere').addEventListener('mousemove',function(event){
                    document.querySelector("#point").innerHTML= event.screenX + "," + event.screenY
                })
        </script>
    </head>
    <body>
        <div id="trackHere"></div>
        <p id="point"></p>
    </body>
</html>

The Event Object Practice

  • Write JavaScript to let the user know while they are dragging selected text using the drag event and the HTML below
In [ ]:
%%html
<html>
    <head>
        <script>
        </script>
    </head>
    <body>
        <div>
            <span>Meesage:</span> <span id="selected"></span>
        </div>
        <p id="toWatch">The giant anteater (Myrmecophaga tridactyla), also known as the ant bear, is a large insectivorous mammal native to Central and South America. It is one of four living species of anteaters and is classified with sloths in the order Pilosa. This species is mostly terrestrial, in contrast to other living anteaters and sloths, which are arboreal or semiarboreal. The giant anteater is the largest of its family, 182–217 cm (5.97–7.12 ft) in length, with weights of 33–41 kg (73–90 lb) for males and 27–39 kg (60–86 lb) for females. It is recognizable by its elongated snout, bushy tail, long fore claws, and distinctively colored pelage.</p>
        <p><small>From the Wikipedia entry on the Giant Anteater</small></p>al and South America. It is one of four living species of anteaters and is classified with sloths in the order Pilosa. This species is mostly terrestrial, in c
    </body>
</html>

Time Outs

  • Calling a handler everytime an event fires for events that fire in rapid suggestion (mousemove, etc.) can freeze the browser
  • There is no way to tell the browser not to call the events so often, but we can make sure the computationally expensive code is run only at certain intervals
  • We use a function in JavaScript called setTimeout to achieve this

Time Out example

  • Adapted from Eqloquent JavaScript
In [ ]:
%%html
<html>
<head>

        <style>
            #trackHereAgain{width:100px;height:100px; border:1px solid blue}
        </style>
<script>
  function displayCoords(event) {
    document.querySelector("#point2").textContent =
      "Mouse at " + event.pageX + ", " + event.pageY;
  }

  var scheduled = false, lastEvent;
  document.querySelector("#trackHereAgain").addEventListener("mousemove", function(event) {
    lastEvent = event;
    if (!scheduled) {
      scheduled = true;
      setTimeout(function() {
        scheduled = false;
        displayCoords(lastEvent);
      }, 2000);
    }
  });
</script>
</head>
<body>
      <div id="trackHereAgain"></div>
      <p id="point2"></p>
</body>
</html>

Web Workers

  • As an alternative to using timeouts, a recent technology known as WebWorkers has been added to JS
  • WebWorkers will run in separate threads and use message events to send information back to the main thread
worker = new Worker('jsFileName')

worker.addEventListner("message",
function(event){
    doSomething(event.data);
})

worker.postMessage(toSendToWorker);
In [ ]: