Adding an Event Listener

Browsers are busy pieces of software. Every tap, click, scroll, and keystroke is noticed by the browser. Each of these is an event that the browser may respond to. To make websites more dynamic and interactive, you can trigger your own code when one of these events occurs. In this section, you will add event listeners to each of your thumbnails.

An event listener is an object that, as the name suggests, “listens” for a particular event, such as a mouse click. When its assigned event occurs, the event listener triggers a function call in response to the event.

(Mouse events, like clicks and double-clicks, and keyboard events like keypresses are among the most common event types. For a complete listing of events, check the event reference in the MDN at developer.mozilla.org/​en-US/​docs/​Web/​Events.)

The addEventListener method is available on every DOM element, including the document. As before, you will experiment with some code in the console first and then use your tested code to write functions in main.js.

Switch to Chrome and enter the following code in the console. You will need to press Shift-Return to enter the line breaks. Press Return when you have finished typing all the code.

document.addEventListener('click', function () {
  console.log('you clicked!');
});

The code you entered added an event listener for the document object that is listening for any clicks that occur on the page. When a click happens, the event listener will print you clicked! to the console using the built-in console.log method (Figure 6.23).

Figure 6.23  Adding a listener for click events

Adding a listener for click events

Click on the header, the detail image, or the background. You should see that the text you clicked! appears printed in the console. (Do not click the thumbnails – those will take you away from Ottergram’s index.html page. When you are not on the index.html page, none of your markup, CSS, or JavaScript will be loaded and running in the browser.)

addEventListener accepts two arguments: a string with the name of the event and a function. This function will be run by addEventListener any time the event occurs for the element. The way this function is written may look a little strange at first. It is an anonymous function.

So far, you have worked with named functions, like setDetails and titleFromThumb. Named functions have names – no surprise there – and are created using function declarations.

You can also write literal function values, the same way you can write literal number values like 42 and literal string values like "Barry the Otter". Another name for literal function values is anonymous functions.

Anonymous functions are frequently used as arguments to other functions, like the one you passed as the second argument to document.addEventListener. This practice of passing a function to another function is quite common in JavaScript and is known as a callback pattern because the function you pass in as an argument will get “called back” at some point in the future.

It is perfectly fine to use a named function as a callback, but many front-end developers will use anonymous functions because they can provide more flexibility than named functions. You will see how this works shortly.

Now you will add an event listener for an individual thumbnail. Enter the following in the console. (Remember to use Shift-Return for the line breaks in the call to firstThumbnail.addEventListener.)

var firstThumbnail = document.querySelector(THUMBNAIL_LINK_SELECTOR);
firstThumbnail.addEventListener('click', function () {
  console.log('you clicked!');
});

If you try clicking the first thumbnail (Barry the Otter, farthest to the left), your browser will take you to the large image of Barry. What happened? Remember that each thumbnail is wrapped in an anchor tag with an href that points to an image, like img/otter1.jpg. This is the normal behavior of a browser when a user clicks a link: It has opened the file indicated by the href attribute.

But you do not want to navigate away from Ottergram when a thumbnail is clicked, and you should not have to change your anchor tags to something else. Luckily, you can handle all of this from your callback function.

Recall from earlier in the chapter that functions carry out their tasks without you having to worry about the details. Usually you only need to know what information to pass as arguments and what information will be returned. When you pass a callback function as an argument, there is one more thing you need to know: what information will be passed to your callback.

When you call addEventListener, you are telling the browser, “When the firstThumbnail is clicked, call this function” – and then the browser diligently waits for that element to be clicked. If a click happens, the browser makes note of all the details about the event (such as the exact position of the mouse, whether it was the left or right mouse button, and whether it was a single or double click). The browser then passes an object with this information to your function. This object is an event object.

This relationship is diagrammed in Figure 6.24, using a made-up implementation of addEventListener.

Figure 6.24  Passing an anonymous function that expects an argument

Passing an anonymous function that expects an argument

In a moment, you will pass an anonymous function to addEventListener, just like before. But, this time, your anonymous function will expect to receive an argument. Make sure Ottergram is on the index.html page and enter the following in the console:

var firstThumbnail = document.querySelector(THUMBNAIL_LINK_SELECTOR);
firstThumbnail.addEventListener('click', function (event) {
  event.preventDefault();
  console.log('you clicked!');
  console.log(event);
});

The browser will call your anonymous function each time firstThumbnail is clicked, and it will pass your anonymous function the event object. Using this object (which you have labeled event), you call its preventDefault method. This method will stop the link from taking the browser to a different page. Finally, you call console.log on the event object so that you can inspect it in the DevTools.

Now click on the first thumbnail. Your browser remains on the Ottergram page and the event is logged to the console: MouseEvent {isTrusted: true}. If you click the disclosure arrow next to MouseEvent, you should see quite a bit of information about the event (Figure 6.25), including the mouse coordinates on the page, which mouse button was clicked, and whether any special modifier keys were pressed during the click.

Figure 6.25  Preventing the event default and logging the event object

Preventing the event default and logging the event object

For now, do not focus on the different properties of the event object. Just know that it carries lots of information about the browser event that was triggered.

By the way, it is not required that the callback function’s parameter be named event – it will be mapped to the value that is passed in no matter what you name it. You can use whatever parameter names you like, but it is good practice to use descriptive names, as you have done here, to make your code easier to read and maintain.

You now have a function that accepts a thumbnail and adds an event listener. Add a function declaration to main.js for addThumbClickHandler. It should define a parameter named thumb.

You can copy your experimental addEventListener code from the console and paste it into the body of addThumbClickHandler. Modify it so that you are calling thumb.addEventListener. For now, you will only need the call to event.preventDefault in the event callback.

...
function setDetailsFromThumb(thumbnail) {
  ...
}

function addThumbClickHandler(thumb)
  'use strict';
  thumb.addEventListener('click', function (event) {
    event.preventDefault();
  });
}

Inside the event callback, you have access to the thumb parameter declared as part of addThumbClickHandler. Pass it to a call to setDetailsFromThumb.

...
function addThumbClickHandler(thumb) {
  'use strict';
  thumb.addEventListener('click', function (event) {
    event.preventDefault();
    setDetailsFromThumb(thumb);
  });
}

JavaScript, like many other programming languages, has rules about defining and accessing variables and functions. The anonymous function you passed to addEventListener is able to access the setDetailsFromThumb function because setDetailsFromThumb was declared in the global scope. This means that it can be accessed from any other function or from the console. The same is true for variables like DETAIL_IMAGE_SELECTOR, which is also declared in the global scope.

However, the variables detailImage and detailTitle, which you declared inside setDetails, are only available within the body of setDetails. You cannot access them from the console or from other functions. These variables are declared in the function scope (or local scope) of setDetails. A function’s parameters work very much like variables declared inside a function. They too are part of that function’s scope.

Normally, functions cannot access variables or parameters that are part of another function’s scope. addThumbClickHandler is interesting because it defines the parameter thumb, which is accessed by another function – the callback function you passed to addEventListener. This is possible because the callback function is part of addThumbClickHandler’s scope.

You can read more about how all of this works in a For the More Curious section at the end of this chapter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.225.255.187