1

I'm having trouble getting an event listener to apply to all items in an array I've created. I've looked at lots of other related posts here, but none seem to cover my precise situation.

I know the for loop is working because I'm logging it out to the console and can see each iteration pop up. I can even see in the console that the event listener has been applied to each iteration, but won't fire when actually mousing over the element on the page.

Any clues on what I might be missing? The complete code is below.

<head>
    <title>Test Page</title>
</head>

<style>
    .red-text {
        color: red;
        font-size: 75px;
        transition: 4s;
        font-family: Times;
    }

    .new-header {
        color: blue;
        font-size: 100px;
        transition: 3s;
        font-style: bold;
    }
</style>

<body>
    <h1>Welcome</h1>
    <p>This is the first paragraph</p>
    <p>Here is the second paragraph</p>
    <p>And this is the final paragraph</p>

    <script>


        var h = document.querySelector("h1");
        var p = document.querySelectorAll("p");

        var changeHeader = function() {
            h.className = h.className + " new-header";
        }

        var addRedClass = function() {
            p.className = p.className + " red-text";
        }

        h.addEventListener("mouseover", changeHeader); 

        for(var i = 0; i < p.length; i += 1) {
            console.log(p[i]);
            p[i].addEventListener("mouseover", addRedClass);
        }

    </script>

</body>

Again, each element in the array is being targeted, and I can verify that the listener is being applied, but it will not fire on mouse over.

Thanks in advance for any advice!

1
  • p might not have dimensions via CSS in the DOM that allow it to be mouseovered perhaps. Commented Aug 31, 2016 at 15:03

2 Answers 2

5

You need to have the right scope on the addRedClass function.

var addRedClass = function() {
    this.className = this.className + " red-text";
};

By using this.className, you are referencing the <p> tag that was moused over.

The reason you don't need need to use this in the changeHeader function is because the variable h only contains the header node. The variable p however, contains a nodeList which is not a single reference to a <p> node. Therefore, when the addEventListener fires, it will pass the <p> tag you mousedover to the addRedClass as the scope. That is why this works to change the className.

Sign up to request clarification or add additional context in comments.

1 Comment

Brilliant! This fixed it perfectly. Thanks for the insight!
3
p[i].addEventListener("mouseover", addRedClass);

So whenever any of the elements in p is moused over, the addRedClass function is called. This is fine.

Now let's look at that function:

p.className = p.className + " red-text";

You modify the className of p.

Which is the non-live NodeList of element objects.

It doesn't have a className property (until you create it).

Presumably want to use to this.className or loop over p and use p[i].className repeatedly.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.