How do we handle parent elements of clicked elements using Javascript event delegation?

http://jsfiddle.net/walkerneo/QqkkA/

In the realm of Javascript event delegation, there are many discussions related to using it for elements that serve as targets for click events. However, a less explored topic is how to implement event delegation for elements that are not necessarily the targets of the click event.

Take, for example:

HTML:

<ul>
    <li><div class="d"></div></li>
    <li><div class="d"></div></li>
    <li><div class="d"></div></li>
    <li><div class="d"></div></li>
    <li><div class="d"></div></li>
    <li><div class="d"></div></li>
</ul>​

CSS:

ul{
    padding:20px;
}
li{
    margin-left:30px;
    margin-bottom:10px;
    border:1px solid black;

}
.d{
    padding:10px;
    background:gray;
}
​

How can we add a click event handler for the li elements when they're clicked? Attaching an event handler directly to the ul element will always result in the divs being the target elements. Besides checking every parent of the target element within a click function, is there another way to achieve this?

Edit:

I am looking to utilize event delegation instead of:

var lis = document.getElementsByTagName('li');
for(var i=0;i<lis.length;i++){
    lis[i].onclick = function(){};
}

However, if I attempt:

document.getElementsByTagName('ul')[0].addEventListener('click',function(e){

    // e.target is going to be the div, not the li
    if(e.target.tagName=='LI'){

    } 
},false);

EDIT: I'm not interested in utilizing Javascript libraries for this. My focus is on understanding how it's done and implementing it with pure js.

Answer №1

Here is a solution method:

const list = document.getElementsByTagName('ul')[0]

list.addEventListener('click', function(e){
  let el = e.target
  // Move up the tree until we find an LI element
  while (el && el.tagName !== 'LI') {
     el = el.parentNode
  }
  console.log('clicked item', el)
}, false)

This approach may be too simplistic, as it continues moving up the tree even beyond the UL element. For a more comprehensive example, refer to the implementation in rye/events.

The use of methods such as Element.matches, Node.contains, and Node.compareDocumentPosition can enhance the implementation of similar functionalities.

Answer №2

A new feature has been introduced for elements known as the closest method. This method allows you to specify a CSS selector and it will find the closest ancestor element that matches the selector, including the element itself if applicable. While all current versions of desktop browsers support this feature, it is still not recommended for production use. For those interested, there is a polyfill available on the MDN page linked above.

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

What is causing the error that app.js file cannot be located?

Here is the layout of my directory: ReactCourse // Main folder public // Subfolder within ReactCourse index.html // HTML file with linked js file app.js // JavaScript file This is the content of index.html: <!DOCTYPE ...

The React/Redux application is experiencing difficulties with API calls, as they are returning empty responses and the actions are not being triggered

Hey there, I'm currently working on a React Native app and running into some issues with making API get requests. It seems like the response is throwing an error and the action isn't executing properly. I'll share my code below, so if anyone ...

What is the method for gaining access to variables and functions within bundle.js?

Hello, I am trying to figure out how to access variables in bundle.js. I want to experiment with variables and functions on the client side using JavaScript, but I'm having trouble calling them in index.html or the Chrome console. I use browserify to ...

What are the steps for implementing custom edit components in material-react-table?

I am currently using the official material-react-table documentation to implement a CRUD table. You can find more information at this link: . However, I encountered an issue while trying to utilize my own custom modal components for the "create new" featur ...

Include a new key and its corresponding value to an already existing key within FormData

I have a form that includes fields for title, name, and description. My goal is to submit the form values using an API. To achieve this, I am utilizing jQuery to add key-value pairs to the FormData variable: formdata.append('description_text', jq ...

Eliminate Video Time Indicator

Can the video progress bar be removed from this specific video player? I would like it to be integrated into the embed code that I share with others. <iframe id="hapyak-player-157199-8825" marginwidth="0" marginheight="0" frameborder="no" scrolling=" ...

Prevent clicking here

I'm attempting to only prevent the click event on the current item with a certain class. $(document).on('click', '.item', function() { $(".item").removeClass('is-expanded'); $(this).addClass('is-expanded'); ...

Managing POST request data in Express: A step-by-step guide

Currently, I am facing an issue with my alert button on the client side, which has an event listener that is supposed to send data to the server. Below is the code snippet for the client side: alertBtn.addEventListener("click", () => { axios ...

Can I use a custom font in an HTML5 canvas?

Has anyone had success importing a custom font for use in HTML5 canvas? I've been trying to do this by loading the font file on my computer, but all my attempts have failed so far. The canvas keeps showing the default font instead of the one I want to ...

Python: Mimicking Splinter/Selenium Functionality to Test a JavaScript-Driven Website

My automated bot interacts with a dynamic website using Splinter and Selenium. Despite its effectiveness most of the time, it occasionally encounters exceptions due to random events. Debugging these occurrences is quite challenging, especially since the we ...

Fade the current Div out and fade in the following Div while also animating its child element

Looking to achieve a fade in and out effect for 3 divs, with the child element animating its way up from the bottom right once the divs have faded in. I've been working on it but haven't made much progress, does anyone have any ideas? Check out ...

How can I structure the response from HttpClient to make it compatible with *ngFor

I need assistance in solving a minor issue. I am working with data from a REST API, which is returned as an array of objects. After receiving this data in my service, I attempt to transform it and push it to a subject to notify my component about the arriv ...

Tips for transferring backend information to show up as options in a multiselect dropdown menu (Jsfiddle link included)

Here is a reference to a fiddle link -->> https://jsfiddle.net/etfLssg4/ In the fiddle, users can select multiple dropdown items. The dropdown values are initialized with Lisa and Danny as the default items. These default selections are displayed in ...

Tips for placing a div within a curved div?

I've got a nested div situation, <div style="background-color: red; height: 100px; width: 100px; border-radius: 10px;" id="div1"> <div style="background-color: orange;" id="div2"> testing </div> </div ...

What could be causing the NaN error when parsing a number in Javascript?

I'm having trouble figuring out why I keep getting a NaN when I try to print a number with JavaScript. This code snippet is used in multiple places on the website and usually works without any issues. The URL where this issue is occurring is: Here ...

Receive notifications when asynchronous processes are completed

I recently came across this code online that allows me to upload multiple files to an Amazon S3 server. const AWS = require("aws-sdk"); // import AWS SDK const fs = require("fs"); // import file system module from node.js const path = require("path"); // ...

In the scenario where there are duplicate 'id' keys within the array of objects, what is the best method to remove the object with the duplicate key?

When there are duplicate 'id' keys among the objects in the array, how can you remove the object with the duplicated 'id'? I attempted to use filter, map, and set methods, but none of them were successful. Since the array is not one-di ...

What is the best method for resizing an SVG according to the size of my website's window?

I am attempting to implement a scalable settings icon SVG file that adjusts based on the window width. My approach involved creating a JavaScript function that alters the element's dimensions according to the window size, but unfortunately, this metho ...

What steps can I take to resolve my password validation rule when confirming during sign-up?

Utilizing react-hook-form in combination with Material-UI for my sign-up form has been a challenge. I am currently working on implementing a second password field to confirm and validate that the user accurately entered their password in the initial field, ...

Creating a redux store with an object using typescript: A step-by-step guide

Having recently started using Redux and Typescript, I'm encountering an error where the store is refusing to accept the reducer when working with objects. let store = createStore(counter); //error on counter Could this be due to an incorrect type set ...