What is the best way to incorporate child nodes when selecting dynamically generated elements through JavaScript?

Currently, I have buttons being dynamically generated on the page using plain JavaScript.

For example:

<button class="c-config__option c-config__option--button c-config__option--pack" data-index="0">
    Item 1
    <span>Subtext</span>
</button>
<button class="c-config__option c-config__option--button c-config__option--pack" data-index="1">
    Item 2
    <span>Subtext</span>
</button>
...

When targeting the parent class (.c-config__wrapper) and using event.target to access the buttons, clicking on the span within the button changes the target from the button to the span itself.

How can I ensure that the parent button continues to remain the target when using plain JavaScript? Alternatively, how do I include the span as a target along with the button?

Answer №1

The documentation on MDN highlights the presence of a method within the event object called composedPath. This method stores an array of objects where listeners will be triggered, excluding nodes in shadow trees if the shadow root was created with its ShadowRoot.mode set to closed.

While this functionality appears to function correctly in Chrome, the extent of support for this method across different browsers is not clearly outlined in the documentation.

Further examination of the event object unveiled the existence of a property named event.path, which holds the same path array – at least in Chrome. Strangely, no information can be found regarding event.path in any documented source.

In light of this ambiguity, some sources recommend using

var eventPath = event.path || (event.composedPath &&
  event.composedPath());
instead of solely relying on
var eventPath =
  event.composedPath();
.


If your browser does indeed support it, you have the option to traverse through the path of the clicked element and verify whether it is a child of a button or the button itself.

The following code snippet exemplifies this procedure and retains a reference to the button element for future usage:

document.getElementById('wrapper').addEventListener('click', function() {
  // actual element clicked
  console.log(event.target);

  var buttonClicked = false;
  var button;

  var eventPath = event.composedPath();
  for (let i = 0; i < eventPath.length; i++) {
    if (eventPath[i].tagName && eventPath[i].tagName.toLowerCase() === 'button') {
      buttonClicked = true;
      button = eventPath[i];
      break;
    }
  }

  if (buttonClicked) {
    console.log(button);
    console.log('button was clicked');
  }
})
<div id="wrapper">
  <button class="c-config__option c-config__option--button c-config__option--pack" data-index="0">
    Item 1
    <span>Subtext</span>
</button>
  <button class="c-config__option c-config__option--button c-config__option--pack" data-index="1">
    Item 2
    <span>Subtext</span>
</button>
</div>

An alternative approach involves replicating jQuery.closest by utilizing the solution presented in this Stack Overflow post: DOM / pure JavaScript solution to jQuery.closest() implementation?

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Show a mpld3 graph in an HTML page using the Django framework

Incorporating mpld3 to showcase matplotlib charts within an HTML page through django has been my recent focus. I utilize the mpld3.fig_to_dict method to convert a matplotlib figure into a JSON string and store it in a variable. However, I am encountering ...

Creating a plotly.js integration for nuxt SSR: A step-by-step guide

Currently facing issues with setting up plotly.js in my nuxt project. Despite trying various approaches, I keep encountering the error message self is not defined. Installing both plotly.js and plotly.js-dist did not resolve the issue. My attempt to creat ...

Robotic Arm in Motion

GOAL: The aim of the code below is to create a robotic arm that consists of three layers (upper, lower, and middle), all connected to the base. There are four sliders provided to independently move each part except for the base which moves the entire arm. ...

Successive pressing actions

I am struggling to grasp a unique Javascript event scenario. To see an example of this, please visit http://jsfiddle.net/UFL7X/ Upon clicking the yellow box for the first time, I expected only the first click event handler to be called and turn the large ...

The Ajax success callback unexpectedly displays the number "1" in the top left corner of the empty page instead of updating the specified div

Currently, I am in the process of developing a Yii2 application. I have encountered an issue where I select data from a Bootstrap modal popup and submit it to a controller action that contains an insert query. The problem arises after submitting the data f ...

Switch out the icons within a return statement in JavaScript

Help! I have 5 empty star icons (<StarBorderIcon/>) displayed for a product on the material-ui website. I need to replace them with filled star icons (<StarIcon/>) based on the rating entered into a function. I attempted to use replace(), but i ...

Is there a simpler and more refined approach for handling Observables within RxJS pipelines?

Picture this: I have an observable that gives me chocolate cookies, but I only want to eat the ones without white chocolate. Since I am blind, I need to send them to a service to determine if they are white or not. However, I don't receive the answer ...

The React Material-UI Slider does not move when OnChangeCommitted is triggered

Struggling with implementing the Material UI slider in React, I encountered an issue where the OnChange function would trigger every time the value changed. I needed it to activate only when the left mouse button was released. Fortunately, I discovered a s ...

Hey there, could you please set up the DateTimePicker in my expo project using React Native?

Hey everyone, I'm currently trying to set up DateTimePicker but encountered an error. Here's the issue: npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: undefined@undefined npm ERR! Fou ...

Having trouble with setting up the next image configuration for graphcms' images

I've been using graphcms solely for my image assets and trying to integrate them into my Next JS (v12.0.1) frontend. However, I keep getting the error message hostname not configured in next.config.js, even though I have already specified it in my nex ...

How can I determine if a specific button has been clicked in a child window from a different domain?

Is there a method to detect when a specific button is clicked in a cross-domain child window that cannot be modified? Or determine if a POST request is sent to a particular URL from the child window? Below is an example of the HTML code for the button tha ...

Is there a way to automatically interpret and analyze a gruntfile in order to make changes to it and then resave it?

I'm working on a intricate Yeoman Generator and I'm in search of a solution to parse an existing gruntfile. If anyone knows a JavaScript method for parsing a gruntfile, your assistance would be greatly appreciated. ...

A collection of items that mysteriously affix themselves to the top of the page as

Unique Context In my webpage, I have a specific div element with the CSS property of overflow: auto. Within this scrolling div, there is structured content like this: <h3>Group A</h3> <ul> <li>Item 1</li> <li>I ...

Issues with date clicking on FullCalendar in Angular

I'm currently using version 4.4.0 of the FullCalendar plugin, but I am facing an issue where the dayClick event is not being triggered in my code. Below is a snippet of my code: calendar.component.html <full-calendar defaultView="dayGridMonth ...

Can you explain the function of "app.router" in the context of Express.js?

When looking at the default app.js file generated by express.js, I came across the following line: ... app.use(app.router); ... This particular line of code has left me perplexed for a couple of reasons. First, upon consulting the express api documentati ...

The toggleClass() function is only toggling between a single class

I'm currently facing an issue with a jQuery/Angular function that is triggered on click. <a ng-click="like()" href="#" class="like like--yes"></a> Essentially, my goal is to switch between the classes like--yes and like--no when the like ...

"Simply tap on an element that has been dynamically inserted into the

Many individuals are familiar with how to attach a "click" event to an element that is dynamically added using the following syntax: $('#main').on('click','.link',function(){ //some code here }); In this example, .link repr ...

Using Flask and AngularJS: Managing Scope in a Controller with Flask Templating

Currently, my primary objective is to create a table with sortable columns. While following a tutorial and attempting to implement it into my project, I have encountered an issue. It seems that the structure of my code will not allow this functionality to ...

Tips on fetching the ID of the selected option using JavaScript without relying on jQuery

Looking to print the selected option ID using pure Javascript (not JQuery) for multiple select tags. If we have more than one select tag, how do we achieve this? <select onchange="showOptions(this)" id="my_select1"> <option value="a1" id="ida ...

What is the best method to determine the currency associated with the code in dinero.js?

Is there an easy way to locate the dinero currency in the dinero.js/currencies package using its code? For example, a function called getCurrency that accepts a string as input and outputs the corresponding dinero currency. ...