前端最基础的就是 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
记录当前拖拽点 - 放置点增加监听函数
drop
、dragover
阻止默认事件,防止(打开、不能拖拽) - 放置点增加监听函数
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)
})
注意事项
- 放置点增加监听函数
drop
、dragover
阻止默认事件,防止(打开、不能拖拽) -
draggable="true"
用来标识这是一个可拖拽点。 - M 端 和 PC 端 表现其实还不一样的。比如 M 拖动会触发滚动
其他方案 & 开源框架
- jquery-ui
- sortable.js
微信公众号:前端 linong