The functionality of document.elementFromPoint(x, y) seems to be faulty in accurately identifying child elements

I've been trying to retrieve the element over which a "drop" event occurs, but I keep getting unexpected results. It consistently returns parent elements instead of the actual child element where the dragged element is dropped on.

For a full code example on CodeSandbox, check out the link provided above. Here are some snippets from the code...

<div>
    <div id="sidebar">
      <drag :transfer-data="{ type: 'textbox', width: 330, height: 50 }" class="draggable-item"
        >Textbox
        <div slot="image" class="drag-image"><div class="field-container" style="width: 330px;height: 50px;">Texbox</div></div></drag
      >
    </div>
    <div id="pages-container" @click.self="deselectAll();">
      <b-alert show variant="info" class="text-center">Drag controls from the left sidebar to the pages below.</b-alert>
      <drop
        class="page-container"
        v-for="(p, index) in pages"
        @drop="onDrop"
        @click.self="deselectAll();"
        :data-page-number="p.pageNumber"
        :key="p.pageNumber + '_page_' + index"
        :style="{ width: p.width + 'px', height: p.height + 'px' }"
      >
        <img src="https://www.kirupa.com/flash/images/single_column_text.png" width="100%" height="100%" :data-page-number="p.pageNumber" @click.self="deselectAll();" />
        <div style="position: absolute;top:0;bottom:0;left:0;right:0;background-color:white;opacity:0" :data-page-number="p.pageNumber" @click.self="deselectAll();"></div>

        <vue-draggable-resizable
          :id="f.id"
          :style="{ 'z-index': '1044 !important' }"
              ...

The JavaScript snippet below corresponds to the issue mentioned above (the page number alert always shows as undefined)...

onDragStop(x, y) {
  //...
  const el = document.elementFromPoint(x, y);
  alert("Dropped onto page number: " + el.dataset.pageNumber);
}

Answer β„–1

According to @Joao's observation, the method document.elementFromPoint() necessitates viewport coordinates while VueDraggableResizable provides offset coordinates relative to the initial drop-element based on its configured lock aspect ratio and bounds. One way to still obtain the viewport coordinates is by extracting them directly from the draggable item itself.

Instructions:

  1. Begin by adding a ref to the <vue-draggable-resizable> component (which generates an array of references to the draggables), and modify the dragstop handler to include an index parameter that will be used in conjunction with the corresponding ref in the subsequent step:

    // template
    <vue-draggable-resizable
        v-for="(f, f_index) in ..."
        ref="draggable" πŸ‘ˆ
        @dragstop="(x,y) => onDragStop(x,y,f_index)" πŸ‘ˆ
        >
    
    // script
    onDragStop(x, y, πŸ‘‰index) { ... }
    
  2. Inside the dragstop handler function, disable the pointer-events on the referenced draggable element's $el (associated with the index from the previous step) so that document.elementFromPoint() can identify the element positioned under the draggable's viewport coordinates, obtained using getBoundingClientRect():

    onDragStop(x, y, index) {
      const draggable = this.$refs.draggable[index].$el;
      draggable.style.pointerEvents = 'none'πŸ‘ˆ
    
      const { left: dragX, top: dragY } = draggable.getBoundingClientRect();
      const targetElem = document.elementFromPoint(dragX, dragY);
    
      draggable.style.pointerEvents = 'auto'
    
      ...
    }
    

Check out the demo here!

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 the purpose of re-checking the user in the passport.deserializeUser function?

After reading multiple articles on how to utilize passport.js, I'm left wondering why user verification is repeated within the passport.deserializeUser function. The code snippet looks like this: passport.deserializeUser((id, done) => { console. ...

Establish characteristics for the temporary print document

Struggling to configure the properties of a temporary file created for later printing by the user. Here's a breakdown of the process: User clicks on "Print Map Area" button on the website. A menu appears asking for preferred dimensions (e.g. A4 ...

Running a CSS keyframes animation can be achieved by removing the class associated with it

Is there a way to reverse the CSS animation when a class is removed? I'm trying to achieve this on my simple example here: https://codepen.io/MichaelRydl/pen/MWPvxex - How can I make the animation play in reverse when clicking the button that removes ...

What is the best way to transfer variables from an ng-template defined in the parent component to a child component or directive?

Is there a way to pass an ng-template and generate all its content to include variables used in interpolation? As I am still new to Angular, besides removing the HTML element, do I need to worry about removing anything else? At the end of this ...

Limiting the number of times a specific character appears using a regular expression

Currently, I am in search of a regular expression that allows me to set a limit on the number of times a special character can appear. For instance, if I want to restrict the occurrence of * to a maximum of 5 times in the entire text, then the output shou ...

Error 2300 in Vetur: Identical identifier found for '(Missing)'

Recently, I've been encountering a strange issue with Vetur in my typescript nuxt.js project. Every component, whether it's just an empty line or contains code, displays an error message on the first line. I can't pinpoint when this problem ...

Does React trigger a re-render when setState is called even if the state value remains unchanged?

Imagine I create a React component with an initial state of {random: 1}. Now, if I were to execute the following code: this.setState({random: 1}) Would this action result in triggering a re-render of the component? Furthermore, is there a method to avoid ...

Choosing all components except for one and its descendants

I am searching for a method to choose all elements except for one specific element and its descendant, which may contain various levels of children/grandchildren or more. What I'm trying to accomplish is something like... $("*").not(".foo, .foo *").b ...

Jasmine test failing due to uninitialized angular controller

I encountered some difficulties while writing jasmine tests for an AngularJS application that utilizes angular ui-router. Despite proper initialization of my services and app in the test, I found that the controllers were not starting up correctly. In an e ...

The list item click event is not triggered when new list items are added

I've run into a bit of confusion with my code. Everything seems to be working perfectly fine until I introduce new items. Take a look at a sample of my items However, once I make changes to my list, the click function stops working. Check out a sa ...

"Performing validation on a number input by using the ng-change event

Im using a number input that dynamically sets the min and max values based on another form field. I have two scenarios: Level 1: Min = 2, Max = 50 Level 2: Min = 5, Max = 1000 I've set up an ng-change event on the input field to check if the entere ...

How to style large numbers with AngularJS

I'm facing a challenge with large numbers in a table and I'm seeking a solution to format them, ideally as $13b, $10m... Has anyone encountered this issue before and discovered a customized filter or solution for it? Appreciate any help! ...

Running a designated AJAX function from a variable by utilizing Applescript

Struggling to execute a JavaScript code within a page using Applescript. In the JavaScript, an AJAX function was defined like so: var myFunction = function () { // Here be the code... } I attempted this in Applescript: do JavaScript "document.myFunct ...

What is the best way to iterate through elements that come after a specific element?

I'm confident that I will be able to provide an answer to this very soon... Here's a sample code snippet: <script> function ClearAndRunFuncs(element) { //Clears responses for elements AFTER this element with an onchange //Executes the uni ...

JavaScript, keep it easy: globalize

Looking for help with a simple regex expression... document.getElementById('testing').value=f2.innerHTML.replace(">",">\n"); I'm having an issue where it only stops after the first line break. How can I make it work for the enti ...

The jQuery application adds new HTML elements to the page and then reveals the code that follows

When making an Ajax call and rendering two templates based on the response, I encountered a problem where the correct template renders but the script following it appears on the page as plain text. Here's the code snippet with the issue: if (question ...

Troubleshooting the issues with implementing cross-browser jscrollpane functionality

Hey there! I've been exploring this tool to customize the default scroll-bar, and here's a fiddle showcasing my experimentation. In the fiddle, I've included the following code snippet <div class="scroll-pane horizontal-only">(located ...

Is it really necessary to still think poorly of JavaScript in 2011?

Here's an intriguing question for you. I've tested out a variety of popular websites, including Facebook, and I've noticed that many features still work perfectly fine even when JavaScript is disabled. People always used to say that JavaScr ...

Is there a way to generate random numbers that will create a chart with a general upward trend?

Are you looking for a solution to generate random numbers for charts that trend upwards and to the right? I am currently utilizing a JavaScript charting engine, so I will require numbers in JSON format eventually. However, I am open to alternative methods ...

The act of initiating a click on a radio button involves evaluating conditions prior to toggling

Apologies for the slightly ambiguous title, let me provide a clearer explanation. I have created a codepen to demonstrate an issue that I am facing. You can view it here. In my codepen, I have two toggle buttons labeled "Male" and "Female" for simplicity. ...