拖动原始元素 HTML5 拖放
Posted
技术标签:
【中文标题】拖动原始元素 HTML5 拖放【英文标题】:Drag original element HTML5 drag and drop 【发布时间】:2012-09-17 10:51:29 【问题描述】:我正在使用原生拖放 html5 api 开发拖放界面。我们已经将 jQuery draggable 用于其他部分,但它对于这个特定部分的性能很差,所以我们使用原始 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”进行拖动时显示,但是如何拖动用户正在拖动的实际元素?
【问题讨论】:
这有帮助吗? w3schools.com/html/html5_draganddrop.asp @enhzflep 看看当您拖动徽标时,您不会拖动原始徽标...图像被克隆,然后您拖动克隆。我想拖动原始图像而不仅仅是克隆。 我发现拖放没用,而是使用标准的javascript,我认为你走错了路。使用脚本而不是内置免打扰有什么问题? 【参考方案1】:(不是真正的答案,但评论太长了)
.图像被克隆,然后你拖动克隆。
不太清楚你的意思。我只是在我链接的页面上复制/粘贴了示例 - 没有任何事情发生。没有任何元素的复制或克隆。也许您不确定 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)" >
-->
<h1 id='drag1' draggable='true' ondragstart='drag(event)'>Drag me</h1>
</body>
</html>
【讨论】:
也许克隆是一个不正确的术语....在 jQuery draggable 中,您可以拖动实际可拖动的元素..如果需要,您可以有一个助手,但如果您没有设置助手,您可以移动实际元素。通过本机拖放,浏览器会显示一个幻影图像,而原始元素保持在同一位置。我想移动可拖动元素而不是幻影版本。【参考方案2】:根据回答 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>
【讨论】:
以上是关于拖动原始元素 HTML5 拖放的主要内容,如果未能解决你的问题,请参考以下文章
使用 HTML5 拖放,有没有办法在保持拖动流的同时隐藏元素
HTML5 使用 Hammer.js 拖动事件在 div 上拖放元素
使用 HTML5 拖放防止拖动事件干扰 Firefox 中的输入元素