The .on() Method

With the release of jQuery 1.7, the .on() method came as a replacement for the earlier .bind(), .live() and .delegate() methods.

The .on() method lets us attach one or more event handlers to selected elements and their descendants and takes the syntax below

jquery on
				
				$(elements).on(events,descendant,data,handler)
				
			
events
Required. One or more events (separated by spaces) attached to the selected element. The events can also be namespaced.
descendant
Optional. Specified descendants of selected elements to which the the event handler is attached.
data
Optional. Data that you intend to pass to the handler when the event is triggered.
handler
Required. The function to be executed when the event is fired.

We start this lesson by attaching the click event handler to the only <p> element in the document. When the <p> element is clicked, the console logs a message.

				
				<!DOCTYPE html>
				<html lang="en">
				<head>
					<title>Title of this Page</title>	
					<script type="text/javascript" 
						src="//code.jquery.com/jquery-latest.min.js">
					</script>
				</head>
				<body>
				    <p>This is a paragraph.</p> 

				    <script type="text/javascript">
				    	$(document).ready(function(){
							$("p").on("click", function(){
							    console.log("You clicked a paragraph.");
							});
						});
				    </script>
				</body>
				</html>
				
			

Now let us append another paragraph element below the existing paragraph. We can type the following code into the browser console

				
				$("body").append("<p>This is another paragraph.</p>");
				
			

A new paragraph element will then be appended below the existing one. But if you click on it, the console message does not appear. This is because when the .on() method was initially called, the direct event is attached only to the existing <p> element - not to the not-yet-existed paragraph element we appended later.

This is where event delegation comes in handy and where the .on() method does the work of the previously available .delegate() method, allowing us to attach event listener to an element that will trigger for all its descendants matching the selector, irrespective of their current existence in the document or in the future.

Event Handler on Descendants

Events are propagated up the DOM. So when the paragraph element <p> is clicked, the click event fires for the paragraph element and bubbles up the DOM tree in the sequence: <p>, <body> and <html>. This behaviour allows us to attach a delegated event to a descendant, which will inherit the binding event of the ancestor. We illustrate this below by attaching the click event to the <body> element and assigning its descendant element "p" as the second parameter of the .on() method. On click of <p>, a message is logged into the console.


				$(document).ready(function(){
					$("body").on("click", "p", function(){
					    console.log("You clicked a paragraph.");
					});
				});
				

Now as before, we will try appending another paragraph element below the existing paragraph by typing the below code into the browser console

					
					$("body").append("<p>This is another paragraph.</p>");
					
				

On click of the newly appended <p> element, the console will now log a message.

Passing Data

Data can be passed as an argument to the .on() method which is then passed to the handler via the event.data property. Below we pass a plain object with the element property having the value 'paragraph'

					
					$(document).ready(function(){
						$("body").on("click", "p", {element: 'paragraph'}, function(e){
						    console.log("You clicked a " + e.data.element);
						});
					});
					
				

Multiple Events

The .on() method also has a provision to attach multiple events to the same element. We illustrate this below by toggling the background colour of an <input> element on focus and blur.

Insert an internal style which consists of a class called .highlight that colours the element's background red

					
					<style>
					.highlight {		  
					    background-color: red;
					}
					</style>
					
				

Add an <input> element into the body of the document

					
					<input type="text"/>
					
				

We make use of jQuery's .toggleClass() method to toggle between adding/removing the .highlight class inside the common handler of the focus and blur events attached to the <input> element

					
					$(document).ready(function(){
						$("body").on("focus blur", "input", function(e){
						    $(this).toggleClass("highlight");
						});
					});
					
				

Notes

  • To understand event bubbling better, try attaching alert() method as a handler to the onclick event in the document's <html> element as
    							
    							<html onclick="alert('')">
    							
    						
    It will be fired after the <p> element is clicked.