30 Days Of JavaScript

Day 17: Events

Lesson 2: onmouseover and onmouseout

Target vs currentTarget

CSS have the :hover pseudo class that allows us to change styling when we hover the mouse over an element. What if we want to do more than that though. What if we want to change some data. Let's add a due day to our todo and show it when we hover.

To do that we will use two events, the onmouseover event to show the due day and the onmouseout to hide it again.

First of all we need to learn about target and currentTarget, add this line to your todos.forEach() function on the line above listItem.append(content).

1listItem.onmouseover = (e) => {
2  console.log(e.target.innerText);

Now hover over Bake cake in your list and look at the console. You will see Bake cakeDone because that is all the text inside the element you have hovered on, even though the button is a child element it's text appears here as well.

Now hover on a Done button. You will see Done in the console. Does this make sense?

Let's think about this. We added an event to the <li> so when we hover on it we see all it's innerText. That makes sense because the .target is the thing we hovered on.

But when we hover on the <button> we still get the event but now we only see the Done text. This is is because the .target and how events bubble up through the DOM.

We hovered on the button, which is the target because our cursor is on it. It doesn't have an onmouseover event handler, but it does bubble the event up to it's parent element, the <li>, which does have an onmouseover event handler, so this gets triggered and we see the log. But we don't see it's full text, just the Done ... because the target is still just the <button> that caused the event to fire.

So, what if we want to get a reference to the <li> even when we hover on the child <button>, we can use currentTarget which is a reference to the element that has the event handle and not the element that caused the event in the first place.

Change e.target.innerText to e.currentTarget.innerText, hover on the button and see that we now go back to logging Bake cakeDone 😁

So this is actually really important to get. The element that causes the event to fire, isn't always the same as the thing that actually has the event handler attached to it.

If you ever need to check "is the thing that fired this event (target) the same as the thing that is calling the event handler (currentTarget)" then you can do this check in your event handler:

1element.onmouseover = (e) => {
2  if (e.target !== e.currentTarget) {
3    return;
4  }
5  // code you want to run

onmouseover and onmouseout

So, how do we show this due day, let's get to it.

Change your todos array to this:

1const todos = [
2  { description: "Walk dog", important: true, due: "today" },
3  { description: "Watch TV", important: false, due: "today" },
4  { description: "Bake cake", important: false, due: "tomorrow" },

and now add this inside your listItem.onmouseover function

1const due = document.createElement("p");
2due.textContent = todoItem.due;

This will create a paragraph tag and show it below the item. Hover on an item and see what happens.

It works but the due day stays on the screen and then more and more add as you hover around. So now we need remove them!

After your onmouseover function and before listItem.appendChild(content); add this function:

1listItem.onmouseout = (e) => {
2  const p = listItem.getElementsByTagName("p");
3  listItem.removeChild(p[0]);

This gets all the child paragraphs in the <li> and then removes the first one (there will only be one as onmouseover will only fire one when your cursor enters the <li> so we can just remove the first, and only, child paragraph)

Go hover now, much better.

Not the greatest UI to look at but for this course that doesn't matter too much, we are just focussing on the functionality of JavaScript and not the styling of HTML and CSS. If you want to make this experience really nice and are good with HTML and CSS then you have all the tools you need to make something really nice looking - go have fun 😊


Go Pro?

If you upgraded to pro, sign in here

  • About
  • Blog
  • Privacy
Looking to email me? You can get me on my first name at allthecode.co