H5中的draggable

基本语法及事件

draggable 属性规定元素是否可拖动。必须设置,否则没有拖拽效果及事件触发

提示: 链接和图像默认是可拖动的。

提示: draggable 属性经常用于拖放操作

语法 

<element draggable="true|false|auto">
描述
true 规定元素是可拖动的。
false 规定元素是不可拖动的。
auto 使用浏览器的默认特性。

在拖放过程中会触发以下事件:

在拖动目标上触发事件(源元素),作用于被拖拽元素上

  • ondragstart - 开始拖动元素触发
  • ondrag - 元素正在拖动时触发
  • ondragend - 用户完成元素拖动后触发 
<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>

作用于目标元素

  • ondragenter - 进入其容器范围内触发(当被鼠标拖动的源元素进入目标容器范围内时触发) 
  • ondragover - 被拖动的源对象在目标容器中拖动时触发
  • ondragleave - 拖动的对象离开目标容器时触发
  • ondrop - 释放鼠标时触发

Event.preventDefault 

阻止默认事件,在ondragover中一定要执行preventDefault方法,否则ondrop不会被触发

<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>

DataTransfer

在进行拖放操作的时候,dataTransfer对象可以用来保存被拖动的数据。它可以保存一项或多项数据、一种或多数数据类型。通谷一点讲,就是可以通过它来传输被拖动的数据,以便在拖拽结束的时候,对数据进行其他的操作。

  • setData(type, data): 用于声明所发送的数据
  • getData(type):用于获取指定type的数据 注意:只能在ondrop中获取的到
  • clearData(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>

在其它的事件(如ondragoverondragleave等),是无法获取dataTransfer里面的值了。这是由于W3C要求对dataTransfer里的值进行保护[参考]。因此,如果需要在这些事件里获取数据,只能通过一个全局变量等其它方式来实现了。

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

setDragImage方法用于在拖放操作过程中,修改鼠标指针所指向的图像

示例一: 

先看效果: 

先说一下,这种和鼠标去拖拽某个元素跟着鼠标移动一直移动不一样的,那种核心用到三个鼠标事件是 onmousedown、onmousemove、onmouseup。咱们这种是拖拽、就是本身是不动的状态 

 

下面是完整代码: 

<!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>

示例二: 

 

完整代码: 

<!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>

猜你喜欢

转载自blog.csdn.net/m0_51431448/article/details/132130403