JavaScript Events Handlers — ondragleave and ondragover

John Au-Yeung - Jan 31 '20 - - Dev Community

Subscribe to my email list now at http://jauyeung.net/subscribe/

Follow me on Twitter at https://twitter.com/AuMayeung

Many more articles at https://medium.com/@hohanga

Even more articles at http://thewebdev.info/

In JavaScript, events are actions that happen in an app. They’re triggered by various things like inputs being entered, forms being submitted, and changes in an element like resizing, or errors that happen when an app is running, etc. We can assign an event handler to handle these events. Events that happen to DOM elements can be handled by assigning an event handler to properties of the DOM object for the corresponding events. In this article, we will look at the ondragleave and ondragover event handlers and how to use them.

ondragleave

The ondragleave property of a DOM element let us set the an event handler function to handle the dragleave event. The dragleave event is fired when the dragged element or text selection leave a valid drop target. For example, we can check where the draggable box is moving away from by adding the following HTML code:

<p id='drag-leave-tracker'>
</p>
<div id='drag-box' draggable="true">
</div>
<div id='drop-zones'>
  <div id='drop-zone'>
  </div>
<div id='drop-zone-2'>
  </div>
</div>

The code above is better than passing in dragBox directly into appendChild since it’s much more generic than the original version of the event handler function. We can attach it to any draggable object we want. For example, if we have more than one draggable div element like in the following HTML code:

<div id='drag-box' draggable="true">
</div>
<div id='drag-box-2' draggable="true">
</div>
<div id='drop-zone'>
</div>

And we change the CSS to style both draggable div elements like in the code below:

#drag-box {  
  width: 100px;  
  height: 100px;  
  background-color: red;  
}

#drag-box-2 {  
  width: 100px;  
  height: 100px;  
  background-color: green;  
}

#drop-zone {  
  width: 200px;  
  height: 200px;  
  background-color: purple  
}

Then we can write the following JavaScript code to use one ondragleave event handler function to handle the dropping of both draggable div elements like we have in the code below:

const dragBox = document.getElementById('drag-box');
const dropZone = document.getElementById('drop-zone');
const dropZone2 = document.getElementById('drop-zone-2');
const dragLeaveTracker = document.getElementById('drag-leave-tracker');
const dragEnterHandler = (e) => {
  if (e.toElement.id.includes('drop-zone')) {
    e.toElement.appendChild(document.getElementById('drag-box'));
  }
}
const dragLeaveHandler = (e) => {
  if (e.toElement.id.includes('drop-zone')) {
    dragLeaveTracker.innerHTML = `Leaving ${e.target.id}`;
  }
}
dropZone.ondragenter = dragEnterHandler;
dropZone.ondragleave = dragLeaveHandler;
dropZone2.ondragenter = dragEnterHandler;
dropZone2.ondragleave = dragLeaveHandler;

In the code above, we created a dragLeaveHandler function, which has an e parameter with the DragEvent object to get the DOM element that the draggable element is moving away from. It can also move away from itself since it’s also a valid drop target. We only care about moving away from the 2 drop-zone div elements so we added a check if the ID of the element that it’s moving away from with the e.toElement.id.includes(‘drop-zone’) line. Then we set the innerHTML property of the dragLeaveTracker DOM element to display which one the 2 div elements the drag-box div is moving away from.

Also, we have the dragEnterHandler to handle the actual dropping of the drag-box element into the drop-zone div element by using the appendChild method to append the drag-box inside the drop-zone div .

ondragover

We can assign an event handler to the ondragover property of a DOM element to handle the dragover event, which is triggered when an element or text selection is being dragged over a valid drop target every few hundred milliseconds. For example, we can add the following HTML code to add a p element for displaying the ID of the element that the draggable element is dropped into, a draggable div element and 2 div elements that we can drop the draggable div element into, by writing the following code:

<p id='drag-over-tracker'>
</p>
<div id='drag-box' draggable="true">
</div>
<div id='drop-zones'>
  <div id='drop-zone'>
  </div>
<div id='drop-zone-2'>
  </div>
</div>

Then we style the elements we have in the HTML code by changing the color and the size of each div with the following CSS code:

#drag-box {  
  width: 100px;  
  height: 100px;  
  background-color: red;  
}

#drop-zones {  
  display: flex;  
}

#drop-zone {  
  width: 200px;  
  height: 200px;  
  background-color: purple  
}

#drop-zone-2 {  
  width: 200px;  
  height: 200px;  
  background-color: green;  
}

We put the 2 div elements that we can drop our draggable div into side by side by using the display: flex property and value. Then we can assign our own event handler function to the ondragover property of our 2 div elements where we can drop our draggable div element into by writing the following code:

const dragBox = document.getElementById('drag-box');
const dropZone = document.getElementById('drop-zone');
const dropZone2 = document.getElementById('drop-zone-2');
const dragOverTracker = document.getElementById('drag-over-tracker');
const dragEnterHandler = (e) => {
  if (e.toElement.id.includes('drop-zone')) {
    e.toElement.appendChild(document.getElementById('drag-box'));
  }
}
const dragOverHandler = (e) => {
  console.log(e);
  if (e.toElement.id.includes('drop-zone')) {
    dragOverTracker.innerHTML = `Dragging over  ${e.target.id}, coordinate (${e.clientX}, ${e.clientY})`;
  }
}
dropZone.ondragenter = dragEnterHandler;
dropZone.ondragover = dragOverHandler;
dropZone2.ondragenter = dragEnterHandler;
dropZone2.ondragover = dragOverHandler;

In the code above, we have the dragOverHandler function to handle the dragover event for the drop-zone and drop-zone-2 div elements. When the drag-box div element is dragged over one of the drop-zone div elements, we can see that the console.log statement inside the dragOverHandler function outputs data multiple times if we keep the drag-box div over either of the drop-zone divs . This is because the dragover event is fired every few milliseconds when we drag a draggable element over a valid drop target, which are the 2 drop-zone div elements. As long as we drag it over either of the 2 div elements, we will see new output from the console.log . Also, as we move drag-box inside either of the 2 drop-zone div elements, the coordinate that the drag-box within the screen will also be updated as it’s being moved by the mouse or touchscreen. We will see the ID of the div element that the drag-box is dragged over by getting the value of the e.toElement.id property and we also get the ID the drag-box is dragging over from the e parameter. The e parameter is an DragEvent object, which has properties like the drag coordinates with the clientX and clientY properties and the element being dragged over with the toElement property.

Also, we have the dragEnterHandler to handle the actual dropping of the drag-box element into the drop-zone div element by using the appendChild method to append the drag-box inside the drop-zone div .

The ondragleave property of a DOM element let us set the an event handler function to handle the dragleave event. The dragleave event is fired when the dragged element or text selection leave a valid drop target. It’s handy for getting which drop target element the element being dragged is leaving. We can assign an event handler to the ondragover property of a DOM element to handle the dragover event, which is triggered when an element or text selection is being dragged over a valid drop target every few hundred milliseconds. It’s handy for identifying which element we’re dragging over as well as getting the coordinates on the screen that the element being dragged is in.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .