draggable in H5

Basic syntax and events

The draggable attribute specifies whether the element is draggable. Must be set, otherwise there will be no drag effect and event triggering

Tip:  Links and images are draggable by default.

Tip:  The draggable attribute is often used in drag and drop operations

grammar 

<element draggable="true|false|auto">
value describe
true Specifies that the element is draggable.
false Specifies that the element is not draggable.
auto Use the browser's default features.

The following events are triggered during the drag and drop process:

Trigger an event on the drag target (source element) and act on the dragged element

  • ondragstart - triggers when dragging an element starts
  • ondrag - Fires when the element is being dragged
  • ondragend - fired after the user has finished dragging the element 
<div id="app">
  <div class="drag" draggable="true"></div>
  <div class="target"></div>
</div>

<script>
  const drag = document.querySelector('.drag')
  const target = document.querySelector('.target')

  drag.addEventListener('dragstart', ondragstart)
  drag.addEventListener('drag', ondrag)
  drag.addEventListener('dragend', ondragend)
  function ondragstart(event) {
    console.log('开始拖动')
  }
  function ondrag(event) {
    console.log('正在拖动')
  }
  function ondragend(event) {
    console.log('完成拖动')
  }
</script>

Acts on target element

  • ondragenter - Triggered when the source element dragged by the mouse enters the scope of its container (triggered when the source element dragged by the mouse enters the scope of the target container) 
  • ondragover - triggered when the dragged source object is dragged within the target container
  • ondragleave - triggered when the dragged object leaves the target container
  • ondrop - triggered when the mouse is released

Event.preventDefault 

To prevent the default event, the preventDefault method must be executed in ondragover, otherwise ondrop will not be triggered.

<div id="app">
  <div class="drag" draggable="true"></div>
  <div class="target"></div>
</div>

<script>
  const drag = document.querySelector('.drag')
  const target = document.querySelector('.target')

  target.addEventListener('dragenter', ondragenter)
  target.addEventListener('dragover', ondragover)
  target.addEventListener('dragleave', ondragleave)
  target.addEventListener('drop', ondrop)
  function ondragenter(event) {
    console.log('进入入其容器范围内触发')
  }
  function ondragover(event) {
    event.preventDefault()
    console.log('容器中拖动时触发')
  }
  function ondragleave(event) {
    console.log('离开目标容器时触发')
  }
  function ondrop(event) {
    console.log('释放鼠标时触发')
  }
</script>

Data Transfer

When performing a drag-and-drop operation, the dataTransfer object can be used to save the dragged data. It can save one or more data, one or most data types. To put it simply, it can be used to transmit the dragged data so that other operations can be performed on the data when the drag is completed.

  • setData(type, data): used to declare the data sent
  • getData(type): used to obtain data of a specified type . Note: it can only be obtained in ondrop.
  • clearData(type): used to clear data of a specified type
<div id="app">
  <div class="drag" draggable="true"></div>
  <div class="target"></div>
</div>

<script>
  const drag = document.querySelector('.drag')
  const target = document.querySelector('.target')

  drag.addEventListener('dragstart', dragstart)
  target.addEventListener('dragover', ondragover)
  target.addEventListener('drop', ondrop)

  function dragstart(event) {
    event.dataTransfer.setData('comp', JSON.stringify({name: 'WFT'}))
  }
  function ondragover(event) {
    event.preventDefault()
  }
  function ondrop(event) {
    let data = JSON.parse(event.dataTransfer.getData('comp'))
    console.log(data)
    // ...
    // 处理完数据 最后清除一下
    event.dataTransfer.clearData()
  }
</script>

In other events (such as ondragover, ondragleaveetc.), the value in dataTransfer cannot be obtained. This is due to W3C's requirement to protect the values ​​in dataTransfer [ Reference ]. Therefore, if you need to obtain data in these events, you can only achieve it through a global variable or other methods.

event.dataTransfer.setDragImage(p_w_picpath, x, y)

The setDragImage method is used to modify the image pointed by the mouse pointer during the drag and drop operation.

Example one: 

Let’s look at the effect first: 

First of all, this is different from dragging an element with the mouse and keeping moving with the mouse. The three core mouse events used are onmousedown, onmousemove, and onmouseup. Ours is dragging, which means it is in a motionless state. 

 

Here is the complete code: 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <div class="drag" draggable="true"></div>
    <div class="target"></div>
  </div>

  <script>
    const drag = document.querySelector('.drag')
    const target = document.querySelector('.target')

    drag.addEventListener('dragstart', dragstart)
    target.addEventListener('dragover', ondragover)
    target.addEventListener('drop', ondrop)

    let curDragDom = null
    let curOffsetX = 0
    let curOffsetY = 0
    
    // 开始拖拽
    function dragstart(event) {
      curDragDom = this
      curOffsetX = event.offsetX
      curOffsetY = event.offsetY
    }
    // 在目标元素中拖拽 移除掉默认事件 否则不会触发 drop事件
    function ondragover(event) {
      event.preventDefault()
    }
    // 在目标容器中松开鼠标
    function ondrop(event) {
      if(!curDragDom) return
      let copyDom = curDragDom.cloneNode(true)
      copyDom.style.position = 'absolute'
      const { x, y } = this.getBoundingClientRect()
      copyDom.style.left = event.clientX - x - curOffsetX + 'px'
      copyDom.style.top = event.clientY - y - curOffsetY + 'px'
      copyDom.removeAttribute('draggable')
      this.appendChild(copyDom)
    }
  </script>

  <style>
    * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }
    #app {
      width: 100vw;
      height: 100vh;
      padding: 50px 0 0 50px;
      box-sizing: border-box;
      display: flex;
    }
    .drag {
      width: 100px;
      height: 100px;
      background-color: red;
    }
    .target {
      width: 400px;
      height: 400px;
      border: 1px solid red;
      margin-left: 200px;
      position: relative;
      overflow: hidden;
    }
  </style>
</body>
</html>

Example two: 

 

Complete code: 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <div class="upload" draggable="true">
      <div>将文件拖到此处进行上传</div>
    </div>
    <div class="images"></div>
  </div>

  <script>
    const upload = document.querySelector('.upload')
    const imageContainer = document.querySelector('.images')

    upload.addEventListener('dragover', ondragover)
    upload.addEventListener('drop', ondrop)

    function ondragover(event) {
      event.preventDefault()
    }

    function ondrop(event) {
      event.preventDefault()
      const { files } = event.dataTransfer
      Array.from(files).forEach(blob => {
        const url = window.URL.createObjectURL(new Blob([blob]))
        const img = document.createElement('img')
        img.src = url
        imageContainer.appendChild(img)
      })
    }
  </script>

  <style>
    * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }
    #app {
      width: 100vw;
      height: 100vh;
      padding: 50px 0 0 50px;
      box-sizing: border-box;
    }
    .upload {
      width: 360px;
      height: 180px;
      border: 1px dashed #c0c4cc;
      border-radius: 5px;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .upload > div {
      color: #606266;
      font-size: 14px;
    }
    .images {
      width: 100%;
      display: flex;
      flex-wrap: wrap;
      margin-top: 10px;
    }
    .images img {
      width: 300px;
      height: 180px;
      margin-right: 20px;
    }
  </style>
</body>
</html>

Guess you like

Origin blog.csdn.net/m0_51431448/article/details/132130403