JavaScript Events
Events are where all the magic happens in JavaScript. Whatever context you are working within (be it a browser window or on the system/server level using Node.js), it’s pretty safe to say that a lot of “stuff” is constantly happening… clicks, loads, mouseovers, AJAX requests and responses — these are the types of things your website or application will need to respond to. In this section we will take a look at how we can use events in JavaScript…
Adding Events in the DOM
Like with many things in software, there are many different ways to do things. In the past you may have often seen stuff like the following…
<script type="text/javascript">
function showMessage(){
alert("Hello world!");
}
</script>
<input type="button" id="messageButton" value="Submit" onclick="showMessage()" />
Here we are adding an event to this button by calling a function in the onclick attribute. This code will work fine in all modern browsers (and even really really old browsers). However this is not exactly the best approach because it intermixes application/business logic (JavaScript) with our view (HTML). A better approach is to pull this code out of the view…
var b = document.getElementById("messageButton");
b.onclick = function(){
alert("Hello World");
};
<input type="button" id="messageButton" value="Submit" />
Here we have created a separation of concern and our button is free from having business logic intermixed within it.
However, this too is not even the best approach. What if we wanted to add multiple click events to our button? We could certainly perhaps call multiple functions within the onclick function, but a better approach is to use the addEventListener function because multiple events can be attached to one element…
var b = document.getElementById("messageButton");
b.addEventListener("click", function() {
alert("Hello World...");
}, false);
b.addEventListener("click", function() {
alert("Hello again...");
}, false);
Removing Events
A big advantage to using addEventListener is that we can add multiple listeners to a single element. But there is also another big plus: if we want to remove specific events we can use the removeEventListener function to remove listeners. Unfortunately there’s also an issue with the approach we used above. The following does not work because we passed in anonymous functions as callbacks when we first set addEventListener…
var b = document.getElementById("messageButton");
b.addEventListener("click", function() {
alert("Hello World...");
}, false);
b.removeEventListener("click", function() { }, false);
To actually remove the event, we have to give our function a name when we first set our event listeners…
var b = document.getElementById("messageButton");
var handler = function(){
alert("Hello World...");
};
b.addEventListener("click", handler, false);
b.removeEventListener("click", handler, false);
And yes, it will also work with the other function form…
var b = document.getElementById("messageButton");
function handler(){
alert("Hello World...");
};
b.addEventListener("click", handler, false);
b.removeEventListener("click", handler, false);
Event Context: this and event
Event context is available to the developer to be used for whatever purpose is needed. For example, in our “click” example above, the this pointer is the element that was acted upon — in this case, the button. So you could, for example, get the id of the button clicked…
var b = document.getElementById("messageButton");
var handler = function(){
alert(this.id);
};
b.addEventListener("click", handler, false);
Or you could do other things such as change the style…
var b = document.getElementById("messageButton");
var handler = function(){
this.style.backgroundColor="blue";
};
b.addEventListener("click", handler, false);
Even if you have other buttons on the page, JavaScript determines the context from the click event so that only the button that was actually clicked is acted upon. What that means is that even if you attach an event listener to other buttons and use handler as a callback, only buttons that actually are clicked will have the code in handler executed on them.
You can also get information about the event that’s occurring but in that instance you actually have to pass the event into the callback function like so. You may not need to do anything with the event object, so doing this is optional, however it is there if you need it. For example, below we pass the event as an argument named “e” and we can get the event type from e (in this case “click”)…
var b = document.getElementById("messageButton");
var handler = function(e){
alert(e.type);
};
b.addEventListener("click", handler, false);
There are many other useful things you can do with the “this” pointer and the event object. This only shows a quick demo of how you can use them.
Event Types
Up until now, we’ve only looked at the click event type, but there are a lot of other event types that you listen for with add event listener. Below is a listing of some common ones…
- UI Events - events having to do with the DOM and the browser. “load”, “unload”, “scroll”, and “resize” are in this category
- Focus Events - fired when an element gains or loses focus, such as when a cursor is placed in an input field.
- Mouse Events - the mouse is used to perform an action on the page. “click” is one of these.
- Text Events - fired when text is input into the document.
- Keyboard Events - fired when the keyboard is used to perform an action on the page.
For example, to execute some JavaScript immediately after all of the content on the page is loaded you could do something like the following where you attach an event listener to the window (global) object…
var afterLoad = function(){
alert("Page Loaded");
};
window.addEventListener("load", afterLoad, false);
And to fire an event when the user scrolls you could do something like the following…
var windowScrolled = function(){
console.log('You scrolled me');
};
window.addEventListener("scroll", windowScrolled, false);
Be careful though as this event is particularly sensitive and will fire numerous numerous times if the user scrolls rapidly. If you want to only fire things once, you could do something called “debouncing” using the setTimeout and clearTimeout functions in JavaScript…
var scrollTimeout;
var windowScrolled = function(){
clearTimeout(scrollTimeout);
scrollTimeout = setTimeout(function() {
console.log('You scrolled me, but I am only going to talk about it once');
}, 300);
};
window.addEventListener("scroll", windowScrolled, false);
Creating and Dispatching Events
There may be situations where you want to “simulate” an event. That is, you want to run code that is attached to your event even if the evenr does not actually occur due to user interaction. For example, suppose we had our same button that displayed a message to the user that we saw previously. What if we wanted to display that same message at some point within our application even if the user did not click the button. Instead of writing a wholly separate function that does the same thing (i.e. creating duplicate code… a no-no in software development), we can create an event with the createEvent function and then dispatch the event (simulate the click) with the dispatchEvent function to essentially hook into that functionality that we had already defined…
var b = document.getElementById("messageButton");
var event = document.createEvent("MouseEvents");
event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
b.dispatchEvent(event);
This example shows how we can simulate a click event, but we could simulate any of the other event types mentioned above. Notice the initMouseEvent function in the example which has 10 zillion parameters. Each simulated event that you create is going to have different arguments that you pass into them and different ways of implementing them. You’ll have to consult JavaScript documentation to find out just exactly what you’ll need to do depending on the particular type of event you are working with. For example, here is the page for the initMouseEvent function for the Mozilla Developer Network.
The jQuery method trigger essentially just uses this same implementation of creating and dispatching events.
Conclusion
We have only just scratched the surface of using events in JavaScript. There are many more types of events and many more things you can do when they happen. But this should give you a good introduction on how you can register them and what you can do with them. So use your events wisely, young grasshopper.






0 Responses to JavaScript Events