Gabriele Passoni
Gabriele Passoni

Reputation: 105

Referring to the calling object in JavaScript using addEventListener

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.

Upvotes: 0

Views: 929

Answers (1)

Marco Nisi
Marco Nisi

Reputation: 1241

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.

Upvotes: 1

Related Questions