• 拖拽实现备忘:拖拽drag&拖放drop事件浅析


    1、相关重点

      DataTransfer 对象:拖拽对象用来传递的媒介,使用一般为Event.dataTransfer。

      draggable 属性:就是标签元素要设置draggable=true,否则不会有效果,例如:

    <div title="拖拽我" draggable="true">列表1</div>

      ondragstart 事件:当拖拽元素开始被拖拽的时候触发的事件,此事件作用在被拖曳元素上

      ondragenter 事件:当拖曳元素进入目标元素的时候触发的事件,此事件作用在目标元素上。建议绑定于可拖放区域,该事件仅在进入拖放区域时触发,在其内部移动时不触发,离开某一可拖放区域后再进入时会再次触发

      ondragover 事件:拖拽元素在目标元素上移动的时候触发的事件,此事件作用在目标元素上

      ondrop 事件:被拖拽的元素在目标元素上同时鼠标放开触发的事件,此事件作用在目标元素上

      ondragend 事件:当拖拽完成后触发的事件,此事件作用在被拖曳元素上

      Event.preventDefault() 方法:阻止默认的一些事件方法等执行。在ondragover中一定要执行preventDefault(),否则ondrop事件不会被触发。另外,如果是从其他应用软件或是文件中拖东西进来,尤其是图片的时候,默认的动作是显示这个图片或是相关信息,并不是真的执行drop。此时需要用document的ondragover事件把它直接干掉。

      Event.effectAllowed 属性:就是拖拽的效果。

    2、ondrop

      拖放事件,绑定于可拖放区域上。之所以把这个方法单独拎出来,是因为在使用该方法时存在一些注意事项。当我们这样使用时:

    <div class="drop-field" @drop="drop"></div>
    
    methods: {
        drop (event) {
            console.log('drop', event)
        }
    }

      发现当我们将可拖拽元素拖放至此时,并没有触发事件。根据 MDN 的文档:

    A listener for the dragenter and dragover events are used to indicate valid drop targets, that is, places where dragged items may be dropped. Most areas of a web page or application are not valid places to drop data. Thus, the default handling for these events is to not allow a drop.", hence the only way for the drop event to be fired is to first cancel the dragenter or dragover event.

      我们必须阻止某一 DOM 元素对 dragover 的默认行为,才能使 drop 事件在其上正确执行:

    <div class="drop-field"
    @drop="drop"
    @dragover="dragover">
    </div>
    
    methods: {
        drop (event) {
            console.log('drop', event)
        },
        dragover (event) {
            event.preventDefault()
        }
    }

      在 Vue 中,我们可以将组织默认行为的过程简写如下:@dragover="dragover" 改为: @dragover.prevent

    3、DragEvent传递参数消息

      注意,无论是 dragxxx 或 drop 事件,其传递的参数都是 DragEvent。

      让我很费解的是,对于在拖放区绑定的 drop 事件而言,其 DragEvent 中竟然无法找到被拖拽元素。这也就意味着,不借助额外变量,drop 事件是无法知道被拖放者是什么的。但我们仍可以借助 DragEvent 中的 DataTransfer 来进行被拖放对象的消息传递。流程如下:

      (1)在被拖拽对象的 dropstart 事件中传递消息

    dragstart (event) {
        console.log('dragstart', event)
        event.dataTransfer.setData('my-info', 'hello')
        event.dataTransfer.setData('my-extra-info', 'world')
    }

      (2)在拖放区的 drop 事件中获取消息

    drop (event) {
        console.log('drop', event)
        console.log(event.dataTransfer.getData('my-info'))
        console.log(event.dataTransfer.getData('my-extra-info'))
    }

      (3)在被拖拽对象的 dragend 事件中清除消息

    dragend (event) {
        console.log('dragend', event);
        event.dataTransfer.clearData()
    }

      注意:

      (1)不能在被拖拽对象的 dragend 事件中传递消息

      在整个拖拽过程中,事件的先后顺序为:拖拽对象的 dropstart -- 拖放区的 drop -- 拖拽对象的 dropend

      因而,如果在 dragend 中传递消息,是不能被 drop 捕获的。

      (2)不能在被拖拽对象的 dragover 事件中传递消息

      如果我们在被拖拽对象的 dragover 事件中传递消息,由于 dragover 事件的作用对象是「可拖放区」,即此时,该 dragover 中的 DragEvent 是以「可拖放区」身份施加的,故而不会传递到 drop 中。

      (3)消息只能是 String 类型

      dataTransfer 中设置的消息( 即 setData 的第二个参数 )只能是字符串类型。如果想要传递对象,需要先进行序列化。

      (4)Vue 中事件参数

      在上面的代码中,如果我们在 @dragstart 中想传递一些参数,如下:@dragstart="dragstart(item)",就会遇到一个问题:默认传递的 DragEvent 参数丢失了。此时,我们需要使用 Vue 的特殊变量来实现事件参数的传递:

    @dragstart="dragstart($event, item)"
  • 相关阅读:
    3.8快乐
    只剩一个人了
    需求分析
    再也不看皇马比赛
    最近蛮忙,没头绪
    ↗☻【响应式Web设计 HTML5和CSS3实战 #BOOK#】第5章 CSS3:选择器、字体和颜色模式
    ↗☻【高性能网站建设进阶指南 #BOOK#】第12章 尽早刷新文档的输出
    ↗☻【响应式Web设计 HTML5和CSS3实战 #BOOK#】第4章 响应设计中的HTML5
    ↗☻【JavaScript】code
    ↗☻【高性能网站建设进阶指南 #BOOK#】第11章 划分主域
  • 原文地址:https://www.cnblogs.com/goloving/p/12852451.html
Copyright © 2020-2023  润新知