今天简单研究一下拖拽,首先拖拽提供了几个api
container.ondragstart = e =>{}//拖拽开始 后续可以在这和函数里面拿到拖拽对象
container.ondragover = e=>{
e.preventDefault();
} // 拖拽结束 这个他是一直触发的 后续可以在这个函数中取消默认事件让拖拽元素可以放置在指定的元素内
container.ondragenter = e=>{} //拖拽进入 可以监听拖拽到那个元素上
container.ondrop= e=>{ } //可以理解为放手
1. 要想让元素可以触发拖拽首先要给想要拖拽的元素加上 draggable="true"这个属性 否则触发不了拖拽
2.
再比如我们看这张图有很多区域我们怎么确定要将元素放到指定的区域内那?????
这个时候就需要一个标记吧 要拖拽的元素和要拖拽到的区域做一个相同的标记当标记相同时就可以放入否者不执行,可以在元素上定义一个自定义属性 操作dom 通过dataset.xxx拿到属性值进行比较
我这里面设置了一些拖拽样式
//html
<div class="center">
<div class="classdiv" data-drop="move">
<div class="div" data-effect="copy" draggable="true">语文</div>
<div class="div" data-effect="copy" draggable="true">数学</div>
<div class="div" data-effect="copy" draggable="true">英语</div>
</div>
<table border="1px">
<thead>
<tr>
<th>第一节</th>
<th>第二节</th>
<th>第三节</th>
</tr>
</thead>
<tbody>
<tr>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
</tr>
</tbody>
</table>
</div>
SCRIPT
var source //定义一个全局变量用来保存拖拽元素
let container = document.querySelector(".center")
container.ondragstart = e =>{ //拖拽开始 只触发一次
e.dataTransfer.effectAllowed = e.target.dataset.effect //属性指定拖放操作所允许的一个效果
source = e.target //拿到拖拽的元素
console.log("source",source);
console.log("start", e.target);
}
container.ondragover = e=>{ //拖拽结束 一直触发
e.preventDefault(); //取消默认事件 使元素可以放置
// console.log("over", e.target);
}
function getDropNode(node){ //看属性自身是否存在dorp用来设置样式 没有的话就向其父元素
if(node.dataset&&node.dataset.drop){
return node
}else{
node = node.parentNode
}
}
function clearStyleFn(){ //取消样式
document.querySelectorAll(".drop-over").forEach(node =>{
node.classList.remove("drop-over")
})
}
container.ondragenter = e=>{ //拖拽进入 进入触发一次
clearStyleFn()
const dropNode= getDropNode(e.target)
if(!dropNode){
return;
}
console.log("111111",source);
//当拖拽的元素与放置的元素的自定义属性的值相同就可以放上去
// if(source.dataset.effect === e.target.dataset.drop) 不设置拖拽样式可以这样
if(source.dataset.effect === dropNode.dataset.drop){
dropNode.classList.add("drop-over")
console.log("enter ", e.target);
}
}
container.ondrop= e=>{ //拖拽放置结束 进入触发一次 放手
clearStyleFn()
const dropNode = getDropNode(e.target)
if(!dropNode){
return
}
if(source.dataset.effect !==dropNode.dataset.drop){
return
}
if(dropNode.dataset.drop==='copy'){
//复制
const cloneNode = source.cloneNode(true)
cloneNode.dataset.effect = "move"
dropNode.innerHTML = ""
dropNode.appendChild(cloneNode)
}else{
source.remove()
}
}
//style
*{
padding: 0px;
margin: 0px;
}
.center{
height: 200px;
width: 300px;
box-sizing: border-box;
padding: 10px;
display: flex;
border: 1px solid rebeccapurple;
justify-content: space-around;
}
.classdiv{
width: 100px;
height:100px;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
border:1px red solid ;
}
.div{
width: 40px;
text-align: center;
/* margin: 10px 0px; */
border: 1px green solid;
}
.drop-over{
background-color: pink;
}