image.png

  1. 当 drag元素被拖动时,原来容器中的drag元素并不会消失
    1. 需要手动隐藏
    2. 添加 class=’visible’
  2. 如果同步操作会立马触发 dragend事件导致拖动效果消失,
    1. 所以在 setTimeout的回调中,异步设置可确保拖动操作开始后,再隐藏 drag元素
  3. 在 dragEnter和 dragOver方法中,要通过 e.preventDefault来取消事件
    1. 表示容器是一个合法的 droppable元素,接收拖拽的容器,否则:
    2. 接收容器的drop事件将无法触发,接下来的操作也将无法进行
  4. 在 dragDrop方法中,直接使用append方法将draggable元素移动至当前容器下

drag事件触发顺序

dragover会一直触发
image.png
.visible 为drag拖拽开始后,隐藏拖拽的元素
.dragging为drag拖拽元素正在被拖动的状态,增加黄色border
.drag-over为draggable元素被拖动到容器上方时容器的状态,增加灰色虚线border
image.png

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>html5-drag drop</title>
  8. <style>
  9. body {
  10. background-color: rgba(233, 150, 122, 0.1);
  11. }
  12. /* 拖拽的元素 */
  13. .draggable {
  14. background-image: url('http://via.placeholder.com/150x150');
  15. position: relative;
  16. height: 150px;
  17. width: 150px;
  18. top: 5px;
  19. left: 5px;
  20. cursor: move;
  21. }
  22. /* 接收容器的样式 */
  23. .droppable {
  24. display: inline-block;
  25. height: 160px;
  26. width: 160px;
  27. margin: 10px;
  28. border: 3px salmon solid;
  29. background-color: white;
  30. }
  31. /* 拖拽时的样式 */
  32. .dragging {
  33. border: 4px yellow solid;
  34. cursor: move;
  35. }
  36. /* dragOver 拖拽接收的容器样式 */
  37. .drag-over {
  38. background-color: #f4f4f4;
  39. border-style: dashed;
  40. }
  41. /* dragStart隐藏拖拽的元素 */
  42. .visible {
  43. display: none;
  44. }
  45. </style>
  46. </head>
  47. <body>
  48. <div class="droppable">
  49. <div class="draggable" draggable="true"></div>
  50. </div>
  51. <div class="droppable"></div>
  52. <div class="droppable"></div>
  53. <div class="droppable"></div>
  54. <div class="droppable"></div>
  55. <script>
  56. let timer;
  57. // 查询draggable和droppable
  58. const draggable = document.querySelector('.draggable');
  59. const droppables = document.querySelectorAll('.droppable'); // 接收的容器
  60. // 监听 drag的相关事件
  61. draggable.addEventListener('dragstart', dragStart);
  62. draggable.addEventListener('dragend', dragEnd);
  63. function dragStart(e) {
  64. // 当前拖拽的元素添加拖拽样式
  65. this.className += ' dragging';
  66. timer = setTimeout(() => {
  67. this.className += ' visible';
  68. }, 0);
  69. }
  70. function dragEnd() {
  71. this.className = 'draggable';
  72. clearTimeout(timer);
  73. console.log(timer)
  74. }
  75. // 监听 drop的相关事件
  76. for (const droppable of droppables) {
  77. droppable.addEventListener('dragover', dragOver); //
  78. droppable.addEventListener('dragleave', dragLeave); // 拖拽元素离开容器
  79. droppable.addEventListener('dragenter', dragEnter); // 拖拽元素进入容器范围
  80. droppable.addEventListener('drop', dragDrop); // 释放拖拽
  81. }
  82. // 高频事件,慎用
  83. function dragOver(e) {
  84. e.preventDefault();
  85. console.log('over')
  86. }
  87. // 拖拽进入
  88. function dragEnter(e) {
  89. e.preventDefault();
  90. console.log('enter')
  91. this.className += ' drag-over';
  92. }
  93. // 拖拽离开
  94. function dragLeave(e) {
  95. console.log('leave')
  96. this.className = 'droppable';
  97. }
  98. // 拖拽释放
  99. function dragDrop(e) {
  100. this.className = 'droppable';
  101. this.append(draggable);
  102. console.log('drop')
  103. }
  104. </script>
  105. </body>
  106. </html>