0

I'm new to JavaScript/HTML/CSS and I can't spot the mistake I'm doing in this JavaScript function. Our teacher told us to use the addEventListener method cause it has some notable advantages.

This is my entire script with the problematic function

 var espandi = function (e) {
    var toHide = document.getElementsByClassName("optional");
    for (var index = 0; index < toHide.length; index++)
        toHide[index].style.display = "none";
    var toShow = e.target.getElementsByClassName("optional");
    for (index = 0; index < toShow.length; index++)
        toShow[index].style.display = "block";
}
var expansibleObjects = document.getElementsByClassName("singleresult");
for (var index = 0; index < expansibleObjects.length; index++)
    expansibleObjects[index].AddEventListener("click",espandi);

The fact is the line e.target.getElementsByClassName gets me an error of this type

Uncaught TypeError: Cannot read properties of undefined (reading 'getElementsByClassName').

On the contrary, if I set the function with the property "onclick" directly on the element the function works perfectly. So I think the problem it's about referring to the calling object using e.target

Update 1

First of all, I want to say that this is a project for university and I cannot publish the whole code, it would be risky for my exam. Then there are more issues apparently. First of all with the method getElementsByClassName() applied on document it seems that he can get the Collection of Elements but then if I try to print the single Element it gives me undefined on the log. Here's the code:

var list = document.getElementsByClassName("prova");
if (list[0]) {
    console.log("Assigning using \"list[0]\" as check");
    list[0].onclick = espandi();
    list[0].addEventListener("click",espandi);
    console.log("finished adding listeners");
}
else if(list.item(0)){
    console.log("Assigning using \"list.item(0)\" as check");
    list.item(0).onclick = espandi();
    list.item(0).addEventListener("click",espandi);
    console.log("finished adding listeners");
}
else console.log("failed assignment");
console.log("printing list");
console.log(list);
console.log("printing list[0]");
console.log(list[0]);
console.log("printing list.item(0)");
console.log(list.item(0));

and here's the log output: log output

Apparently the only way I succesfully make my script work is editing the function this way:

function espandi (caller) {
    var toHide = document.getElementsByClassName("optional");
    for (var index = 0; index < toHide.length; index++)
        toHide[index].style.display = "none";
    var toShow = caller.getElementsByClassName("optional");
    for (index = 0; index < toShow.length; index++)
        toShow[index].style.display = "block";
}

and then assigning it to elements directly using the "onclick" HTML attribute, like this:

<table class="prova" onclick="espandi(this)">

so that the parameter "caller" refers to the element who actually triggered the function espandi. The problem is I really want to know 2 things:

  1. how to refer to the caller using an EventHandler function (in the case of method .addEventListener()) and a normal function (in the case of the attribute .onclick of the desired element) in JS.
  2. how to manage the method getElementByClassName() and the collection returned by itself.

In the end, just to sum up, now I have problems with assigning the event listeners and also with referring to the caller without using a parameter like this in the HTML code I showed you.

2
  • You don't want the parentheses when assigning the event handler: expansibleObjects[index].onclick = espandi;. You're invoking the function during the assignment...you don't want to do that. With addEventListener it's the same: expansibleObjects[i].addEventListener('click', espandi); Commented Dec 16, 2021 at 18:02
  • Sorry man, I've totally mistaken the code. That actually was one of many tries to make it work, but was not correlated to my question. Commented Dec 17, 2021 at 8:52

1 Answer 1

1

You are calling espandi instead of assign it to onclick handler.

So you need to remove the () and do expansibleObjects[index].onclick = espandi;

Anyway in your question I don't see any e.target.addEventListener() so when you say The fact is the line e.target.addEventListener() gets me an error I don't understand what you mean, maybe you have to add more code.

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

3 Comments

Sorry mate I've adjusted the code right now. That was one of many tries that I've done to make it work, unsuccessfully. Anyway the main focus is how can I refer to the caller while assigning the event listener with the function addEventListener()
@GabrielePassoni the code seems to be right. Can you provide a codesandbox or a code snippet with all the js and html code in order to reproduce the problem? In this way we can help you better.
i've just updated my question with new issues. Please check them out

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.