关于javascript:HTML5拖放到屏幕上的任意位置

HTML5 Drag and Drop anywhere on the screen

我有一个用JavaScript编写的调试器日志,用于我正在处理的项目。 日志基本上是HTML5中的标记,仅在需要时显示。 我想体验一下能够在屏幕上移动日志的想法,因为它可能与某些内容重叠(这对我的项目很好)。 但是,我似乎无法弄清楚如何使用HTML5正确拖放标签,以便可以将其放置在屏幕上的任何位置(好在元素内)。

在阅读了HTML5的拖放支持之后,我对它的工作原理有了基本的了解,但是我不确定将div放置在任何地方(z索引是一个很高的值,因此它应该从哪里开始)。 如我所说,重叠是可以的)。

有什么建议么?

哦,我想尽量避免在此项目中使用外部库。 我正在尝试使用纯JavaScript / HTML5做到这一点。


拖放操作不会移动元素,如果希望元素在拖放时移动,则必须在drop事件中设置元素的新位置。我已经做了一个可以在Firefox和Chrome浏览器中使用的示例,这是要点:

1
2
3
4
5
function drag_start(event) {
    var style = window.getComputedStyle(event.target, null);
    event.dataTransfer.setData("text/plain",
    (parseInt(style.getPropertyValue("left"),10) - event.clientX) + ',' + (parseInt(style.getPropertyValue("top"),10) - event.clientY));
}

dragstart事件计算出鼠标指针与元素左侧和顶部之间的偏移量,并将其传递到dataTransfer中。我不必担心传递ID,因为页面上只有一个可拖动元素-没有链接或图像-如果页面上有任何东西,那么您将不得不在这里做更多的工作。

1
2
3
4
5
6
7
8
function drop(event) {
    var offset = event.dataTransfer.getData("text/plain").split(',');
    var dm = document.getElementById('dragme');
    dm.style.left = (event.clientX + parseInt(offset[0],10)) + 'px';
    dm.style.top = (event.clientY + parseInt(offset[1],10)) + 'px';
    event.preventDefault();
    return false;
}

drop事件解压缩偏移量,并使用它们将元素相对于鼠标指针定位。

当任何内容被拖动时,dragover事件只需要preventDefault。同样,如果页面上还有其他可拖动的内容,则您可能需要在此处进行更复杂的操作:

1
2
3
4
function drag_over(event) {
    event.preventDefault();
    return false;
}

因此,将其与drop事件一起绑定到document.body以捕获所有内容:

1
2
3
4
var dm = document.getElementById('dragme');
dm.addEventListener('dragstart',drag_start,false);
document.body.addEventListener('dragover',drag_over,false);
document.body.addEventListener('drop',drop,false);

如果要在IE中使用此功能,则需要将aside转换为a元素,当然,所有事件绑定代码都将不同。据我所知,拖放API在Opera或任何移动浏览器中均不起作用。另外,我知道您说过您不想使用jQuery,但是跨浏览器事件绑定和操纵元素位置是jQuery使事情变得更加容易的事情。


对于多个项目,我调整了robertc的好答案。在这里,second类名仅用于另一个位置。

1
2
One</aside>
Two</aside>

将data-item属性添加到setData函数。

1
2
3
4
function drag_start(event) {
  var style = window.getComputedStyle(event.target, null);
  event.dataTransfer.setData("text/plain", (parseInt(style.getPropertyValue("left"), 10) - event.clientX) + ',' + (parseInt(style.getPropertyValue("top"), 10) - event.clientY) + ',' + event.target.getAttribute('data-item'));
}

定位要拖动的元素。

1
2
3
4
5
6
7
8
function drop(event) {
  var offset = event.dataTransfer.getData("text/plain").split(',');
  var dm = document.getElementsByClassName('dragme');
  dm[parseInt(offset[2])].style.left = (event.clientX + parseInt(offset[0], 10)) + 'px';
  dm[parseInt(offset[2])].style.top = (event.clientY + parseInt(offset[1], 10)) + 'px';
  event.preventDefault();
  return false;
}

并使用类dragme遍历所有元素。

1
2
3
4
5
6
var dm = document.getElementsByClassName('dragme');
for (var i = 0; i < dm.length; i++) {
  dm[i].addEventListener('dragstart', drag_start, false);
  document.body.addEventListener('dragover', drag_over, false);
  document.body.addEventListener('drop', drop, false);
}

钢笔


感谢您的回答。它在Chrome和Firefox中效果很好。我将其调整为可在IE中使用。下面是代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
 <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <meta name="generator" content="CoffeeCup HTML Editor (www.coffeecup.com)">
        <meta name="dcterms.created" content="Fri, 27 Jun 2014 21:02:23 GMT">
        <meta name="description" content="">
        <meta name="keywords" content="">
       
       
        <!--[if IE]>
        <script src="http://html5shim.googlecode.com/svn/trunk/html5.js">
        <![endif]-->
    \t<style>
    \tli
    \t{
          position:  absolute;
          left: 0;
          top: 0; /* set these so Chrome doesn't return 'auto' from getComputedStyle */
          width: 200px;
          background: rgba(255,255,255,0.66);
          border: 2px  solid rgba(0,0,0,0.5);
          border-radius: 4px; padding: 8px;
    \t}
    \t</style>
    \t
            function drag_start(event) {
                var style = window.getComputedStyle(event.target, null);
                var str = (parseInt(style.getPropertyValue("left")) - event.clientX) + ',' + (parseInt(style.getPropertyValue("top")) - event.clientY) + ',' + event.target.id;
                event.dataTransfer.setData("Text", str);
            }

            function drop(event) {
                var offset = event.dataTransfer.getData("Text").split(',');
                var dm = document.getElementById(offset[2]);
                dm.style.left = (event.clientX + parseInt(offset[0], 10)) + 'px';
                dm.style.top = (event.clientY + parseInt(offset[1], 10)) + 'px';
                event.preventDefault();
                return false;
            }

            function drag_over(event) {
                event.preventDefault();
                return false;
            }
    \t
      </head>
      <body ondragover="drag_over(event)" ondrop="drop(event)">
       
<ul>

              <li id="txt1" draggable="true" ondragstart="drag_start(event)"> Drag this text
</li>

              <li id="txt2" draggable="true" ondragstart="drag_start(event)"> Drag me
</li>

     
</ul>

      \t   <p>
I never am really satisfied that I understand anything; because, understand it well as I may, my comprehension can only be an infinitesimal fraction of all I want to understand about the many connections and relations which occur to me, how the matter in question was first thought of or arrived at, etc., etc.
</p>
      \t   <p>
In almost every computation a great variety of arrangements for the succession of the processes is possible, and various considerations must influence the selections amongst them for the purposes of a calculating engine. One essential object is to choose that arrangement which shall tend to reduce to a minimum the time necessary for completing the calculation.
</p>
      \t   <p>
Many persons who are not conversant with mathematical studies imagine that because the business of [Babbage’s Analytical Engine] is to give its results in numerical notation, the nature of its processes must consequently be arithmetical and numerical, rather than algebraical and analytical. This is an error. The engine can arrange and combine its numerical quantities exactly as if they were letters or any other general symbols; and in fact it might bring out its results in algebraical notation, were provisions made accordingly.
</p>
      \t   <p>
The Analytical Engine has no pretensions whatever to originate anything. It can do whatever we know how to order it to perform. It can follow analysis, but it has no power of anticipating any analytical revelations or truths. Its province is to assist us in making available what we are already acquainted with.
</p>
   
      </body>
   </html>