zoukankan      html  css  js  c++  java
  • html5鼠标拖动排序及resize实现方案分析及实践

    对列表进行拖动排序,尺寸改变。之前一般会使用jQuery-UI。其通过mousedown、mousemove、mouseup这三个事件来实现页面元素被鼠标拖拽的效果。vue-drag-resize vuedraggable等包也大抵如此:https://codepen.io/lujun-zhou/pen/LYybXNx

    而HTML5中直接提供了拖放的API,只要通过监听元素的拖放事件就能实现各种拖放功能。

    拖放(Drag和 drop)是 HTML5 标准的组成部分。相比之前用jquery-UI等库实现,更加方便(省去计坐标计算等)。

    为了使元素可拖动,必须把 draggable 属性设置为 true 

    <div id=test draggable=true>test</div>[object Object]

    整个拖拽事件触发的顺序如下:dragstart-> drag -> dragenter -> dragover -> dragleave -> drop ->dragend

    拖放事件事件详情

    一个元素被拖放,他可能会经过很多个元素上,最终到达想要放置的元素内。这里,我暂时把被拖放的元素称为源对象,被经过的元素称为过程对象,到达的元素称为目标对象。不同的对象产生不同的拖放事件。

    源对象事件:

        dragstart:源对象开始拖放,开始移动时事件触发

        drag:源对象拖放过程中,移动被拖拽对象时触发

        dragend:源对象拖放结束,整个拖放操作结束时触发。

    过程对象事件:

        dragenter:源对象进入过程对象范围内,被拖拽对象进入过程对象时被触发

        dragover:源对象在过程对象范围内移动,被拖拽对象在过程对象内移动时触发

        dragleave:源对象离开过程对象的范围,被拖拽对象离开目标对象时触发

    目标对象事件:

        drop:源对象拖放到目标对象中,目标对象完全接受被拖拽对象时触发,可理解为在目标对象内松手时触发。

    dragenter和dragover事件的默认行为是拒绝接受任何被拖放的元素。因此,我们必须阻止浏览器这种默认行为。e.preventDefault();

    如果drop接收盒子要想接收到元素,那么接收的拖动元素 dragenter和dragover必须阻止默认行为。

    el.ondragover = function(e){
       e.preventDefault();
    }
    el.ondrop = function(e){
     e.preventDefault();
    }

    在vue项目中:

    @dragstart.native="dragStart(index,$event)"
    @dragenter.native.prevent="dragenter(index,$event)"
    @dragleave.native.prevent
    @dragover.native.prevent
    @dragend.native="dragend(index,$event)"
    @drop.native.prevent="drop(index,$event)"

    这样才会触发drop

    dataTransfer对象

    在所有的拖放事件中都提供了一个数据传输对象dataTransfer,主要是用于在源对象和目标对象之间传递数据

    dataTransfer方法

    setData(format, data)

    设置拖拽事件中要传递的数据,format的参数为数据类型,data要存入的数据。例如:event.dataTransfer.setData('text/plain', 'hello world')

    存入的数据类型,共有4种:

      • text/plain

      • text/html

      • text/xml

      • text/uri-list

    注:如果给定类型的数据不存在,则将其添加到拖动数据存储的末尾,使得dataTransfer.types列表中的最后一个项目将是新类型。

    getData(format)

    该方法从dataTransfer对象中读取数据,参数为在setData方法中指定的数据类型,例如:event.dataTransfer.getData('text/plain')

    clearData()

    该方法清空dataTransfer对象中存储的数据,参数可选,为数据类型。若为空,则清空所有数据。

    setDragImage(element,x,y)

    • 该方法通过img元素来设置拖放图标

    • element表示拖拽时鼠标下面的图片(通常是image元素,也可以说canvas元素)

    • x、y分别指示相对于图片的横向和纵向偏移量,相对应鼠标指针。

    dataTransfer属性

    dropEffect 和 effectAllowed属性

    给指定拖放操作所允许的一个效果,例如:dataTransfer.effectAllowed = "move"。

    1. effectAllowed  用来指定当元素被拖放式所允许的视觉效果。如果effectAllowed属性是定为none,则不允许拖放元素

    2. dropEffect   表示拖放操作的视觉效果,如果dropEffect 属性设定为none,则不允许被拖放到目标元素中。

    应该在dragstart事件中设置此属性,以便为拖动源设置所需的拖动效果。在 dragenter 和dragover 事件处理程序中,该属性将设置为在dragstart 事件期间分配的任何值,因此,可以使用effectAllowed来确定允许哪个效果。其值如下(dropEffect只有none 、copy、move、link):

    none 、copy、move、link,copyMove,linkMove、all、uninitialized

    chrome 默认是显示一个绿色的加号,设置:$event.dataTransfer.effectAllowed = 'move'。则恢复成默认鼠标样式。

    files属性

    返回被拖拽的文件列表,是一个FileList对象,有length属性,可通过下标访问。此功能可用于将文件从用户桌面拖动到浏览器。一般配合FileReader来处理文件。如FileReader.readAsDataURL与FileReader.onload

    拖动元素排序实现

    之前写了两篇文章,有读者留言希望看代码,这次大致写了下

    https://codepen.io/lujun-zhou/pen/KKmNgxv

    vue实现

    https://codepen.io/lujun-zhou/pen/zYwozMZ

    magicBox tab 排序也是,就是采用这个

    画布元素位置与尺寸调整

    可以先回顾下《再谈BOM和DOM(6):dom对象及event对象位值计算—如offsetX/Top,clentX

    如果使用mouse事件控制,就显得非常复杂。这种一般都是使用第三方库实现,如  interact.js 、vue-drag-resize等。

    如果直接使用 css resize,然后通过 resizeObserve 回调尺寸改变,实现起来就变得简单的多。

    这种思路之前也介绍过,如《懒加载优化:JavaScript IntersectionObserver API监听元素是否可见》。

    这里的大致实现代码:

    https://codepen.io/lujun-zhou/pen/jOmVLGy

    之前做过一版类似DataV的需求,就是直接用html5 原生属性写的。

    canvas 画布实现:https://codepen.io/atindo23/pen/OJLbdrJ

    鼠标缩放元素操作

    缩放事件,实现不肖多说,MDN案列写的够好了

    https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onwheel

    参考文章:

    HTML5--拖放事件与dataTransfer对象 https://blog.csdn.net/hjc256/article/details/89021483

    说说 HTML 中的dropEffect 和 effectAllowed https://blog.csdn.net/gggg5643/article/details/52135824

    HTML5 进阶系列:拖放 API 实现拖放排序 - 林鑫的文章 - 知乎 https://zhuanlan.zhihu.com/p/26666141

    HTML5前端技术教程:H5拖放 - 方伟景的文章 - 知乎 https://zhuanlan.zhihu.com/p/47458212

    转载本站文章《html5鼠标拖动排序及resize实现方案分析及实践》,
    请注明出处:https://www.zhoulujun.cn/html/webfront/SGML/html5/2016_0124_434.html

  • 相关阅读:
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    block的是发送信号的线程,又不是处理槽函数的线程
  • 原文地址:https://www.cnblogs.com/zhoulujun/p/15008710.html
Copyright © 2011-2022 走看看