拖拽API学习

130 阅读2分钟

一、拖拽事件

1、拖拽元素
  • drag:拖拽事件,当元素正在被被拖拽时触发
  • dragstart:拖拽开始事件,拖拽元素开始拖拽时触发
  • dragend:拖拽结束事件
2、目标元素
  • dragenter:拖拽元素进入目标元素事件
  • dragover:拖拽元素在目标元素中事件
  • dragleave:拖拽元素离开目标元素事件
  • drop:拖拽元素或文本放置在目标元素区域时触发
3、事件顺序

drapstart->dragenter->dragover->dragleave->dragend

4、拖拽事件对象

dataTransfe

   ①dropEffect:拖放的操作类型,决定浏览器如何显示鼠标形状,取值为:copy、move、link、none
       注意:只能在dragover事件这种设置该属性,当显示禁止的指针样式时,将无法触发目标元素的drop事件
   ②effectAllowed:指定允许的操作,取值为:move、link、copy、copylink、copymove、linkmove、allnone
       注意:只能在dragstart事件中设置该属性

二、拖拽案例

image.png 如上图实现拖拽排序功能:

1、准备好需要排序的元素,并给他们添加draggable属性,值为true

<head>
...
    <style>
            .container {
                padding: 0;
                margin: 100px 0 0 100px;
            }
            .item {
                width: 300px;
                height: 30px;
                margin-bottom: 3px;
                line-height: 30px;
                size: 20px;
                padding-left: 10px;
                border-radius: 3px;
                background-color: rgb(3, 85, 3);
                /* border: 1px dashed 3px white; */
            }
            .moving {
                border: 1px dashed rgb(215, 214, 214);
                background-color: transparent;
            }
        </style>
    </head>
    <body>
        <div class="container">
            <div draggable="true" class="item hh" data-self="888">1</div>
            <div draggable="true" class="item">2</div>
            <div draggable="true" class="item">3</div>
            <div draggable="true" class="item">4</div>
            <div draggable="true" class="item">5</div>
            <div draggable="true" class="item">6</div>
        </div>
    </body>

2、监听开始拖拽事件:dragstart

 var dragItems = document.querySelector(".container");
 var dragItem;
 dragItems.addEventListener("dragstart", (e) => {
    //拖拽开始设置原来位置元素样式
    dragItem = e.target;
    //直接设置,会导致原位置和跟随鼠标拖动元素的样式都发生改变,setTime在拖拽之后,再改变原位置的样式
    setTimeout(() => {
        dragItem.classList.add("moving");
    }, 0);
    //e.dataTransfer.setData('text','hello Roper')
    //console.log(e.dataTransfer.getData('text'));
    e.dataTransfer.effectAllowed = 'move'
 })

3、监听拖拽结束事件:dragenter ①特殊情况处理 排除自身和父元素 ②获取拖拽元素和目标元素的order,利用insertbefore实现元素的拖拽

     dragItems.ondragenter = (e) => {
        e.preventDefault();
        //特殊情况处理:1、拖拽到父元素 2、拖拽到自身
        if (e.target === dragItems || dragItem === e.target) {
            return;
        }
        var childrens = [...dragItems.children];
        //拖拽元素下标
        var sourcesIndex = childrens.indexOf(dragItem);
        //目标元素下标
        var targetIndex = childrens.indexOf(e.target);

        if (sourcesIndex > targetIndex) {
            dragItems.insertBefore(dragItem, e.target);
        } else {
            dragItems.insertBefore(
                dragItem,
                e.target.nextElementSibling,
            );
        }
        // console.log(e.target);
    };

4、问题处理

①去掉原拖拽元素的样式

    dragItems.ondragend = function (e) {
        dragItem.classList.remove("moving");
    };

②拖动元素会自动回到原来位置:浏览器默认不允许元素拖动到自身,需要去dragenter和dragover中阻止默认事件

    dragItems.ondragenter = (e) => {
                e.preventDefault();
    }
     dragItems.ondragover =  (e) =>{
            e.preventDefault();
    };

③鼠标样式设置(effectAllowed只能在dragstart中设置)

    dragItems.addEventListener("dragstart", (e) => {
        e.dataTransfer.effectAllowed = 'move'
    });