tldr; I need an element to register drag and drop pointer events, but pass click and other pointer events to elements behind it.
I am building a drag and drop photo upload feature in react using react-dropzone
. I want the dropzone
to be over the whole page, so if you drag a file onto any part of the page, you can drop it to upload the image. The dropzone
is transparent when no file is dragged over it, so I need clicks to register with elements behind it.
To accomplish this, I gave the dropzone component the following style:
position: fixed; top: 0; left: 0; right: 0; bottom: 0; pointer-events: none;
However, pointer-events: none;
causes the dropzone
to not recognize the necessary drag and drop events. Is there any way to recognize these specific pointer events, while passing others (like click) to elements behind the dropzone
?
The pointer-events property allows for control over how HTML elements respond to mouse/touch events – including CSS hover/active states, click/tap events in Javascript, and whether or not the cursor is visible.
Conclusion. To disable clicking inside a div with CSS or JavaScript, we can set the pointer-events CSS property to none . Also, we can add a click event listener to the div and then call event. preventDefault inside.
Pointer events are DOM events that are fired for a pointing device. They are designed to create a single DOM event model to handle pointing input devices such as a mouse, pen/stylus or touch (such as one or more fingers). The pointer is a hardware-agnostic device that can target a specific set of screen coordinates.
Use pointer-events-auto to revert to the default browser behavior for pointer events (like :hover and click ). Use pointer-events-none to make an element ignore pointer events. The pointer events will still trigger on child elements and pass-through to elements that are “beneath” the target.
Try using the draggable
attribute. It worked for me
<p draggable="true"> jkjfj </p>
UPDATED ANSWER:
#dropzone{ position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 10; //set this to make it sit on the top of everything pointer-events: none; } .user-is-dragging #dropzone{ pointer-events: all !important; }
//element declarations const dropzone = document.getElementById("dropzone"); const body = document.body; //timeout function to help detect when the user is dragging something let dragHandle; // utility function to detect drag & drop support function dragDropSupported() { var div = document.createElement('div'); return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div); } function initDragDrop(){ //simply exit / do other stuff if drag & drop is not supported if(!dragDropSupported()){ console.warn("Drag & drop not supported"); return; } //add user-is-dragging class which enables pointer events for the drop event body.addEventListener("dragover", (e) => { body.classList.add("user-is-dragging"); clearTimeout(dragHandle); dragHandle = setTimeout(() => { body.classList.remove("user-is-dragging"); }, 200); }); //this is to prevent the browser from opening the dragged file(s) dropzone.addEventListener('dragover', (e) => { e.preventDefault(); }); dropzone.addEventListener('drop', (e) => { //prevent the browser from opening the dragged file(s) e.preventDefault(); //dragged files const files = e.dataTransfer.files; console.log(files); }) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With