260 likes | 393 Views
Events. DOM Event Model. HTML Events. <tag onevent="" /> "on" + event name attribute value is javascript javascript runs 1st return false to STOP browser event (if any). Layered Events. <p onclick=" alert( 'p' ); "> <a onclick=" alert( 'a' ); ">click me</a> </p>
E N D
Events • DOM Event Model
HTML Events • <tag onevent="" /> • "on" + event name • attribute value is javascript • javascript runs 1st • return false to STOP browser event (if any)
Layered Events • <p onclick="alert('p');"> <a onclick="alert('a');">click me</a> </p> • What happens? Why don't you try it? • <p onclick="alert('p');"> <a onclick="alert('a');return false;">click me</a> </p> • Why doesn't the return false stop it? • ONLY stops the <a> from going to href=""
DOM Events • DOM API's event model - separate from HTML • SAME BASIC EVENT NAMES AND BEHAVIORS • no more "on" prefix! • many MORE events! create your own events! • Programs somewhat like JAVA's SWING API • More flexible and powerful (except in IE6)
addEventListener() • HTMLElement.addEventListener( • "event name without on prefix. ex: click", • function object which is .call(this, event), • optional: true - capture event early • );
HTML is easier.Why use DOM? • HTML on"event" requires CHANGES TO HTML • Automation, productivity, bandwidth • Flexibility • getElementsByClassName() • code reuse! - programming costs more • More features; + invalid HTML events can exist in DOM (some events only exist in DOM)
function hi(){ alert("hello!"); } • document.body.addEventListener( 'load', hi ); • // after page is loads • // an alert window says "hello!"
see also... • removeEventListener() • dispatchEvent() • fake events; trigger made up events • requires Event object: • e= document.createEvent("name") • e.initEvent(...) - setup properties
capture / bubble • HTML tags have a hierarchy parent tags can overlap events • <p onclick="alert('p')"> paragraph is parent • <a onclick="alert('a')">child tag</a> • </p> • Try it. experiment.
Capture (true) body Bubble (false) p a Click! <a>'s onclick="runs" <a>'s href is followed
function capture(){ alert("captured!"); } • function bubble(){ alert("bubbled"); } • tagObject= document.getElementById('id'); • tagObject.addEventListener( 'click', bubble, false ); • tagObject.addEventListener( 'click', capture, true ); • // A click on tagObject: • // 1st says "hello!" (capture phase) • // 2nd says "bye" (bubble phase - default) • // 3rd tagObject does whatever it normally does • //- likely nothing unless it is <a>, <button>, etc.
Common Use • Bubble only - HTML onEvents are bubble • Usually Bubble is all you want • MSIE never supported capture • Compatibility libraries forced to do same • So, addEventListener('event', function); • false is redundant, undefined comes out false
Event object • Describes details of the event; timestamp, keys • <a onclick="your_f(event)">click</a> • HTML onEvents set var event for you • You never work with Event, you use event an instance of Event
event use in DOM • tagObject.addEventListener('click', your_f, false) • what it does: your_f.call( tagObject, event) • function your_f(e){ alert(this); alert(e); } • FYI: Function.call(this, parameters); • your_f.call( this=object, parameters,... );
Useful event methods • .preventDefault() • stops HTML tags from seeing event • function your_f(e){ e.preventDefault(); } • similar to HTML's <a onclick="return false;"> • .stopPropagation() • event stops traveling down/up to other tags
Useful event Properties • .target = same as this; the object of the event • .keyCode, charCode = character pressed • .shiftKey, .ctrlKey, .altKey = true/false if down • .button = mouse button # down (only 1 at a time) • .clientX, .clientY, .screenX, .screenY = mouse • .bubbles = event is bubbling up
variable "binding" • Problem: event handler function lack parameters • onclick="your_f(anything, I, want...)" • addEventListener( 'click', your_f) • nothing you want can be given to your_f
Solution 1 • Javascript can hack any object • tagObject.addEventListener('click', your_f); • tagObject.myInformation= "hello"; • function your_f(e) { • alert(this.myInformation); • alert(e.target.myInformation); }
Solution 2:variable "binding" • Solution: exploit Javascript's memory management • function f(){ • var x=5; • setTimeout( function(){alert(x);},1000); • } f(); • variables actually DIE when nothing uses them
variable "binding"(see Closure) • Variables are references to memory storage • memory storage is freed when there are no more references • If you ADD references to the storage it will live until all of them are gone • javascript event handling HEAVILY uses "binding"
function attach_an_event(){ • var myInformation= "hello"; • var your_f= function(e){ • alert(myInformation); • } • tagObject.addEventListener('click', your_f); • } • // myInformation is "bound" to your_f • // it lives until your_f dies and that will not die • // if you removedEventListener then it would die • // if you removed tagObject then it would die
function your_f(your_evt, your_info){ • alert(this);alert(your_evt.type);alert(your_info); • } • function bind( tag, evt, f, info ){ • var middleman= function(event){ • return f.call(event.target, event, info); • }; • tag.addEventListener(evt, middleman); • } • bind(document.body, "click", your_f, "hello");