Why isn't the drop event firing on this web page?
Even though it spends online tutorials understanding native HTML5 drag'n'drop, I can't figure out why the "drop" event is not firing for my base html page.
There is a fiddle here - https://jsfiddle.net/carlv/0yeuce3u/
The code looks like this. Html:
<div id="wrapper">
<div id="fixedWidth">
<div id="modulesBlock">
<div id="mod1" class="module" draggable="true" ></div>
<div id="mod2" class="module" draggable="true" ></div>
<div id="mod3" class="module" draggable="true" ></div>
<div id="mod4" class="module" draggable="true" ></div>
<div id="mod5" class="module" draggable="true" ></div>
<div id="mod6" class="module" draggable="true" ></div>
<div id="mod7" class="module" draggable="true" ></div>
<div id="mod8" class="module" draggable="true"></div>
<div id="mod9" class="module" draggable="true" ></div>
<div id="mod10" class="module" draggable="true"></div>
</div>
</div>
<div id="theRest">
<div id="contentBlock">
<div class="target" id="target1" ></div>
<div class="target" id="target2" ></div>
</div>
</div>
</div>
and javascript for event handling:
function moduleDragStart(ev) {
console.log(ev.target.id);
ev.dataTransfer.setData("text", ev.target.id);
}
function handleDrop(e) {
e.preventDefault();
console.log('drop onto --'+e.target.id);
}
function handleDragEnter(e) {
console.log('target dragenter ='+e.target.id);
e.preventDefault();
this.classList.add('over');
}
function handleDragEnd(e) {
[].forEach.call(cols, function (col) {
col.classList.remove('over');
});
}
function handleDragLeave(e) {
this.classList.remove('over');
}
var cols = document.querySelectorAll('.target');
[].forEach.call(cols, function(col) {
col.addEventListener('dragenter', handleDragEnter, false);
col.addEventListener('dragleave', handleDragLeave, false);
col.addEventListener('dragend', handleDragEnd, false);
col.addEventListener('drop', handleDrop, false);
});
var mods = document.querySelectorAll('.module');
[].forEach.call(mods, function(mod){
mod.addEventListener('dragstart',moduleDragStart,false);
});
When I try to drag the module block (red in the fiddle) onto the target block (white in the fiddle) while I see the dragger and dralbauer firing, for some reason the drop event does not fire the drop event listener on the target element. Any ideas?
source to share
You have not defined an event dragover
. If you do this, everything will be fine. Just use the same function as for dragenter
, or define a simple one:
function handleDragOver(e) {
e.preventDefault();
}
....
col.addEventListener('dragover', handleDragEnter, false);
Once you do this, it will stop. You can see how it works here (or on this JSFiddle ):
function moduleDragStart(ev) {
console.log(ev.target.id);
ev.dataTransfer.setData("text", ev.target.id);
}
function handleDrop(e) {
// this / e.target is current target element.
e.preventDefault();
console.log('--'+e.target.id);
}
function handleDragEnter(e) {
// this / e.target is the current hover target.
e.preventDefault();
this.classList.add('over');
}
function handleDragEnd(e) {
// this/e.target is the source node.
[].forEach.call(cols, function (col) {
col.classList.remove('over');
});
}
function handleDragLeave(e) {
this.classList.remove('over'); // this / e.target is previous target element.
}
// NEW FUNCTION!
function handleDragOver(e) {
e.preventDefault();
}
var cols = document.querySelectorAll('.target');
[].forEach.call(cols, function(col) {
col.addEventListener('dragenter', handleDragEnter, false);
col.addEventListener('dragleave', handleDragLeave, false);
col.addEventListener('dragover', handleDragOver, false);
col.addEventListener('drop', handleDrop, false);
});
var mods = document.querySelectorAll('.module');
[].forEach.call(mods, function(mod){
mod.addEventListener('dragstart',moduleDragStart,false);
// moved the dragend here, as it applied to mod and not to col
mod.addEventListener('dragend', handleDragEnd, false);
});
html,body { height: 100%; margin: 0px; padding: 0px; }
.module {
height:50px;
width:50px;
background:red;
float:left;
margin:10px;
}
.target { float:left;height:100px; width:100px; background:white;margin:20px;border:1px solid;}
.target.over {
border: 2px dashed #000;
}
#contentBlock {
width:100%;
height:100%;
}
#fixedWidth{
width: 300px;
float: left;
background: blue;
height:100%;
}
#theRest{
background: green;
min-width:1000px;
width:100%;
height:100%;
}
#wrapper {
overflow:scroll;
height:100%;
width:100%;
float:left;
}
#contentHeader {
width:100%;
height:75px;
background: orange;
padding: 10px;
}
#logoBlock {
height:75px;
background: yellow;
padding: 10px;
}
#userBlock {
height:75px;
background: white;
padding: 10px;
}
#modulesBlock {
background: yellow;
padding: 10px;
}
<div id="wrapper">
<div id="fixedWidth">
<div id="logoBlock">logoblock</div>
<div id="userBlock">logoblock</div>
<div id="modulesBlock">
<p>modulesBlock</p>
<div id="mod1" class="module" draggable="true" ></div>
<div id="mod2" class="module" draggable="true" ></div>
<div id="mod3" class="module" draggable="true" ></div>
<div id="mod4" class="module" draggable="true" ></div>
<div id="mod5" class="module" draggable="true" ></div>
<div id="mod6" class="module" draggable="true" ></div>
<div id="mod7" class="module" draggable="true" ></div>
<div id="mod8" class="module" draggable="true"></div>
<div id="mod9" class="module" draggable="true" ></div>
<div id="mod10" class="module" draggable="true"></div>
</div>
</div>
<div id="theRest">
<div id="contentHeader">content header</div>
<div id="contentBlock">
<div class="target" id="target1" ></div>
<div class="target" id="target2" ></div>
</div>
</div>
</div>
source to share