简体   繁体   中英

HTML5 drag and drop with only javascript

All,

I'm trying to use event delegation, drag and drop and only javascript.

After I double click on item 1 from sourceContainer....the item then gets created in the destinationContainer. No problem here.

However, when I try to drag the new item in the destinationContainer I can't set the top and left styles for the selected div. Either the event.target.id or the this.id is always the same. I expect the id to be 1 which is the newly created id for the div that exists in destinationContainer.

Can anyone help me understand how I might be able to change the top and left style for only the div that was created in destinationContainer.

Here is a fiddle: https://jsfiddle.net/mdevera/oys3tLww/1/

Here is the drop function:

function drop(event) {

console.log("event.target.id: " + event.target.id);
console.log("this.id: " + this.id);

// This does not allow me to set the selected div's appropriate top and left styles.
// I do not want the whole destinationContainer to not move.  Just the selected child element.

// var offset = event.dataTransfer.getData("text/plain").split(',');
//
// this.style.top = (event.clientY + parseInt(offset[0], 10)) + 'px';
// this.style.left = (event.clientX + parseInt(offset[1], 10)) + 'px';

}

/*Drag and Drop events*/
var source;
var before;
function isbefore(a, b) {
    if (a.parentNode == b.parentNode) {
        for (var cur = a; cur; cur = cur.previousSibling) {
            if (cur === b) {
                return true;
            }
        }
    }
    return false;
}

function dragenter(e) {
    before =isbefore(source, e.target);
    if (before) {
        e.target.parentNode.insertBefore(source, e.target);
    } else {
        e.target.parentNode.insertBefore(source, e.target.nextSibling);
    }
}
function dragstart(e) {
    source = e.target;
    e.dataTransfer.effectAllowed = 'move';
    e.dataTransfer.setData("Text", source.getAttribute('id'));
    return true;
}
function dragDrop(e) {
    var source = e.dataTransfer.getData("Text");
    if (!before) {
        ev.target.appendChild(document.getElementById(src));
    }
    ev.stopPropagation();
return false;
}
<body>

<div class="dropdown">

    <button class="btn btn-primary dropdown-toggle"
            type="button" id="dropdownMenu1"
            data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
        Border-style
        <span class="caret"></span>
    </button>

    <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
        <li><a href="#" id="border-solid" onClick="return_id(this.id)">Solid</a></li>
        <li><a href="#" id="border-dashed" onClick="return_id(this.id)">Dashed</a></li>
        <li><a href="#" id="border-dotted" onClick="return_id(this.id)">dotted</a></li>
    </ul>
</div>


<center><input type="text" id="text1" onClick="ele_id(event)"/></center>
<center><input type="text" id="text2" onClick="ele_id(event)"/></center>

<center><input type="text" id="text5" onClick="ele_id(event)"/></center>

Purely in Javascript. Main Point is to play with mouseup,mousedown and mousemove events to simulate drag and drop. Play with offset to get desired offset from mouse cursor of drag object.

Run code snippet in full page for better view. Scrolling is enemy of drag and drop

 var elements=document.getElementsByClassName("item"); var dest=document.getElementById("dest"); var drag=false; var tempObj=null; //active object to drag //add events to item class for(obj of elements) { obj.addEventListener('mousedown',function dragInitiate() { drag=true; tempObj=this; }); } document.addEventListener('mouseup',function dragInitiate(e) { drag=false; if(tempObj!=null) { if(itemInsideDestination(tempObj,e)==true) { tempObj.innerHTML="Success!!!"; dest.appendChild(tempObj); tempObj.style.position="relative"; tempObj.style.left="0px"; tempObj.style.top="0px"; }else { tempObj.style.left="0px"; tempObj.style.top="0px"; } } }); document.addEventListener('mousemove',function dragStop(e) { if(drag==true && tempObj!=null) { //play with offset to get accurate position of item with mouse cursor var offset=100; tempObj.style.left=(e.clientX)+"px"; tempObj.style.top=(e.clientY-offset)+"px"; if(itemInsideDestination(tempObj,e)==true) { tempObj.innerHTML="I am inside Destination"; }else { tempObj.innerHTML="Do not Drop me!!!"; } } }); function itemInsideDestination(obj,e) { var mx=e.clientX,my=e.clientY; var itemRect=obj.getBoundingClientRect(); var destRect=dest.getBoundingClientRect(); if((itemRect.left+itemRect.width)>=destRect.left && (itemRect.left+itemRect.width)<=destRect.left+destRect.width) { if((itemRect.top)>=destRect.top && (itemRect.top)<=destRect.top+destRect.height) { //console.log('box inside'); return true; } } } 
 #source { border:1px solid gray; height:200px; width:200px; } #dest { border:1px solid gray; height:200px; width:400px; } .item { background-color:lightblue; width:200px; height:30px; position:relative; border:1px solid gray; cursor:move; } .inDest { background-color:lightblue; width:200px; height:30px; position:relative; border:1px solid gray; left:0px; top:0px; } .item:active { border:1px solid blue; } 
 <p>Source</p> <div id="source"> <div class="item">Item1</div> <div class="item">Item2</div> <div class="item">Item3</div> <div class="item">Item4</div> </div> <p>Destination</p> <div id="dest"> </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM