Understanding the concept of event bubbling through the use of querySelector

I am currently working on implementing an event listener that filters out specific clicks within a container.

For instance, in the code snippet below I am filtering out clicks on elements with the class UL.head.

<div>
 <ul class="head">
  <li data-test="...">1</li>
  <li>2</li>
  <li>3</li>
 </ul>
 <ul class="head">
  <li>1</li>
  <li>2</li>
  <li data-test="...">3</li>
 </ul>
 <ul class="head">
  <li>1</li>
  <li data-test="...">2</li>
  <li>3</li>
 </ul>
</div>
document.querySelector('div').addEventListener('click', function(e) {

  var ul = findParentByClass(e.target, ".head");
  if(ul) { // clicked a UL }

});

function findParentByClass(node, cls) {
    while (node && !hasClass(node, cls)) {
        node = node.parentNode;
    }
    return node;
}

I want to create a new function similar to findParentByClass, but this time it would be called findParentByQuerySelector. This way, I could potentially use it like so:

li = findParentByQuerySelector('li:[data-test]');
if(li) { // clicked li with data-test attribute }

However, I am struggling to figure out how to incorporate a querySelector into this event bubbling logic.

Answer №1

If you're looking for a way to find the parent element based on a specific selector, one approach is to utilize the Element.matches method:

function getParentBySelector(node, selector) {
    while (node && !node.matches(selector)) {
        node = node.parentNode;
    }
    return node;
}

It's worth noting that the implementation of this method may not be consistent across all browsers.

Alternatively, you could opt for using Element.querySelectorAll, which searches within the specified element's children. Keep in mind that you will need to consider not only direct parents but also grandparents:

function getParentBySelector(node, selector) {
    while (node && node.parentNode) {
        let elements = node.parentNode.querySelectorAll(selector);
        if (Array.prototype.includes.call(elements, node)) {
          return node
        }
        node = node.parentNode;
    }
    return node;
}

However, it's fair to say that this method is not the most elegant solution available.

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

I am utilizing client-side JS to send a large number of requests. What methods can I implement to enable my server to cache this content

Here's a bit of an unusual question from someone who is new to this - I have client-side JavaScript that is making API calls using the getJSON method. Since the content doesn't change frequently, I would like to store the results on my server an ...

AJAX not showing validation error message

For the past two days, I've been grappling with an issue and can't seem to pinpoint where it's coming from. After leaving the textbox, the Ajax call functions correctly and returns results as either true or false, triggering the success fun ...

Clicking on an element triggers the addition of a class, and the newly

Once the page has finished loading, I am able to utilize jQuery to add a specific class in the following way. $(document).ready(function() { $("#parent").click(function(){ $(".child").addClass("active"); }); }) ...

Whenever a user logs in or logs out from the child component, the app.js is not being re-rendered

I'm having trouble figuring out how to re-render the app.js function. It loads initially, but when I click the login or logout button, I need to call a function from the helper again to check the user status. Here is the code snippet for App.js: impor ...

Access the CSV file using Office365 Excel via a scripting tool

Objective I want to open a CSV file using Office365's Excel without actually saving the file on the client's machine. Challenge The issue with saving raw data on the client's machine is that it leads to clutter with old Excel files accumu ...

Tips for Implementing {{ }} within Angular Filters in Nested ng-repeat statements

I am looking to incorporate {{ }} within the Angular "filter" filter, specifically while nested inside an ng-repeat. Let's consider the relationship below: var categories = [ {"title":"land"}, {"title":"sea"}, {"title":"air"} ]; var vehi ...

The information returned to the callback function in Angular comes back null

In my Node.js application, I have set up an endpoint like this: usersRoute.get('/get', function(req, res) { //If no date was passed in - just use today's date var date = req.query.date || dateFormat(new Date(), 'yyyy-mm-dd&ap ...

The VueJS component from a third-party source is not located in the node_modules directory

Utilizing vue-cli version 3 for a fresh vuejs project (I've been dedicating ample time to learning vuejs, but this marks my initial attempt at integrating a third-party component). I'm aiming to incorporate a visually appealing grid component. Th ...

What is the best way to retrieve the values of various input fields using their numbered IDs and then store them in a MySQL

I attempted to design a form that allows for multiple inserts, where users can add as many titles and languages as they desire by entering a number. The display of titles and languages is functioning correctly, but I am struggling to retrieve the individua ...

Ways to retrieve a JSON element and incorporate it into a CSS styling

Can someone assist me in converting a JSON object for use in CSS? I've attempted to do this using Vue.js, creating a map legend with v-for to generate the legend. However, if there is an alternative method that allows me to take a JSON object and ins ...

Is there a way to insert a dot after every two digits in a text field using Javascript upon keypress?

When inputting a 4-digit number (e.g. 1234) in my text field with value format 00.00, I want it to automatically adjust to the 12.34 format. How can I achieve this behavior using JavaScript on keyup event? ...

Evaluation of Library (VueJS) - Displaying various components in an individual test case

Just starting out with testing and have a simple question: I am working on testing a checkbox component. I understand the basics, but how can I render multiple components within one it block? Here is my current code. I am stuck on the second test where I ...

Guide on utilizing JSON data sent through Express res.render in a public JavaScript file

Thank you in advance for your assistance. I have a question that has been on my mind and it seems quite straightforward. When making an app.get request, I am fetching data from an external API using Express, and then sending both the JSON data and a Jade ...

Modify URL parameters using history.pushState()

Utilizing history.pushState, I am adding several parameters to the current page URL after performing an AJAX request. Now, based on user interaction on the same page, I need to update the URL once again with either the same set of parameters or additional ...

In React js, I wanted to display the animation specifically on the "add to bag" button for the added item

When I click the "add to bag" button, all other buttons also display the animation. How can I make sure that only the clicked button shows the animation? Any suggestions? <Table responsive> <thead> <tr> ...

Steps for showing personalized validation error messages in Angular 7

Is there a way to highlight the input field of a form with a red border and display the message Password is invalid when a user types in a password that does not match the set password? I have managed to see the red border indicating an error when I enter ...

Tips for showcasing an uploaded image with ajax

I am looking to upload an image and display it without having to reload the page. I believe this can be achieved using Ajax form submission. However, I have tried some code but the Ajax form submit function does not seem to be working for me. Can someone p ...

Troubleshooting JavaScript If-Else Statements

Having a bit of trouble with my if else structure. When I enter the correct star name like "Vega", it incorrectly shows me "Error" instead of the expected result "Lyra". Here's my code snippet: var stars = ["Polaris", "Aldebaran", "Deneb", ...

Utilizing jQuery's .clone() function to duplicate HTML forms with radio buttons will maintain the radio events specific to each cloned element

I'm currently developing front-end forms using Bootstrap, jQuery, HTML, and a Django backend. In one part of the form, users need to input "Software" information and then have the option to upload the software file or provide a URL link to their hoste ...

Working with Node.js and JavaScript's Date object to retrieve the time prior to a certain number of hours

I am currently working on a script in node.js that is able to locate all files within a specific directory and retrieves their modified time: fs.stat(path, function(err, states){ console.log(states.mtime) }) After running the script, it ...