乐趣区

前端培训中级阶段19-拖拽API20191003期

前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水平,打牢基础知识的中心思想,我们开课啦( 每周四 )。

其实在之前就写过一篇拖拽相关的内容。今天简单说说吧。拖拽想要实现分为两种形式:

  1. 模拟实现
  2. drag API 实现

    1. M 端表现
    2. pc 端表现

模拟实现拖拽

实现方案

  1. 鼠标按下的时候记录按下的 DOM。(如果有需要会进行查询父级)
  2. 鼠标移动时,根据鼠标位置修改 DOM 的位置。(如果要求原位置不变,可以 clone 一个新的)
  3. 鼠标抬起的时候判断父级不同则移入。(如果有需要会进行查询父级,如果是同级的标签可以做排序操作,目前代码中是追加)

测试地址

实现代码

var drapDOM = null;
window.addEventListener('mousedown', function(e){if(e.target.classList.contains('drap')){drapDOM = e.target;}
})
window.addEventListener('mousemove', function(e){if(drapDOM){
        drapDOM.style.position = 'fixed';
        drapDOM.style.pointerEvents =  'none';
        drapDOM.style.left = e.clientX + 'px'
        drapDOM.style.top = e.clientY + 'px'
        console.log(e)
    }
})
window.addEventListener('mouseup', function(e){console.log(e.target)
    if(drapDOM){
        drapDOM.style.position = 'initial';
        drapDOM.style.pointerEvents =  'initial';
        drapDOM.style.left = '0'
        drapDOM.style.top = '0';
        if(drapDOM.parentNode != e.target){e.target.appendChild(drapDOM)
        }
        drapDOM = null
    }
})

注意事项

  1. drapDOM.style.pointerEvents = 'none' 防止副本干扰 e.target
  2. 可以拖拽的 DOM
  3. 可以放置的 DOM

drag API 实现

先说说有什么好处

  1. 可以自动生成副本样式
  2. 动作周期的事件,可以方便的区分出(目标对象与源对象)

    1. ondragstart: 源对象开始被拖动
    2. ondrag: 源对象被拖动的过程中
    3. ondragend: 源对象被拖动结束
    4. ondragenter: 目标对象被源对象拖动进入
    5. ondragover: 目标对象被源对象悬浮在上面
    6. ondragleave: 源对象拖动着离开了目标对象
    7. ondrop: 源对象拖动着在目标对象上方松手
  3. 数据传递:

    1. 源对象数据保存:e.data.Transfer.setData(k,v)//k- v 必须都是 string 类型
    2. 目标对象获取数据:e.data.Transfer.getData(k,v)

实现方案

测试地址

  1. 可拖拽点增加属性(draggable="true"
  2. 可拖拽点增加监听函数 dragstart 记录当前拖拽点
  3. 放置点增加监听函数 dropdragover 阻止默认事件,防止(打开、不能拖拽)
  4. 放置点增加监听函数 drop 判断如果拖拽点不在放置点内(if(!$(ev.target).find(dragged).length){)就追加

实现代码

var dragged;
function allowDrop(ev){// console.log('allowDrop', ev)
    ev.preventDefault();}

function drag(ev){// console.log('drag', ev)
}

function drop(ev){console.log('drop', ev)
    ev.preventDefault();
    if(!$(ev.target).find(dragged).length){$(ev.target).append(dragged)
    }

}

function dragstart(ev){dragged = ev.target;}
$(function(){$('ul').off().on('drop', drop).on('dragover', allowDrop)
    $('li[draggable="true"]').off().on('drag', drag).on('dragstart', dragstart)
})

注意事项

  1. 放置点增加监听函数 dropdragover 阻止默认事件,防止(打开、不能拖拽)
  2. draggable="true" 用来标识这是一个可拖拽点。
  3. M 端 和 PC 端 表现其实还不一样的。比如 M 拖动会触发滚动

其他方案 & 开源框架

  1. jquery-ui
  2. sortable.js

微信公众号:前端 linong

退出移动版