前端培训-中级阶段(19)- 拖拽API(2019-10-03期)


思否
前端培训 HTML5 JavaScript

转载自 SegmentFault

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

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

  • 模拟实现

drag API 实现

M 端表现

  • pc 端表现

模拟实现拖拽

实现方案

  • 鼠标按下的时候记录按下的DOM。(如果有需要会进行查询父级)

  • 鼠标移动时,根据鼠标位置修改DOM的位置。(如果要求原位置不变,可以clone一个新的)

  • 鼠标抬起的时候判断父级不同则移入。(如果有需要会进行查询父级,如果是同级的标签可以做排序操作,目前代码中是追加)

测试地址

实现代码

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

注意事项

drapDOM.style.pointerEvents = 'none' 防止副本干扰e.target

  • 可以拖拽的DOM

  • 可以放置的DOM

drag API 实现

先说说有什么好处

  • 可以自动生成副本样式

动作周期的事件,可以方便的区分出(目标对象与源对象)

ondragstart:源对象开始被拖动

ondrag:源对象被拖动的过程中

ondragend:源对象被拖动结束

ondragenter:目标对象被源对象拖动进入

ondragover:目标对象被源对象悬浮在上面

ondragleave:源对象拖动着离开了目标对象

ondrop:源对象拖动着在目标对象上方松手

数据传递:

源对象数据保存:e.data.Transfer.setData(k,v)//k-v必须都是string类型

  • 目标对象获取数据:e.data.Transfer.getData(k,v)

实现方案

测试地址

  • 可拖拽点增加属性( draggable="true"

  • 可拖拽点增加监听函数 dragstart 记录当前拖拽点

  • 放置点增加监听函数 dropdragover 阻止默认事件,防止(打开、不能拖拽)

  • 放置点增加监听函数 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)
})

注意事项

  • 放置点增加监听函数 dropdragover 阻止默认事件,防止(打开、不能拖拽)

draggable="true" 用来标识这是一个可拖拽点。

  • M端 和 PC端 表现其实还不一样的。比如M拖动会触发滚动

其他方案&开源框架

  • jquery-ui

  • sortable.js

微信公众号:前端linong


原文:SegmentFault

评论

评论功能即将开放。你也可以通过 邮件GitHub Issue 反馈。