Lost in Multiple Event Handling Purgatory


#1

The prelude is that I’m trying to learn JS on my own (books, YouTube, Udemy, etc.) and have created a test problem for myself that I cannot figure out how to solve.

In the project, I’m attempting:

  1. Multiple events for many elements
  2. Tabs (which work fine - I think)
  3. Efficient code (vanilla JS, DRY)

Here’s a working CodePen (minus the tabs) for one aspect. The window opens with three buttons:
Control: displays an image
Show: shows an image for 2 seconds
Stay: shows the same image until you click another button

I’m trying to ramp this up as follows:

  1. Four versions of the above CodePen code with each version in it’s own tab on the same page.
  2. Each version uses the same three buttons, but within its own tab
  3. Each version uses a different set of three images and their displaying properties

My failing attempt at that is in this Pen.
There, I’ve loaded the images into an Array of Objects. But then I got lost as to how to run the tabbed content image display using a single set of functions for all tabs. So I tried coding each separately, but that failed as well.

I’m assuming I’m missing a whole lot here as my understanding of loops, arrays, objects, etc. is limited (though growing). I think I can use a single loop to control populating the content area for each tab, but am now quite lost.

Can anyone push me in the correct direction?


#2

Have you looked into this tutorial: https://www.kirupa.com/html5/handling_events_for_many_elements.htm

That will give you a good idea of how to deal with having a single parent element handle all of the event listening for all of its descendants :stuck_out_tongue:


#3

Yep. In fact that’s what got me started!
Trouble is, I lost my way - big time.


#4

You are on the right track. I would move all of your event listening to the container div element. Inside the event handler for that, you can perform the equivalent checks you are doing in each duplicated section of code.

Does this help a bit?


#5

I made those changes on a forked Pen, to no avail. The result was that buttons on the first tab ended up calling images from the second tab instead - head bangs against the wall.

Maybe I’m approaching this all wrong?
Overall goals:

  1. The functionality in this working Pen times 4 on the same page, with each version accessible via a tab.* The four versions will call different images and the timer aspect will be different on each.
  2. Vanilla JS
  3. No JS in the HTML, other than pulling in the scripts.js file.
  4. As efficient as possible (DRY).

*I have the tabs worked out already. Each tab is its own div.

It seems to me that having four versions of the code (each tied to the three buttons within each tab) is overkill and inefficient. I simply cannot figure out how to fold the four versions in one array of objects (or think of another solution). Searching the problem led me to your video (linked in your first response).

I’m about at the point that I’m ready to pay someone $50 to figure this out and comment it so that I can learn. :thinking: It seems like it ought to be so simple but clearly it’s beyond me at this point.

I’ve watched 6 different tutorials on Arrays, and another 4 on loops but cannot seem to pull that knowledge into something workable.


#6

What you are trying to do isn’t easy, so you shouldn’t feel bad that you are running into some difficulties. Here is one way to think about this: in each tab, you have an image component that supports three states: control, show, stay. These have a certain set of properties on them that are unique to the tab you are in.

To help visualize what gets clicked from a single event listener, take a look at the following pen: https://codepen.io/kirupa/pen/eQdpNb?editors=1111

This is the code I added to the top:

var container = document.querySelector(".container");
container.addEventListener("click", printElement, false);

function printElement(e) {
  console.log(e.target);
}

Take a look at the Codepen console to see what gets printed for each tab and element click. One approach is to use a bunch of if statements or switch statements and special case the behavior for whatever element gets clicked.

Does that help more?

Cheers,
Kirupa


#7

Thanks for that.

I looked at the Pen and that does help me comprehend what’s actually happening. Your suggestions (if or switch and case) makes sense too since I’ve studied some of that already.

Before I act on it though I thought it best to try a version without tabs (using separate divs instead) and doing it long-hand, so to speak. I also reduced it to two states (show and stay), as well as opened each main div with the control image visible.

This Pen ( https://codepen.io/squinter/pen/pQEgqb )* shows exactly what I’m after (prior to trying to make the JS more efficient via your suggestions).

*For some reason the forum no longer lets me post links to CodePen - hence the pre-formatted text link.


#9

Looks like my initial post and my second one was flagged by multiple community members as SPAM. Why?


#10

Dunno. It was marked as a system flag, not a particular user, but I re-approved the posts, so you’re good. :slight_smile:


#11

We probably have spam bots registered as regular users who report everything that’s not spam as spam… to help promote the real spam.


#12

Thanks.
It’s not paranoia if everyone is after you. :rofl: