Struggling to create a universal list open/close click event

As a new part of my online CV (Now hosted on Github),
I’m working on a universal event listener where I pass the list of data entries of a corresponding section and open and close them.

Here’s some of the code I wrote so far to test it.

const careerList = document.createElement("div");
careerList.classList.add("hide");
careerSection.appendChild(careerList);

Each section in my CV (i.e. Skills, Career, etc.) would have a div with the class “hide” underneath their h2 titles which I can open and close by either clicking the title or the corresponding link on the navigation bar.

careerHeading.addEventListener("click", toggle(careerList));

Here, I make the careerHeading (the Career sections h2 title) an even listener for the function toggle and pass the careerList variable as an argument.

function toggle(i) {
  i.classList.toggle("hide");
};

I create a function that takes whatever variable it’s been passed and toggle its “hide” class.

But right now, when I run the website, I found that the function runs automatically without me clicking the event listener. I took the function out and the list is closed but when it runs with the function, it runs only once - opening the list and I can’t run the function again to close it.

What am I doing wrong?

1 Like

check this out, if I understood your idea more or less, something like in my pen can work:

it is here

this stuff will work if

h2 is the first child of section

div is the second child of first section

keyword this represent the heading in our case - in general it’s the stuff which was clicked on

As for your code, I am learning DOM just recently, but still:

I’ve never saw callback function in eventlistener with parameter:

And one more little thing

you called your own function toggle - the method toggle already exists in JavaScript, so it may be a bit confusing. I personaaly would give this function more descriptive specific name.

The second argument for an event listener has to be a function.

const myF = ( ) => “hi”

careerHeading.addEventListener("click", myF)

It can also receive the event, which is useful here.

For example,

careerHeading.addEventListener("click", toggle);

And it can be redefined a bit, as it will access the Event object.

function toggle(ev) {
  ev.target.parentElement.classList.toggle("hide");
};

As an advice, I’d call it collapse rather than hide, and I’d keep the h2 just hide the body of the section. A CV should be short enough not to need a table of contents imho.

And the hovering color that you currently has, needs an lower opacity maybe in the range 0.8 or 0.5.

Hi.

Sorry it took me so long to get back to you.
I got it all figured out and here’s what I came up with.

careerHeading.addEventListener("click", open);
function open(i) {
  i.target.parentElement.children[1].classList.toggle("collapsed");
};

It worked perfectly…!

Except, now the next challenge is to get the links in my navigation bar to open corresponding sections as I click them and I realize that adding this same function to them isn’t going to cut it because the function will kinda target the <a> tags themselves, not the sections they link to. facepalm

well, yes

But you can create some constants, lets say for sections.

And you can refer these constants somehow inside the function.

Just first general idea, I am sure there is bunch of approaches to this stuff.

Nice code, still can be improved but the most important step is getting a good mental model. That looks good. You can accept your solution I think.

I am not convinced with the hovering effect highlighting whole sections, but apart from that you got a good taste, it looks good.