Activate an event on a shadow DOM element that is covered by an element in the light DOM (not directly related)

I am currently facing a challenge in retrieving the coordinates of a table cell within a shadow DOM. This table cell may have overlay elements displayed above it, which could span over multiple cells and may not necessarily be direct children of the cell I am interested in.

Despite my efforts to make the event bubble through the table as expected, I suspect that event retargeting within the shadow DOM is causing issues. Additionally, attaching an event listener to every cell for performance reasons (considering there will be hundreds of cells in the final application) is something I'd like to avoid.

The use of "pointer-events: none;" property seems close to solving my issue, however, I also need the event to trigger on the light DOM overlay element. Given that the overlay element is not a child of the cell where I want to obtain the coordinates from, I'm unsure if this approach is feasible.

In my implementation using vanilla JavaScript, I wonder if there is a way to correctly retrieve the coordinates of the underlying table cell when the overlay div is clicked.

class Custom_Grid extends HTMLElement {
  constructor() {
    super();

    this.attachShadow({
      mode: 'open'
    });
    this.shadowRoot.innerHTML = `
        <style>
          td {
            height:50px; width:50px; border: 1px solid grey;            
          }
        </style>
        <table>
        <tr>
        <td id='x0y0'><slot name='x0y0'></slot></td>
        <td id='x0y1'><slot name='x0y1'></slot></td>
        <td id='x0y2'><slot name='x0y2'></slot></td>
        </tr>
        <tr>
        <td id='x1y0'><slot name='x1y0'></slot></td>
        <td id='x1y1'><slot name='x1y1'></slot></td>
        <td id='x1y2'><slot name='x1y2'></slot></td>
        </tr>
        <tr>
        <td id='x2y0'><slot name='x2y0'></slot></td>
        <td id='x2y1'><slot name='x2y1'></slot></td>
        <td id='x2y2'><slot name='x2y2'></slot></td>
        </tr>
        
      `;
  }
  connectedCallback() {
    this.shadowRoot.addEventListener("click", () => {
      if (e.target.matches('td'))
        console.log(`Grid Cell: ${e.target.id}`)
    });
  }

}

window.customElements.define('custom-grid', Custom_Grid);


document.getElementById('grid_overlay').addEventListener("click", () => {
  console.log("#overGrid Click")
});
#grid_overlay {
  width: 100px;
  height: 100px;
  background-color: grey;
  position: absolute;
}
<custom-grid>
  <div slot='x1y0' id='grid_overlay'></div>
</custom-grid>

Answer №1

One way to solve this issue is by temporarily concealing the overlay element so that we can access the covered element using the elementFromPoint() method.

if ( e.target.id === 'grid_overlay' ) {        
   console.log( 'overlay click' )
   e.target.hidden = true 
   var el = this.shadowRoot.elementFromPoint( e.x, e.y )
   if (el.id)
     console.log( 'under: ', el.id )
   e.target.hidden = false
}

class Custom_Grid extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
    this.shadowRoot.innerHTML = `
        <style>
          td {
            height:50px; width:50px; border: 1px solid grey;            
          }
        </style>
        <table>
        <tr>
        <td id='x0y0'><slot name='x0y0'></slot></td>
        <td id='x0y1'><slot name='x0y1'></slot></td>
        <td id='x0y2'><slot name='x0y2'></slot></td>
        </tr>
        <tr>
        <td id='x1y0'><slot name='x1y0'></slot></td>
        <td id='x1y1'><slot name='x1y1'></slot></td>
        <td id='x1y2'><slot name='x1y2'></slot></td>
        </tr>
        <tr>
        <td id='x2y0'><slot name='x2y0'></slot></td>
        <td id='x2y1'><slot name='x2y1'></slot></td>
        <td id='x2y2'><slot name='x2y2'></slot></td>
        </tr>
        
      `;
  }
  connectedCallback() {
    this.shadowRoot.addEventListener("click", (e) => {
      if (e.target.matches('td'))
        console.log(`Grid Cell: ${e.target.id}`)
      else if (e.target.id === 'grid_overlay' ) {        
        console.log( 'overlay click ' )
        e.target.hidden = true 
        var el = this.shadowRoot.elementFromPoint( e.x, e.y )
        if (el.id)
          console.log( 'under: ', el.id )
        e.target.hidden = false
      }
    });
  }
}

window.customElements.define('custom-grid', Custom_Grid);
#grid_overlay {
  width: 100px;
  height: 100px;
  background-color: grey;
  position: absolute;
}
<custom-grid>
  <div slot='x1y0' id='grid_overlay'></div>
</custom-grid>

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

Resize the image to fit the dimensions of a div, but unfortunately, the overflow: hidden property is not effective in this

I'm looking to set up an image gallery using the Bootstrap grid layout. The gallery should span 100% width and consist of two grids in a row, each containing one picture. I want the height of the second picture to match that of the first, with croppin ...

Create a complete duplicate of a Django model instance, along with all of its associated

I recently started working on a Django and Python3 project, creating a simple blog to test my skills. Within my project, I have defined two models: class Post(models.Model): post_text = models.TextField() post_likes = models.BigIntegerField() post_ ...

Troubleshooting a problem with the transition of the hamburger menu icon in SC

I'm encountering an issue with the transition property and attempting to utilize the all keyword. After including a fiddle, I can't seem to figure out if I've made a simple mistake or if there is something else going on. I have seen the all ...

Generating unique names based on input from users

We are working with an array containing names and an input field where users can enter a string to receive name suggestions. The array includes names like Alex and Anna, and when the user types "a," we want to suggest these names. Below is the code snippet ...

405 error: NGINX blocking POST method in Django DRF Vue.js application

I have encountered a strange issue while building my ecommerce site. Everything seems to be working fine, except for the forms. When attempting to post content, I keep receiving a 405 method get not allowed error. It's confusing as I am trying to use ...

What is the best way to convert an object into an array of objects for use in a select search functionality

I am attempting to map key and value pairs into a single array in order to use them as selectsearch options. I have successfully mapped each item individually, but now I need to combine all the data into one array. How can I achieve this? Here is how I am ...

Obtain the name of the client's computer within a web-based application

I am working on a Java web application that requires the computer name of clients connecting to it. Initially, I attempted to retrieve this information using JavaScript and store it in a hidden form field. However, I discovered that JavaScript does not hav ...

Adding a collection of items to an array in preparation for organizing

Realizing that sorting objects is not feasible - despite the necessity of having the object values sorted - I conclude that the only option is to move the object array content into a new array for sorting purposes. The following code generates the output ...

Utilizing Angular's factory and $resource in your project

For my first app using Angular, I have defined my service as: angular.module('mean.testruns').factory('Testruns', ['$resource', function($resource) { return $resource('testruns/:testrunId', { testrunId: ...

Troubleshooting problem in Vercel with Next.js 13 application - encountering "Module not found" error

Encountering a deployment issue with my Next.js 13 application on Vercel. I recently implemented the Parallel Routes feature of Next in my codebase. While pushing the changes to create a new pull request on GitHub, the branch's deployment on Vercel is ...

The peculiar characteristics of the dragLeave event in various web browsers

I observed a peculiar behavior while working with drag events in Internet Explorer 11. It seems that adding a 'width' property to the elements triggers the dragLeave event, whereas without it, the event does not fire. Can anyone shed light on why ...

What is the best way to create a unique shadow effect for a container in Flutter?

I am facing a challenge with my screen layout that uses GridView.builder with crossAxisCount: 3. In the itemBuilder, I am returning a Container with shadows on the left, right, and bottom, but so far, I have not been able to achieve the desired outcome. H ...

Are there any userscripts available for interactive websites?

I frequently create small GreaseMonkey UserScripts for my personal use. However, I often struggle with a recurring issue: How can I adapt to the changing nature of websites? For example, popular webstores like Amazon now update content dynamically withou ...

Steps for adding an HTML string to a div element using Ajax

I am facing some major challenges with Ajax, especially when it comes to appending HTML code to a div. I am attempting to append this HTML string to <div id="content-loader"></div> PHP function getLogo(){ $logo = '<div class="bg- ...

Using jQuery to handle multiple AJAX XML requests

Currently, I am working on developing a JavaScript XML parser using jQuery. The idea is that the parser will receive an XML file containing information along with multiple links to other XML files. As the parser runs, it will identify tags within the file ...

Tips for partitioning an element using Selenium and Appium when it lacks a distinctive ID, class, package, or resource identifier:

I am currently trying to determine if I am receiving the expected response from a text message. In order to do this, I need to access the text view of the incoming message. The challenge I am facing is how to distinguish between the received text and the s ...

When trying to set the state in the OnMouseOver event, an error is thrown: TypeError - React is

Despite encountering numerous posts discussing this issue, I am struggling to resolve it in my particular scenario. I have a collection of items that I am attempting to apply color changes to (the div's) when they are hovered over. The coloring only ...

Ensure the div remains fixed in its position regardless of the page's height

I am seeking assistance with making two divs of equal height on my website. The left div contains dynamic content that may expand vertically with various inner divs. Meanwhile, the right div has a single inner div that should remain visible at the top ev ...

Literal Route Waypoints Guidance Service

I am currently working on an angularjs directive that utilizes the Google Maps Direction Service. In my controller, I have a getFunction that watches for changes in a scope variable. Once the scope variable changes, it triggers the calculateAndDisplayRoute ...

When you hover over the button, a picture will appear

This is an example code snippet from W3Schools. It showcases an animated button that reveals a small arrow next to the text when hovered over. The specific line of code responsible for this effect is .button span:after {content: '\00bb'. How ...