h5中drag的使用以及相关介绍:实现点餐效果

相关的API

image
主要有7个api,分别用来描述不同的状态

前提准备

主要实现的点餐功能如下:

  • 一个盘子里装了多种菜
  • 另一个是小明的菜单
  • 小明可以拖动菜品到菜单上
  • 小明的菜单中最多可以点三份菜

思考一下我们如何实现这个功能:首先需要两个容器,一个用来装菜品,另一个当作菜单
小明的点菜操作我们可以使用drag相关的api,拖动到菜单上则给菜单添加一个子元素

相关介绍

下面我们把拖拽的物体称为源对象,放置到位置称为目标对象

dragstart

源对象 开始被拖动时触发的函数,事件对象是源对象,比如我们在这个时候可以给源对象添加一些样式,比如边框高亮,字体加粗等效果,触发一次之后就结束

drag

源对象 在被拖动的时候触发的函数,事件对象是源对象 ,相隔几十毫秒就会触发一次

dragend

源对象被拖拉结束时(释放鼠标键或按下 ESC 键)触发,事件对象是源对象。它与dragstart事件,在同一个节点上触发。不管拖拉是否跨窗口,或者中途被取消,dragend事件总是会触发的


dragenter

源对象进入目标对象时,在目标上触发一次,该事件的target属性是目标对象。通常应该在这个事件的监听函数中,指定是否允许在当前节点放下(drop)拖拉的数据。如果当前节点没有该事件的监听函数,或者监听函数不执行任何操作,就意味着不允许在当前节点放下数据。一般我们可以在源对象刚进入目标对象时监听这个事件,我们可以给目标对象添加高亮效果等

dragover

源对象拖拉到目标对象上方时,在当前节点上持续触发(大概相差几十毫秒),e.target也就是事件对象是目标对象,这个方法类似于drag,都会一直触发。

dragleave

拖拉操作离开目标对象范围时触发,该事件的target属性是目标对象。比如说在点菜时,已经拖到这个框里了,但是又不想点了,又继续滑出去,此时就应该将目标对象之前的样式去掉。

drop

源对象释放到目标对象时,在目标节点上触发。注意,如果目标对象不允许drop,即使在上方松开鼠标键,也不会触发该事件。如果用户按下 ESC 键,取消这个操作,也不会触发该事件。该事件的监听函数负责取出拖拉数据,并进行相关处理。比如我们在点菜时,拖动菜品到盘子里并松手时就说明我们确定点这个菜品,此时就应该复制该节点到盘子里。

注意事项

dragenter和dragover事件的监听函数,用来取出拖拉的数据(即允许放下被拖拉的元素)。由于网页的大部分区域不适合作为放下拖拉元素的目标节点,所以这两个事件的默认设置为当前节点不允许接受被拖拉的元素。如果想要在目标节点上放下的数据,首先必须阻止这两个事件的默认行为

<div ondragover="return false">
<div ondragover="event.preventDefault()">

参考代码

还是存在着很多小bug,不过基础功能已经可以实现了
image

点击查看代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    li {
      list-style: none;
      border: 1px solid #ccc;
    }

    .box {
      width: 800px;
      height: 680px;
      margin: 0 auto;
      background-color: rgb(235, 230, 230);
    }

    .dragBox {
      display: flex;
      width: 100%;
      height: 60%;
      flex-wrap: wrap;
      justify-content: space-around;
      align-items: space-between;

    }

    .dragDiv {
      width: 100px;
      height: 100px;
      border-radius: 100px;
      line-height: 100px;
      text-align: center;
      border: 1px solid rgb(80, 77, 77);
      background-color: #7d7a7a;
    }

    .dragCss {
      border: 1px solid blue;
      opacity: 0.5;
    }

    .dropDiv {
      display: flex;
      justify-content: space-around;
      align-items: center;
      width: 80%;
      height: 30%;
      margin: 0 auto;
      border: 1px solid #000;
      background-color: burlywood;
    }

    .dropCss {
      background-color: yellow;
    }
  </style>
</head>

<body>
  <div class="box">
    <h2 style="text-align:center">点餐系统</h2>
    <ul class="dragBox">

    </ul>
    <h2 style="text-align:center">盘子</h2>
    <div class="dropDiv"></div>
  </div>
</body>
<script>
  const foodList = ['火锅', '北京烤鸭', '兰州拉面', '成都冷串串', '重庆酸辣粉', '武汉热干面', '西安肉夹馍', '长沙口味虾', '广东肠粉', '小笼包', '桂林米粉', '柳州螺蛳粉', '天津煎饼果子', '山东煎饼', '东北锅包肉', '福建佛跳墙', '河南烩面', '山西刀削面', '南昌瓦罐汤', '河北驴肉火烧', '手抓饼']
  const dropNode = document.querySelector('.dropDiv')
  const ul = document.querySelector('.dragBox')
  let fragment = document.createDocumentFragment()
  foodList.forEach(item => {
    let li = document.createElement('li')
    li.innerText = item
    li.classList.add('dragDiv')
    li.draggable = 'true'
    fragment.appendChild(li)
  })
  ul.appendChild(fragment)
  // 1.准备工作,先将foodList渲染到ul中
  const dragNodes = document.querySelectorAll('.dragDiv')
  let dragNode = null
  dragNodes.forEach(node => {
    node.addEventListener('dragstart', function (e) {
      console.log('开始拖拉')
      dragNode = e.target
      e.target.classList.add('dragCss')
    })
    node.addEventListener('dragend', function (e) {
      e.target.classList.remove('dragCss')
    })
  })



  dropNode.addEventListener('dragenter', function (e) {
    dragNode.classList.remove('dragCss')
    e.target.classList.add('dropCss')
  })

  dropNode.addEventListener('dragover', function (e) {
    e.preventDefault()
  })
  dropNode.addEventListener('dragleave', function (e) {
    e.target.classList.remove('dropCss')
  })

  dropNode.addEventListener('drop', function (e) {

    if (e.target.children.length > 3) {
      e.target.classList.remove('dropCss')
      alert('最多只能点四个菜哦~')
      return
    }
    let newNode = dragNode.cloneNode(true)
    e.target.classList.remove('dropCss')
    e.target.appendChild(newNode)

  })
</script>

</html>
// 本人才疏学浅 如有错误 请指出 谢谢!

参考

dragable

posted @ 2022-11-13 17:49  含若飞  阅读(129)  评论(0编辑  收藏  举报