2

前端拖拽组件实践

 2 years ago
source link: https://iiong.com/front-end-dnd-practice-notes/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

前端拖拽组件实践

淮城一只猫 • 2022年03月07日 • 编程技术 • 阅读量 0 次 • 评论量 0 个

这几年做的可视化项目越来越多,这需要前端的 dragdrop 元素能力(下文简称 dnd),dnd 能力极大提高前端交互能力。然而在开发项目期间很少去了解其运行原理,这段时间趁着空余时间算是系统学习下前端 dnd 事件能力吧。

上面讲述到的 dragdrop 是前端元素上的事件,除了监听这俩个事件之外,还需要对元素进行拖拽支持:

<style>
  .drag {
    position: relative;
    width: 100px;
    height: 100px;
    color: #fff;
    text-align: center;
    line-height: 100px;
    background: #ccc;
    user-select: none;
    cursor: grab;
  }
  .drop {
    position: absolute;
    top: 0;
    left: 200px;
    width: 400px;
    height: 400px;
    background: #eee;
  }
</style>

<div class="app-wrapper">
  <div class="drag-wrapper">
    <div draggable="true" id="dragger" class="drag">
      拖动元素
    </div>
  </div>
  <div class="drop-wrapper">
    <div class="drop">
      放置区域
    </div>
  </div>
</div>
markup

只需要在需要拖拽的元素上添加 draggable 属性,该属性的值是布尔值:

  • true 表示元素可以被拖动
  • false 表示元素不可以被拖动

简单的拖拽例子就这样出来了,但还是远远不够,需要监听对应的事件来满足某些需求。

dnd 事件主要分为拖拽和放置俩大事件类型。

拖拽事件如下:

  • dragstart 开始拖拽元素返回回调事件
  • drag 拖拽期间一定频率返回回调事件
  • dragend 拖拽结束返回回调事件

放置事件如下:

  • dragenter 当拖拽元素拖到可放置元素时候返回回调事件
  • dragover 当拖拽元素拖到可放置元素期间一定频率返回回调事件
  • dragleave 当拖拽元素离开可放置元素时候返回回调事件
  • drop 当拖拽元素在放置元素放置返回回调事件

上面列出都会有 DragEvent 回调事件,回调事件中有个 dataTransfer 属性,关于他的介绍如下:

DataTransfer 对象用于保存拖动并放下(drag and drop)过程中的数据。它可以保存一项或多项数据,这些数据项可以是一种或者多种数据类型。

这个属性主要包含:

  • dropEffect
  • effectAllowed
  • files 包含数据传输中可用的所有本地文件的列表。
  • items(只读)
  • types(只读)

dropEffect 属性拖放操作的视觉效果:

  • none
  • copy
  • link
  • move

effectAllowed 用来指定当元素被拖放式所允许的视觉效果:

  • none
  • move
  • copy
  • link
  • copyMove
  • copyLink
  • linkMove
  • all
element.addEventListener('dragenter', event => {
  event.dataTrasfer.dropEffect = 'move'
})
javascript

下面的例子可以利用 dataTransfer 属性将拖拽的元素在放置元素上起到放置效果作用:

<style>
  body {
    background-color: #F1C40F;
    font-family: "Courier New";
  }

  .container {
    display: grid;
    grid-template-columns: 33% 33% 33%;
  }

  .draggable, .droptarget {
    border: 20px solid white;
    margin: 30px;
    padding: 30px;
    text-align: center;
    color: white;
    font-size: 2rem;
  }

  .one {
    background-color: #f15e0f;
  }
  .two {
    background-color: #a532f1;
  }
  .three {
    background-color: #2274a5;
  }

  .droptarget {
    border: 10px dashed white;
    transition: border-width 0.5s linear;
  }

  .hover {
    border-width: 20px;
  }

</style>
<div class="container">
  <div class="draggable one" draggable="true">
    drag me
  </div>
  <div class="draggable two" draggable="true">
    drag me
  </div>
  <div class="draggable three" draggable="true">
    drag me
  </div>
  <div class="droptarget">drop here</div>
  <div class="droptarget">drop here</div>
  <div class="droptarget">drop here</div>
</div>
markup
document.querySelectorAll('.draggable').forEach(item => {
  item.addEventListener('dragstart', event => {
    event.dataTransfer.setData('text/plain', getComputedStyle(item).backgroundColor)
  })
})

document.querySelectorAll('.droptarget').forEach(item => {
  item.addEventListener('dragover', event => {
    event.preventDefault()
  })
  item.addEventListener('dragleave', event => {
    item.classList.remove('hover')
  })
  item.addEventListener('dragenter', event => {
    item.classList.add('hover')
  })

  item.addEventListener('drop', event => {
    item.style.backgroundColor = event.dataTransfer.getData('text/plain')
  })
})
javascript

利用 setData 方法设置对拖拽元素写入特定的信息,然后在放置元素读取信息来展示不同的效果。

静下心来过一下其实这些东西也没那么复杂,看完之后对那些 dnd 轮子项目也差不多了解其中的架构吧。

参考资料:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK