Events

Introduction -------------- In javascript you can interact with users by creating and executing events. Events are triggered in the browser when something happens such as mouse click or movement and keyboard interaction. "load" is an event that fires when a page is first loaded. "click" is another event, which happens when a user clicks something. These events need to be attached to DOM elements to be executed. For example to execute a function when a link(hyperlink) is clicked, the event "click" should be attached to the "link,". Steps to implement events. 1. Get a DOM node. 2. Attach an event to it. 3. Execute a specific function when the event is triggered. This model referred to as event-driven JavaScript . Attaching an Event ------------------ There are a lot of ways to attach an event to a DOM element. Some are like using inline JavaScript in your HTML or by using other below methods. ■ Event handlers ■ Event listeners (Ref' Add Wiley Learning JavaScript) Event Handlers ............... Using Event handlers we can attach an event to a DOM element. Below is an example to attach an event click to a button element through an Event Handler. Syntax You get the point; every event is on when using event handlers. /* wrap it in an anonymous function to contain the variables */ (function(){ // HTML: // save the button to a variable var btn = document.getElementById("btn"); // Use an event handler to attach the "onclick" event btn.onclick = function(){ // alert inside this anonymous callback function alert('clicked the button'); } })(); In the above example a button element with an id value of "btn" and is attached a click event to it in the form of "onclick" to an anonymous function. When a button is clicked it alerts the text "clicked the button." The events are always prefaced with the word "on." That’s why we’re using " onclick " rather than just "click." It applies to all events: onsubmit , onchange , onfocus , onblur , onmouseover , onmouseout , ontouchstart , ongesturestart , and so on. Note You can attach only a single function to a specific event of a DOM node. You can’t attach two click functions to the same button. To overcome this limitation you can use an event listener instead of an event handler. Event Listeners ................. Event listeners are similar to Event handlers.  Similar to event handlers you need a DOM element to attach them to identify the event, and need a function to call.  The difference is that you can assign multiple functions to the same DOM element and event.  Below is an syntax of an event listener using an anonymous function. // event listener with an anonymous function element.addeventListenter("event", function(){ // stuff you want the function to do }, false); The above event listener is made up of four parts: ■ The DOM element ("element") ■ The event type ("event") ■ The eventListener , aka the function (anonymous function) ■ An optional Boolean value used to initiate something called "capture" (set to false) Setting optional Boolean value to true is like  announcing to all the parent DOM nodes that an event is firing on a particular node. Setting to false prevents this behavior because. It is unnecessary. It’s called "event propagation."  Example for adding a Basic Click Event Through a Listener  on a button, which has an ID value of "btn." /* wrap it in an anonymous function to contain the variables */ (function(){ /* HTML: */ // save the button to a variable var btn = document.getElementById("btn"); // attach a "click" listener to the button btn.addEventListener("click", function(){ // alert inside this anonymous callback function alert('clicked the button'); }, false); })(); Note: Each browser event handler is registered in a context. When you call addEventListener as shown previously, you are calling it as a method on the whole window because in the browser the global scope is equivalent to the window object. Every DOM element has its own addEventListener method, which allows you to listen specifically on that element. Binding Events ............... When a function is inside an addEventListener() method, it’s called an event listener. The functions inside the addEventListener() method don’t have parentheses. Binding an Event to a DOM Element // save the DOM element you want to attach an event to var btn = document.getElementByID("btn"); // define your function normally function alertMessage(){ alert("clicked the button"); } // or use a predefined function (event handler), "alertMessage" btn.addEventListener("click", alertMessage, false); In order to pass arguments into a function while using addEventListener() , you need to use the function as a callback instead by nesting it inside an anonymous function.  The below example shows you how to use an anonymous function and a callback function to achieve this goal. // save the DOM element you want to attach an event to var btn = document.getElementByID("btn"); // define your function normally function alertMessage(message) { alert(message); } // or use a predefined function (event handler), "alertMessage" btn.addEventListener("click", function() { // callback function! alertMessage("clicked the button"); }, false); It is very similar to the previous example but instead of simply calling a function, you can pass parameters into it. If you have a node containing a long list of buttons, it may be more convenient to register a single click handler on the outer node and have it use the target property to figure out whether a button was clicked, rather than register individual handlers on all of the buttons. Preventing Default Behavior (Ref: Add W Learning JS) --------------------------- Html elements have default action associated with them. For example if you click a link, you will be taken to the link’s target. If you press the down arrow, the browser will scroll the page down. If you right-click, you’ll get a context menu. Using JavaScript event handlers you can prevent the default behavior attached with these DOM elements. The JavaScript event handlers are called before the default behavior is performed. It can call the preventDefault method on the event object. For example, a link with an href value wants to go to another page, or in our case, a form that wants to submit somewhere to do a search query. Preventing default behavior is done inside the method. You first need to pass the event (form submit) as an argument into the method. Then attach the preventDefault() method to it.  var adr = { search : function( event ){ event.preventDefault() ; /* continue the rest of the method here */ } } Another example it is used to implement your own keyboard shortcuts or context menu. It can also be used to obnoxiously interfere with the behavior that users expect. For example, here is a link that cannot be followed: MDN The clientX and clientY properties are similar to pageX and pageY but relative to the part of the document that is currently scrolled into view. These can be useful when comparing mouse coordinates with the coordinates returned by getBoundingClientRect, which also returns viewport relative coordinates. Mouse motion (Ref: Eloquent JS) ------------- Every time the mouse pointer moves, a "mousemove" event fires. This event can be used to track the position of the mouse. A common situation in which this is useful is when implementing some form of mouse-dragging functionality. As an example, the following program displays a bar and sets up event handlers so that dragging to the left or right on this bar makes it narrower or wider.

Drag the bar to change its width:

The "mousemove" handler is registered on the whole window. Even if the mouse goes outside of the bar during resizing, we still want to update its size and stop dragging when the mouse is released. We must stop resizing the bar when the mouse button is released. Unfortunately, not all browsers give "mousemove" events a meaningful which property.  Fortunately, all major browsers support either buttons or which, so the buttonPressed function in the example first tries buttons, and falls back to which when that isn’t available. Whenever the mouse pointer enters or leaves a node, a "mouseover" or "mouseout" event fires. These two events can be used, among other things, to create hover effects, showing or styling something when the mouse is over a given element Unfortunately, creating such an effect is not as simple as starting the effect on "mouseover" and ending it on "mouseout". When the mouse moves from a node onto one of its children, "mouseout" fires on the parent node, though the mouse did not actually leave the node’s extent. To make things worse, these events propagate just like other events, and thus you will also receive "mouseout" events when the mouse leaves one of the child nodes of the node on which the handler is registered. To work around this problem, we can use the relatedTarget property of the event objects created for these events. It tells us, in the case of "mouseover", what element the pointer was over before and, in the case of "mouseout", what element it is going to. We want to change our hover effect only when the relatedTarget is outside of our target node. Only in that case does this event actually represent a crossing over from outside to inside the node (or the other way around).

Hover over thisparagraph.

The isInside function follows the given node’s parent links until it either reaches the top of the document (when node becomes null) or finds the parent we are looking for. I should add that a hover effect like this can be much more easily achieved using the CSS pseudoselector :hover, as the next example shows. But when your hover effect involves doing something more complicated than changing a style on the target node, you must use the trick with "mouseover" and "mouseout" events.

Hoveroverthisparagraph.

Scroll events (Ref: Eloquent JS) -------------- Whenever an element is scrolled, a "scroll" event fires on it. This can be useful in showing some indication of progress (by highlighting part of a table of contents or showing a page number). The following example draws a progress bar in the top-right corner of the document and updates it to fill up as you scroll down.

Scrollme...

Load event (Ref: Eloquent JS) ------------ When a page finishes loading, the "load" event fires on the window and the document body objects. Elements such as images and script tags that load an external file also have a "load" event that indicates the files they reference were loaded. Like the focus-related events, loading events do not propagate. When a page is closed or navigated away from (for example by following a link), a "beforeunload" event fires. The main use of this event is to prevent the user from accidentally losing work by closing a document. Preventing the page from unloading is done by returning a string from the handler. The string will be used in a dialog that asks the user if they want to stay on the page or leave it. This ensures that a user is able to leave the page Script execution timeline ------------------------------- There are various things that can cause a script to start executing. Reading a Sometimes you need to cancel a function you have scheduled. This is done by storing the value returned by setTimeout and calling clearTimeout on it. var bombTimer=setTimeout(function(){ console.log("BOOM!"); },500); if(Math.random()<0.5){//50%chance console.log("Defused."); clearTimeout(bombTimer); } The cancelAnimationFrame function works in the same way as clearTimeout —calling it on a value returned by requestAnimationFrame will cancel that frame (assuming it hasn’t already been called). A similar set of functions, setInterval and clearInterval are used to set timers that should repeat every X milliseconds. var ticks=0; var clock=setInterval(function(){ console.log("tick",ticks++); if(ticks==10){ clearInterval(clock); console.log("stop."); } },200); Debouncing (Ref: Eloquent JS) ------------ Some types of events like "mousemove" and "scroll" events fires many times. Any time-consuming actions inside your handler will make interaction with the document starts to feel slow and choppy. If you do need to do something nontrivial in such a handler, you can use setTimeout to make sure you are not doing it too often. This is usually called debouncing the event.  For example when the user has typed something, instead of immediately performing an action in the event handler we wait until a pause occurs. Set a timeout and also clear the previous timeout (if any) so that when events occur close together (closer than our timeout delay), the timeout from the previous event will be canceled. For example, we might want to respond to "mousemove" events by showing the current coordinates of the mouse, but only every 250 milliseconds. Change (Ad W Learning JS) ------- A change event is applied to form elements such as select menus, radios buttons, and check boxes. In radios and check boxes, a change value is triggered when the box/button is checked. In a select menu, the change event is triggered when a new value or option is selected by clicking or by keyboard navigation. submit (Ad W Learning JS) -------- The submit event is triggered when a form is submitted, either by clicking a Submit button, tabbing to the Submit button and pressing Enter/Return, or sometimes just by pressing Enter/ Return while a form element is in focus. Any way you can submit a form, this event gets triggered. Adding a Listener to a Form submit Event /* use the same adr method */ var adr = { /* ...previously defined methods go here... */ // define the method (aka the function) search : function(event){ /* prevent the default behavior */ event.preventDefault(); /* save the DOM element we're putting the output in */ var target = document.getElementById("output"); /* save the contacts JSON object to a variable */ var book = contacts.addressBook; /* save the length to a variable outside the loop for performance */ var count = book.length; /* ready the loop! */ var i; // clear the target area just in case there's something in it. target.innerHTML = ""; // check the count, of course and check to see if the value isn't empty if(count > 0 && searchValue !== ""){ // loop through the contacts for(i = 0; i < count; i = i + 1) { // look through the name value to see if it contains the searchterm string var obj = contacts.addressBook[i], isItFound = obj.name.indexOf(searchValue); // anything other than -1 means we found a match if(isItFound !== -1) { target.innerHTML += '

' + obj.name + ', '+ obj.email +'

'; } // end if } // end for loop } // end count check } // end method } // end adr object // save search field to a variable var searchForm = document.getElementById("search-form"); // activate autocomplete on submit searchField.addEventListener("submit", addr.search, false) Something important to note from the search method in the form no longer submits per its default behavior when the search button is clicked. This is deliberate; if the form were to submit, you wouldn’t be able to execute the JavaScript and update the page (it would have refreshed). You can stop a form submission by using the preventDefault() method. Touch and Orientation Events (Ad W Learning JS) ---------------------------- Touch and Orientation Events events get attached the same way the nontouch events like click and focus. In some cases, they can even use the same functions. Using a touch Event Touch Events

Touch Events Demo

touchstart and touchend The paring of the touchstart and touchend are very common because they mark opposite events. The touchstart event is triggered when a user touches the screen, and the touchend event is triggered with the opposite action of untouching the screen (removing whatever you touched the screen with from the screen; if you touched the screen with your nose, it would execute when you removed your nose from the screen). In Listing 7.5.1 we’re declaring a new object to contain the touch-based events and creating two methods intended to be executed on the touchstart and touchend events by inserting some text into the document’s body element. Listing 7.5.1 Using a touch Event /* Anonymous function wrapper again! */ (function(){ var body = document.getElementsByTagName("body")[0]; // declare an object to hold touch controls var touchControls = { pokeTheScreen : function(){ // output a message to the body body.innerHTML += "you just poked me, how rude!
"; }, stopPokingTheScreen: function(){ // output another message to the body body.innerHTML += "please do not do that again.

"; } } // end object // add event listeners to the body body.addEventListener("touchstart", touchControls.pokeTheScreen, false); body.addEventListener("touchend", touchControls.stopPokingTheScreen, false); })(); If you implement the methods in Listing 7.5.1 and view them in a browser on a touch-capable device, you will see the text “you just poked me, how rude” inserted into the body when you touch the screen and the text “please do not do that again” inserted when you lift your finger off the screen. You can repeat this behavior over and over with the same result. Touch and Orientation Events 145 touchmove The touchmove event is triggered when the user moves their finger on the screen. It is always preceded by the touchstart event. Naturally, you have to touch the screen before you can move your finger. This is often used to create swipe gestures or to move objects around the screen. In Listing 7.5.2 we’re creating a method inside the touchControls object that will output the text “moving!!” into the body while the touchmove event is being triggered. The event will trigger repeatedly until the movement stops. You can see this by moving your finger around the screen and observing the output (it should say “moving!!” a bunch of times). Listing 7.5.2 Using a touchmove Event /* Anonymous function wrapper again! */ (function(){ // the same body variable, no need to redeclare it. var body = document.getElementsByTagName("body")[0]; // declare an object to hold touch controls var touchControls = { /* previously defined methods here */ showMovement : function(){ // output a message to the body body.innerHTML += "moving!!
"; } // end method } // end object // add event listeners to the body body.addEventListener("touchmove", touchControls.showMovement, false); })(); orientationchange orientationchange is the only event related to touch that really isn’t a touch event. As I mentioned earlier, this is the event that relies on the presence of an accelerometer in a device. An accelerometer is what allows the screen on your phone or tablet to rotate when you rotate the device. It also allows high-end gaming because it can return how many degrees the user is turning a device in one direction or another. 146 Chapter 7 Interacting with the User Through Events There are orientation settings for portrait, landscape, upside-down portrait, and upside-down landscape, which can be returned with some work, but we’re only interested in triggering the event that tells us that the device orientation has changed. In Listing 7.5.3 you will see the method “ changedOrientation ” added to the touchControls object. This new method is set up to clear the contents of the body when the orientationchange event is triggered. If you add this method into the object, do some touching and dragging around; you should be able to clear the screen by rotating it to either portrait or landscape (depending on how you started off). Listing 7.5.3 Executing a Method on orientationchange /* Anonymous function wrapper again! */ (function(){ // the same body variable, no need to redeclare it. var body = document.getElementsByTagName("body")[0]; // declare an object to hold touch controls var touchControls = { /* previously defined methods here */ changedOrientation : function(){ // clear out the body content body.innerHTML = ""; } // end method } // end object // add event listeners to the body body.addEventListener("orientationchange", touchControls.changedOrientation, false); })(); Support for Touch Events Support for touch events is surprisingly good among touch devices. The touch-based events will execute only on a device that supports touch (phone, tablet, and so on), and orientation events will be supported in any device that has an accelerometer. At first glance, these seem like the same thing, but some laptops ship with accelerometers in them, even if they’re never used. Putting It All Together 147 These events can be used to create a native app-like experience in the browser. They are the basis for all swipe and gesture behaviors you experience on a touch device, even if they are just a simple event. For example, a drag-and-drop function for a nontouch device could easily be reused to create a touch/drag functionality on a touch-based device. Putting It All Together Again, I thought it might be helpful to have the entire touch event base JavaScript together. Listing 7.5.4 shows all the methods and listeners laid out together. Listing 7.5.4 All the Touch Methods Together /* Anonymous function wrapper again! */ (function(){ // the same body variable, no need to redeclare it. var body = document.getElementsByTagName("body")[0]; // declare an object to hold touch controls var touchControls = { pokeTheScreen : function() { // output a message to the body body.innerHTML += "you just poked me, how rude!
"; }, stopPokingTheScreen: function(){ // output another message to the body body.innerHTML += "please do not do that again.

"; }, showMovement : function(){ // output a message to the body body.innerHTML += "moving!!
"; }, // end method changedOrientation : function(){ // clear out the body content body.innerHTML = ""; } // end method } // end object 148 Chapter 7 Interacting with the User Through Events // add event listeners to the body body.addEventListener("touchstart", touchControls.pokeTheScreen, false); body.addEventListener("touchend", touchControls.stopPokingTheScreen, false); body.addEventListener("touchmove", touchControls.showMovement, false); body.addEventListener("orientationchange", touchControls.changedOrientation, ➥false); })();
Related Tutorial
Follow Us
https://www.facebook.com/Rookie-Nerd-638990322793530 https://twitter.com/RookieNerdTutor https://plus.google.com/b/117136517396468545840 #
Contents