4
votes

I am working on a drag and drop interface using native drag and drop html5 api. We have used jQuery draggable for other pieces but it is performing poorly for this particular piece, so we are going with raw JavaScript.

Essentially the markup looks like this...

<li draggable="true">
  <div class="esia_img esia_amex"></div>
  <span class="esia_imgTitle flo">AmEx</span>
</li>
<li draggable="true">
  <div class="esia_img esia_visamc"></div>
  <span class="esia_imgTitle flo">VisaMC</span>
</li>

I create an addEventListener for 'dragstart' and run the following function

function dragStart (e) {
            var t = this;
            n(t).addClass('rot_15');
            e.dataTransfer.effectAllowed = 'move';
        }

It will apply my class perfectly to the original element but I can not seem to move the original element. Browsers create a 'clone/ghost' image...I seen where you can create your own image to show while dragging using 'setDragImage' but how can I drag the actual element the user is dragging?

2
@enhzflep see how when you drag the logo you don't drag the original...the image gets cloned and you drag the clone. I want to drag the original image not just a clone.afreeland
I found that the drag and drop was useless, and used standard javascript instead, i think your going the wrong way. What was wrong with using the script instead of built in DND?nycynik

2 Answers

0
votes

(Not really an answer, but too long for a comment)

.the image gets cloned and you drag the clone.

Not quite sure what you mean by this. I just copy/pasted the example on the page I linked - nothing of the sort happens. There's no duplication or cloning of any elements. Perhaps you're uncertain of the action of appendChild? The example code simply creates a div, followed by an image. You can drag'n'drop the image onto the div. This causes the img tag to now be contained within the div, rather than repreceding it, as is the case when it's loaded. I'll also note, since their target div (div id='div1') has no content, it has no height. You should add some text to the div to make it visible. Then, watch the html elements in your javascript debugger as you drag n drop. There's only ever 1 image on the page, it simply gets repositioned in the DOM tree. :)

Here, copy/paste and watch this in the debugger.

<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">
function allowDrop(ev)
{
ev.preventDefault();
}

function drag(ev)
{
ev.dataTransfer.setData("Text",ev.target.id);
}

function drop(ev)
{
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body>

<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
    id='Div1' - Drop Target
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)">
    id='Div2' - Drop Target
</div>

<!--
<img id="drag1" src="img/logo.gif" draggable="true"
ondragstart="drag(event)" width="336" height="69">
-->
<h1 id='drag1' draggable='true' ondragstart='drag(event)'>Drag me</h1>

</body>
</html>
0
votes

Following the extra information provided in the comment to answer 1, the way (that I know of) to approach this is to discard html native drag-drop support, instead implementing it yourself.

I forget what it is that causes problems with older browsers (particularly IE), though I've a feeling it's either the event var of onTgtMouseDown or the clientX/scrollLeft.

In any case, below code is tested with current Chrome and IE9.

Hope it's suitable for your purposes (It positions the object visually, but doesn't alter a node's position within the DOM tree)

<!DOCTYPE html>
<html>
<head>

<style>
#tgt
{
    position: absolute;
    border: solid 1px red;
    text-align: center;
    display: inline-block;
}
</style>

<script>
function byId(e){return document.getElementById(e);}
function myInit()
{
    var dragMe = byId('tgt');
    dragMe.ondragstart = function() { return false; }
    dragMe.onmousedown = onTgtMouseDown;
}



function onTgtMouseDown(e)
{
    var mDlg, self=this;
    var initMx, intMy, initDlgX, initDlgY, dx, dy;
    var mTgt;

    mTgt = this;


//  mDlg = this.parentNode;
//  mDlg.zIndex = 1000;
//  mDlg.style.position = 'absolute';
    mTgt.zIndex = 1000;
    mTgt.style.position = 'absolute';

    e = e || event;
    initMx = e.pageX;
    initMy = e.pageY;
    initDlgX = mTgt.offsetLeft;
    initDlgY = mTgt.offsetTop;
    // offset from top left of element to mouse when button pressed
    dx = initMx  - initDlgX;
    dy = initMy - initDlgY;

    document.onmousemove = function(e)
    {
        e = e || event;
        fixPageXY(e);
        mTgt.style.left = e.pageX-dx+'px';
        mTgt.style.top = e.pageY-dy+'px';
    }
    this.onmouseup = function()
    {
        document.onmousemove = null;
    }
}


// e = event
function fixPageXY(e) 
{
  if (e.pageX == null && e.clientX != null ) 
  {
    var html = document.documentElement
    var body = document.body
    e.pageX = e.clientX + (html.scrollLeft || body && body.scrollLeft || 0)
    e.pageX -= html.clientLeft || 0
    e.pageY = e.clientY + (html.scrollTop || body && body.scrollTop || 0)
    e.pageY -= html.clientTop || 0
  }
}

</script>

</head>
  <body onload='myInit();'>
    <div id='tgt'>Drag Me</div>
  </body>
</html>