Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove pointer-events from all children of the element with a dragover event?

I created a global dragover event listener so that when something it dragged over the page it would show a dragover area on the page and hide it when you move the cursor off the page:

 document.addEventListener('dragover', event => { 
   event.preventDefault()
   this.dragOverArea = true
   // ...
 })

 document.addEventListener('dragleave', event => { 
   event.preventDefault()
   this.dragOverArea = false
   // ...
 })

Problem

JSfiddle: http://jsfiddle.net/ct3haqf0

Try dragging any file over the elements on the page (from the top left) you will see the dragover event switching to dragleave rapidly back and forth which makes the drop area appear/disappear while you dragging it through the elements.

In my project it creates a noticeable lag. The problem is, dragover event conflicts with all the element's children (and hence activates dragleave), so it constantly shows/hides the drop area while you're dragging something over the page full of elements

Question

I found that you're supposed to set: pointer-events: none to all the children of the element with dragover listener, so I have to set this rule to body * { }

So how do I set this rule to all children of the body with JS inside addEventListener('dragover') ?

like image 790
Un1 Avatar asked Oct 28 '25 14:10

Un1


2 Answers

What about adding an class to the body, which can be styled with CSS?

adding classes:

function addClassToBody( newClass )
{
    document.body.className += " "+newClass+" ";
}

function removeClassFromBody( oldClass )
{
    document.body.className = document.body.className.replace(" "+oldClass+" "," ");
}

CSS:

body.drag * {
    pointer-events: none !important;
}

I tested it in a jsfiddle: http://jsfiddle.net/timlg07/4fdj0hvc/

like image 80
timlg07 Avatar answered Oct 31 '25 04:10

timlg07


I finally figured it out.

Here's an example

I'm using Vue.js so dragging and showDropZone are just variables in data().

html

  <div 
      v-show="showDropZone === true"
      id="drop-zone"
      class="drop-zone"
   >
      Drop zone text
  </div>

JS

  // In the component with the drop zone div:
  document.getElementById('drop-zone').addEventListener('drop', event => {
    event.preventDefault()
    this.showDropZone = false
    var files = event.dataTransfer.files
  })


  // In the entry component:
  window.addEventListener('dragenter', event => { 
      this.dragging++;
      this.showDropZone = true

      event.stopPropagation();
      event.preventDefault();
  });


  window.addEventListener('dragover', event => { 
      this.showDropZone = true

      event.stopPropagation();
      event.preventDefault();
  });


  window.addEventListener('dragleave', event => { 
      this.dragging--;
      if (this.dragging === 0) {
          this.showDropZone = false
      }

      event.stopPropagation();
      event.preventDefault();
  });
like image 33
Un1 Avatar answered Oct 31 '25 04:10

Un1