When dragging and entering the <div class="upload-cont">
the color changes perfectly from gray to black of border and text and when it comes to the <span class="add-text">
it changes back to gray.
CSS:
.upload-cont{
cursor:pointer;
margin-left:130px;
display:inline-block;
border:2px dashed #a8a8a8;
max-width:220px;
max-height:180px;
min-width:220px;
min-height:180px;
position:relative;
border-radius:3px;
}
.add-text{
display:block;
font-size:10px;
font-weight:bold;
color:#999;
word-wrap:break-word;
text-align:center;
width:100px;
top:37%;
left:25%;
position:absolute;
}
.add-text:hover{ color:black; }
HTML:
<div class="upload-cont">
<span class="add-text">
Click to add or<br/>
Drag and drop image here
</span>
</div>
Jquery:
$(document).ready(function () {
$(".upload-cont,.add-text").on('dragenter', function (e) {
$(".upload-cont").css({
"border": "2px dashed black"
});
$(".add-text").css({
"color": "black"
});
});
$(".upload-cont").on('dragleave', function (e) {
$(".upload-cont").css("border", "2px dashed #a8a8a8");
$(".add-text").css({
"color": "#a8a8a8"
});
});
});
What can i do to remain the black color for the border and text when entering <span class="add-text">
Check this jsfiddle: http://jsfiddle.net/rpABs/
Thanks in advance
Use dragover
instead of dragenter
since dragleave
fires when you enter child elements
$(".upload-cont,.add-text").on('dragover', function (e) {
$(".upload-cont").css({
"border": "2px dashed black"
});
$(".add-text").css({
"color": "black"
});
});
$(".upload-cont").on('dragleave', function (e) {
$(".upload-cont").css("border", "2px dashed #a8a8a8");
$(".add-text").css({
"color": "#a8a8a8"
});
});
DEMO
Apparently this problem is more recurrent than I thought since I found at least 5 questions associated with the same topic (and I will answer all related with this issue).
Unlike "mouseover", the events "dragover" and "dragleave" do not consider the child elements as a whole, so each time the mouse passes over any of the children, "dragleave" will be triggered.
Thinking about the upload of files, I created a widget that allows:
The problem: As everything, both form inputs and images, are within DIVs children, "dragleave" was triggered even if it did not leave the dashed line. Using the attribute "pointer-events: none" is not an alternative since methods 3 and 4 need to trigger "onchange" events.
The solution? An overlapping DIV that covers all the drop-container when the mouse enters, and the only one with child elements with "pointer-events: none".
The structure:
Then, when the mouse enters by dragging an element to #drop-area, inmediatly shows #drop-pupup ahead and successively the events are on this div and not the initial receiver.
Here is the JS/jQuery code. I took the liberty to leave the PoC so do not lose all the time I lost.
jQuery(document).on('dragover', '#drop-area', function(event) {
event.preventDefault();
event.stopPropagation();
jQuery('#drop-popup').css('display','block');
});
jQuery(document).on('dragover dragleave drop', '#drop-popup', function(event) {
event.preventDefault();
event.stopPropagation();
console.log(event.type);
// layout and drop events
if ( event.type == 'dragover') {
jQuery('#drop-popup').css('display','block');
}
else {
jQuery('#drop-popup').css('display','none');
if ( event.type == 'drop' ) {
// do what you want to do
// for files: use event.originalEvent.dataTransfer.files
// for web dragged elements: use event.originalEvent.dataTransfer.getData('Text') and CURL to capture
}
}
});
body {
background: #ffffff;
margin: 0px;
font-family: sans-serif;
}
#drop-container {
margin: 100px 10%; /* for online testing purposes only */
width: 80%; /* for jsfiddle purposes only */
display: block;
float: left;
overflow: hidden;
box-sizing: content-box;
position: relative; /* needed to use absolute on #drop-popup */
border-radius: 5px;
text-align: center;
cursor: default;
border: 2px dashed #000000;
}
#drop-area {
display: block;
float: left;
padding: 10px;
width: 100%;
}
#drop-popup {
display: none;
box-sizing: content-box;
position: absolute;
width: 100%;
top: 0;
left: 0;
background: linear-gradient(to BOTTOM, rgba(245, 245, 245, 1) , rgba(245, 245, 245, 0));
height: 512px;
padding: 20px;
z-index: 20;
}
#drop-popup > p {
pointer-events: none;
}
<html>
<head>
<title>Drag and Drop</title>
</head>
<body>
<div id="drop-container">
<div id="drop-area">
<p>Child paragraph content inside drop area saying "drop a file or an image in the dashed area"</p>
<div>This is a child div No. 1</div>
<div>This is a child div No. 2</div>
</div>
<div id="drop-popup">
<p>This DIV will cover all childs on main DIV dropover event and current P tag is the only one with CSS "pointer-events: none;"</p>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" type="text/javascript"></script>
</body>
<html>
About jQuery "on", use it with the div id inside on, so you can start event triggers starting "uploading box" hidden.
Finally, I preferred to use "dragover" over "dragenter" because it has a small delay (milliseconds) that favors performance (https://developer.mozilla.org/en-US/docs/Web/API/Document/dragover_event).
The dragover
event fires constantly as you're dragging, so I'm not a fan of that solution. I've written a little library called Dragster that gives me better enter
& leave
events.
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