10

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

clipboard.png

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

  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

clipboard.png


linong
29.2k 声望9.5k 粉丝

Read-Search-Ask