美文网首页
HTML5原生拖动效果实现

HTML5原生拖动效果实现

作者: xiaoguo16 | 来源:发表于2019-05-16 19:05 被阅读0次

    HTML5实现了原生拖动的接口,因此在实现拖拽功能时,可以直接使用该方法。下面用一个例子学习其用法。

    案例背景:

    实现ol列表的拖拽可排序功能。

    实现过程:

    1. 拟实现一个类似于下面的ol列表。该列表需要有可拖拽调整顺序的功能。给标签加入draggable属性,标签即赋予拖拽功能。li标签在JS中用数据动态写入,方便拖拽时对数据进行操作,从而控制列表顺序。
      <ol>
        <!-- <li draggable="true"  order=0>apple</li>
        <li draggable="true" order=0>pear</li>
        <li draggable="true" order=0>peach</li>-->
      </ol>
    

    li相应的css代码如下

      li{
        border-bottom:1px solid #ccc;
        width:100px;
        margin-bottom:5px;
      }
    
    1. JS动态写入标签
      JS中加入以下方法生成li标签,给每个li标签加入draggable属性使其可拖拽,以及order属性标记索引值。
        let data = ['苹果', '香蕉', '梨','草莓']
        initDom=(data)=>{
          let ol = document.getElementsByTagName('ol')[0]
          ol.innerHTML=""
          data.map((item,index)=>{
            let newElement = document.createElement('li')
            newElement.setAttribute('draggable', true)
            newElement.setAttribute('order', index)
            let textNode = document.createTextNode(item)
            newElement.appendChild(textNode)
            ol.appendChild(newElement)
          })
        }
        initDom(data)
    
    1. 拖动事件处理:
      拖动事件主要由以下几个事件组成:
    • dragstart: 开始拖拽的时候触发的事件,作用于被拖拽的元素。
    • dragenter: 拖拽元素进入目标元素时触发,作用于目标元素。
    • dragover:拖拽元素在目标元素上方移动时触发,作用于目标元素。
    • dragleave: 拖拽元素离开目标元素时触发,作用于目标元素。
    • drop: 鼠标放开拖拽元素时触发在目标元素上的事件。
    • dragend: 拖拽结束后,作用于被拖拽元素上的事件。

    上述例子中,利用事件冒泡在外层ol标签上加入拖拽事件,不用加在每个li标签上。

    dragstart:

    在开始拖拽时,希望被拖拽元素加入透明度的样式以进行标记。dataTransfer可以在拖拽过程中传递数据。此处将索引值传递过去,方便最后进行重排序。

          let ol = document.getElementsByTagName('ol')[0];
          ol.ondragstart=(event)=>{
            event.target.style.opacity = 0.4;
            const dragIndex = event.target.attributes.order.nodeValue
            event.dataTransfer.setData("text/dragIndex",dragIndex);
          }
    
    dragover:

    在拖动过程中,如果在目标元素上方移动时,给目标元素加一个样式进行标记。

    ol.ondragover = (event)=>{
         //默认拒绝接受任何被拖放的元素,取消默认
         event.preventDefault();
         if(event.target.nodeName.toLowerCase()==='li'){
             event.target.style.borderBottom = '1px solid red'
          }
    }
    
    dragleave:

    当被拖动元素离开目标元素时,需要恢复目标元素的样式。

    ol.ondragleave = (event)=>{
        if(event.target.nodeName.toLowerCase()==='li'){
           event.target.style.borderBottom = '1px solid #ccc'
        }
     }
    
    dragend:

    当拖动结束时,恢复被拖拽元素的样式。

    ol.ondragend = (event)=>{
       event.target.style.opacity = 1;
    }
    
    dragdrop:

    放下拖拽元素时,需要处理数据逻辑,以更改DOM结构,交换元素。

          ol.ondrop = (event)=>{
            //浏览器默认元素会阻止drop,所以取消默认
            event.preventDefault();
            if(event.target.nodeName.toLowerCase()==='li'){
              const dropIndex = Number(event.target.attributes.order.nodeValue)
              const dragIndex = Number(event.dataTransfer.getData("text/dragIndex"))
              const dragData = data[dragIndex]
              const dropData = data[dropIndex]
              data.splice(dropIndex, 1, dragData)
              data.splice(dragIndex, 1, dropData)
              initDom(data)
            }
          }
    

    注意点:

    1. dragoverdrop事件需要加入event.preventDefault(),否则该事件会不起作用。
    2. 拖拽过程中数据的传递可通过event.dataTransfer.setData("数据类型名称",数据)event.dataTransfer.getData("数据类型名称")实现。
    3. 拖拽结束时的数据交换逻辑需要写在drop中而不是dragenddragend作用的元素是被拖拽的元素。

    相关文章

      网友评论

          本文标题:HTML5原生拖动效果实现

          本文链接:https://www.haomeiwen.com/subject/asqiiqtx.html