基于Web API drap事件的简单拖拽功能
- 效果示例图
- 代码示例
效果示例图
代码示例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
* {
padding: 0px;
margin: 0px;
box-sizing: border-box;
}
ul,
ol,
li {
list-style: none;
}
.drag-wrap {
width: 600px;
margin: 20px auto;
}
.drag-header {
border: 1px solid #dcdcdc;
border-radius: 4px;
width: 100%;
display: flex;
flex-wrap: wrap;
}
.drag-tab {
border: 1px solid #00a2ef;
border-radius: 4px;
padding: 6px 12px;
font-size: 16px;
color: #00a2ef;
margin: 6px 6px;
cursor: move;
}
.drag-tab:hover {
border: 1px solid #00a2ef;
background-color: #00a2ef;
color: #fff;
}
.drag-content {
border: 1px solid #dcdcdc;
width: 100%;
margin-top: 60px;
}
.drag-title {
border-bottom: 1px solid #00a2ef;
width: 100%;
display: flex;
flex-direction: row;
}
.drag-th {
border-right: 1px solid #dcdcdc;
flex: 1;
padding: 6px 6px;
}
.drag-th:last-child {
border-right: 0px;
}
.drag-tr {
border-bottom: 1px solid #00a2ef;
width: 100%;
display: flex;
flex-direction: row;
}
.drag-tr:hover {
background-color: #eee;
}
.drag-tr:last-child {
border-bottom: 0px;
}
.drag-item-td {
border-right: 1px solid #dcdcdc;
flex: 1;
padding: 12px 6px;
}
.drag-tr>.drag-item-td:last-child {
border-right: 0px;
}
.drag-item-td-operate {
display: flex;
flex-wrap: wrap;
}
.move-enter {
background-color: #dcdcdc;
}
.operate-btn {
border: 1px solid #00a2ef;
border-radius: 4px;
padding: 6px 12px;
font-size: 16px;
color: #00a2ef;
margin: 6px 6px;
cursor: move;
text-align: center;
}
</style>
</head>
<body>
<div class="drag-wrap">
<!-- header -->
<div class="drag-header">
<div class="drag-tab" draggable="true" data-id="1" data-effect="copy">毛利兰</div>
<div class="drag-tab" draggable="true" data-id="2" data-effect="copy">毛利小五郎</div>
<div class="drag-tab" draggable="true" data-id="3" data-effect="copy">英妃理</div>
<div class="drag-tab" draggable="true" data-id="4" data-effect="copy">工藤新一</div>
<div class="drag-tab" draggable="true" data-id="5" data-effect="copy">工藤优作</div>
<div class="drag-tab" draggable="true" data-id="6" data-effect="copy">毛利博士</div>
<div class="drag-tab" draggable="true" data-id="7" data-effect="copy">小岛元太</div>
<div class="drag-tab" draggable="true" data-id="8" data-effect="copy">黑羽快斗</div>
<div class="drag-tab" draggable="true" data-id="9" data-effect="copy">黑羽盗一</div>
<div class="drag-tab" draggable="true" data-id="10" data-effect="copy">中森青子</div>
</div>
<!-- content -->
<ul class="drag-content">
<li class="drag-title">
<div class="drag-th">ID</div>
<div class="drag-th">状态</div>
<div class="drag-th">性别</div>
<div class="drag-th">操作</div>
</li>
<li class="drag-tr">
<div class="drag-item-td">001</div>
<div class="drag-item-td">上学中</div>
<div class="drag-item-td">男</div>
<div class="drag-item-td drag-operate" data-id="001" data-drop="copy"></div>
</li>
<li class="drag-tr">
<div class="drag-item-td">002</div>
<div class="drag-item-td">上学中</div>
<div class="drag-item-td">男</div>
<div class="drag-item-td drag-operate" data-id="002" data-drop="copy"></div>
</li>
<li class="drag-tr">
<div class="drag-item-td">003</div>
<div class="drag-item-td">上学中</div>
<div class="drag-item-td">女</div>
<div class="drag-item-td drag-operate" data-id="003" data-drop="copy"></div>
</li>
<li class="drag-tr">
<div class="drag-item-td">004</div>
<div class="drag-item-td">研发中</div>
<div class="drag-item-td">男</div>
<div class="drag-item-td drag-operate" data-id="004" data-drop="copy"></div>
</li>
</ul>
</div>
</body>
<script type="text/javascript">
const dragContainer = document.querySelector(".drag-wrap");
//暂存原始节点
let sourceNode = null;
//是否离开
let dragLeave = false;
dragContainer.addEventListener("dragstart", (e) => {
console.log("[dragstart]", e.target)
//DataTransfer.effectAllowed 属性指定拖放操作所允许的一个效果
e.dataTransfer.effectAllowed = e.target.dataset.effect;
sourceNode = e.target;
})
/**
* 拖拽的元素悬浮在元素上,触发事件
* **/
dragContainer.addEventListener("dragover", (e) => {
e.preventDefault()
})
/**
* 判断当前节点或者它的父节点是否设置了data-drop="copy"
* **/
function judgeDropNode(node) {
while (node) {
// 先判断当前节点是否包含data-drop="copy"
if (node.dataset && node.dataset.drop === 'copy') {
return node;
}
//在判断它的父节点是否存在data-drop="copy"
node = node.parentNode
}
}
/**
* 拖拽的元素进入某个元素触发事件
* **/
dragContainer.addEventListener("dragenter", (e) => {
console.log("[dragenter]", e.target)
clearStyle();
const dropNode = judgeDropNode(e.target);
console.log("[node]", dropNode)
if (dropNode && (dropNode.dataset.drop === e.dataTransfer.effectAllowed)) {
dropNode.classList.add("move-enter");
}
})
/**
* 拖拽的元素放手了之后触发的事件
* **/
dragContainer.addEventListener("drop", (e) => {
console.log("[drop]", e.target)
const dropNode = judgeDropNode(e.target);
console.log("[node]", dropNode)
if (dropNode && (dropNode.dataset.drop === e.dataTransfer.effectAllowed)) {
if (dropNode.dataset.drop === 'copy') {
const btn = document.createElement("div");
btn.classList.add("operate-btn");
btn.innerText = sourceNode.innerText;
btn.dataset.id = sourceNode.dataset.id;
dropNode.appendChild(btn);
eventHandle(sourceNode.dataset.id, dropNode.dataset.id);
}
}
})
/**
* 拖拽离开
* **/
dragContainer.addEventListener("dragleave", (e) => {
console.log("[dragleave]", e.target)
})
/**
* 拖拽结束
* **/
dragContainer.addEventListener("dragend", (e) => {
console.log("[dragend]", e.target)
clearStyle();
})
//清除原来添加的样式
function clearStyle() {
document.querySelectorAll(".drag-operate").forEach(item => {
item.classList.remove("move-enter");
});
}
function eventHandle(id, parentID) {
console.log("[]", id, parentID)
}
</script>
</html>
drap API