拖动原始元素HTML5拖放

4
我正在使用本地拖放HTML5 API制作一个拖放界面,与其他部分使用jQuery可拖动不同,它在这个特殊部分表现不佳,因此我们决定使用原生JavaScript。
基本上,标记看起来像这样...
<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>

我为“dragstart”创建了一个addEventListener,并运行了以下函数。
function dragStart (e) {
            var t = this;
            n(t).addClass('rot_15');
            e.dataTransfer.effectAllowed = 'move';
        }

它可以完美地将我的类应用于原始元素,但我似乎无法移动原始元素。浏览器创建一个“克隆/幽灵”图像......我看到你可以使用“setDragImage”创建自己的图像以在拖动时显示,但是如何拖动用户正在拖动的实际元素?


这个有帮助吗? http://www.w3schools.com/html/html5_draganddrop.asp - enhzflep
@enhzflep 看看当你拖动标志时,你没有拖动原始图像...图像被克隆了,然后你拖动克隆。我想拖动原始图像而不仅仅是克隆。 - afreeland
我发现拖放功能无用,改用标准的JavaScript,我认为你走错了方向。使用脚本而不是内置的拖放功能有什么问题吗? - nycynik
2个回答

0

(不是真正的答案,但太长了不能作为评论)

图片被克隆,然后你拖动克隆体。

我不太确定你的意思。我只是复制/粘贴了我链接的页面上的示例 - 没有任何元素被复制或克隆。也许你对appendChild的操作不确定?示例代码只是创建一个div,然后是一个图像。您可以将图像拖放到div上。这会导致img标记现在包含在div中,而不是像加载时那样在其前面。我还要注意一下,因为他们的目标div(div id ='div1')没有内容,所以它没有高度。您应该向div添加一些文本以使其可见。然后,在拖放时观察javascript调试器中的html元素。页面上只有一个图像,它只是在DOM树中重新定位。:)

在这里,复制/粘贴并在调试器中查看。

<!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>

也许“克隆”这个词不太准确……在jQuery可拖动中,您拖动的是实际元素,您可以选择使用助手,但如果您没有设置助手,则移动的是实际元素。而使用本地拖放时,浏览器会显示一个虚影图像,而原始元素保持在原位。我想移动的是可拖动元素,而不是虚影版本。 - afreeland

0

根据回答1中提供的额外信息,我所知道的方法是放弃HTML本地拖放支持,而是自己实现。

我忘记了是什么导致旧浏览器(特别是IE)出现问题,但我有一种感觉,那就是onTgtMouseDown事件变量或clientX/scrollLeft。

无论如何,下面的代码已在当前Chrome和IE9上进行了测试。

希望它适合您的目的(它在视觉上定位对象,但不会改变节点在DOM树中的位置)

<!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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接