js实现一个小小的拖拽功能

50 阅读1分钟

css
    .container{
        display: flex;
        
    }
    .container .table{
        margin-left: 50px;
        border: 1px solid #f5f5f5;
    }
    .dropBGC{
        background-color: blue;
    }
    
    
 html
     <h1>课程表</h1>
    <div class="container">
        <div data-drop="move">
            <div data-effect="copy" draggable="true">语文</div>
            <div data-effect="copy" draggable="true">数学</div>
            <div data-effect="copy" draggable="true">英语</div>
            <div data-effect="copy" draggable="true">音乐</div>
            <div data-effect="copy" draggable="true">政治</div>
        </div>
        <div>
            <table border="1">
                <colgroup>
                    <col/>
                    <col/>
                    <col/>
                    <col/>
                </colgroup>
                <thead>
                    <tr>
                        <td></td>
                        <th>星期一</th>
                        <th>星期二</th>
                        <th>星期三</th>
                        <th>星期四</th>
                        <th>星期五</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <th >上午</th>
                        <td data-drop="copy"></td>
                        <td data-drop="copy"></td>
                        <td data-drop="copy"></td>
                        <td data-drop="copy"></td>
                        <td data-drop="copy"></td>
                    </tr>
                    <tr>
                        <th>下午</th>
                        <td data-drop="copy"></td>
                        <td data-drop="copy"></td>
                        <td data-drop="copy"></td>
                        <td data-drop="copy"></td>
                        <td data-drop="copy"></td>
                    </tr>
                </tbody>

            </table>
        </div>
    </div>
    
js:

const container = document.querySelector('.container')
// 拖拽的哪个元素
// source全局变量用来获取当前拖拽的元素
let source
//此时的e.target就是拖拽的当前元素
container.ondragstart = (e) =>{
    // 鼠标添加样式,有两个参数copy以及move
    e.dataTransfer.effectAllowed = e.target.dataset.effect  
    source= e.target
}
// 放到了哪个位置
container.ondragover = e=>{
    // 因为ondrop事件不会响应所以需要取消它本身带的这个事件也就是下面这段代码
    e.preventDefault()
}
//背景颜色修改函数
function clearDropStyle(){
    //获取所有的dropBGC,然后删除
    const dropNodes = document.querySelectorAll('.dropBGC')
    dropNodes.forEach(node=>{
        node.classList.remove('dropBGC')
    })
}
//检查节点自定义属性
function getDropNode(node){
    while(node){
        if(!node.dataset.drop){
            return node = node.parentNode
        }
        return node

    }
}
// 放到了哪个位置只执行一次
container.ondragenter = e=>{
    //先去除样式
    clearDropStyle()
    //判断节点的自定义属性
    const dropNode = getDropNode(e.target)
    if(!dropNode){
        return
    }
    // 拖到那里,哪里背景颜色进行修改
    if(e.dataTransfer.effectAllowed === dropNode.dataset.drop){
        dropNode.classList.add('dropBGC')
    }
}
// 清空子节点
function removeAllChild(node){
    while(node.hasChildNodes())
    {
        node.removeChild(node.firstChild);
    }
}
// 鼠标放开之后的位置
container.ondrop = e=>{
    clearDropStyle()
    const dropNode = getDropNode(e.target)
    if(!dropNode){
        return
    }
    if(e.dataTransfer.effectAllowed !== dropNode.dataset.drop){
        return;
    }
    if(dropNode.dataset.drop === 'copy'){
        removeAllChild(dropNode)
        dropNode.innerHtml=''
        // cloneNode深拷贝此节点source
        const cloned = source.cloneNode(true)
        cloned.dataset.effect='move'
        dropNode.appendChild(cloned)
    }else{
        dropNode.innerHtml=''
        source.remove()
    }
}