H5 拖放 - 学习

前言 一个典型的drag操作是这样开始的:用户用鼠标选中一个可拖动的(draggable)元素,移动鼠标到一个可放置的(droppable)元素,然后释放鼠标。 在操作期间,会触发一些事件类型,有一些事件类型可能会被多次触发 第一部分 在拖动元素上 要使其他的 HTML 元素可拖动,必须做三件事: 在你想要拖动的元素上,将 draggable 属性设置成 true 。 为事件添加一个监听器 dragstart。 在上面定义的监听器中设置拖动数据 1.1 draggable: 可拖动属性 draggable: 全局属性, 是一个枚举类型, 而不是布尔类型. 这意味着必须显式指定值为 true 或者 false ,像 这样的简写是不允许的。正确的用法是` 默认情况下,只有已选中的文本、图片、链接可以拖动。对其它的元素来说,必须按拖动机制的顺序设置 ondragstart 事件才能正常工作 属性 draggable 设置为 true,所以这个元素变成可拖动的。如果该属性被省略或被设置为 false,则该元素将不会被拖动,而是只选中文本。 注意,当一个元素被设置成可拖动的时候, 文本或者其中的其他元素不能再以正常的方式(通过鼠标点击和拖动)被选择。用户必须按住 alt 键,用鼠标选择文本,或者使用键盘来代替。
1.2 ondragstart: 开始拖动事件 当用户开始拖动时,会触发 dragstart 事件(此事件会冒泡), 所有拖拽事件都有一个名为 dataTransfer的属性,它持有拖曳数据(dataTransfer 是一个 DataTransfer 对象)。 一个web应用需要添加拖拽功能时,应当仅仅使用DragEvent(事件对象)和DataTransfer(事件对象中的属性)接口即 DataTransfer对象 这个对象可以从所有拖动事件 drag events的 dataTransfer属性上获取,但是不能单独创建。 详情见MDN资料 属性: dropEffect: 影响到拖动过程中浏览器显示的鼠标样式 方法: setData: 设置拖动数据 /** * @name: 设置拖动元素的数据 * @param {type: 数据MIME} * @param {value: 数据值} * @return: none */ event.dataTransfer.setData(type, value); // =============== 示例 ============== /* * type类型: application/x-bookmark: 自定义类型 text/uri-list: URL text/plain: 文本 * 您可以以多种格式提供数据, 每种格式可以提供一次, 如果您试图以相同的格式添加两次数据,那么新的数据将替换旧的数据。 * 不能设置复杂类型数据, 此时可以通过反序列化解决 */ var dt = event.dataTransfer; dt.setData("application/x-bookmark", bookmarkString); dt.setData("text/uri-list", "http://www.mozilla.org"); dt.setData("text/plain", "http://www.mozilla.org"); getData(): 获取设置的数据 /** * @name: 获取通过setData()设置的数据 * @param {type: 数据MIME} * @return: none */ event.dataTransfer.clearData(type); /* * 参数必填, 没有参数会直接报错 * 当参数的 MIME 没有对应值时, 返回空字符串 */ event.dataTransfer.getData("text/plain"); clearData: 清除数据** /** * @name: 清除拖动元素的数据 * @param {type?: 数据MIME} * @return: none */ event.dataTransfer.clearData(type); // ================ 示例 ================== /* * 如果没有参数调用此方法,或者格式为空 ,则将删除所有类型的数据。 * 该方法只能在dragstart 事件的处理程序中使用,因为这是拖动操作的数据存储只能写入的时间。 * */ event.dataTransfer.clearData("text/uri-list"); setDragImage(): 设置拖动反馈图像 当一个拖动发生时,一个半透明的图像是由拖拽目标生成的("dragstart" 事件被触发的元素),并在拖动过程中跟踪鼠标指针。这个映像是自动创建的,所以你不需要自己创建它。但是,您仍然可以使用 setDragImage() 方法来自定义拖动反馈图像。 /** * @name: 设置拖动反馈图像 * @param {image: 图像的引用, 通常是图像元素, 也可以是画布(canvas) 或任何其他元素} * @param {xOffset: 相对于图片的横向偏移量} * @param {yOffset: 相对于图片的纵向偏移量} * @return: none */ event.dataTransfer.setDragImage(image, xOffset, yOffset); // ============== 示例 =========== /* * 引用通常是一个图像元素,但它也可以是画布(canvas)或任何其他元素。 */ var canvas = document.createElementNS("http://www.w3.org/1999/xhtml","canvas"); canvas.width = canvas.height = 50; var ctx = canvas.getContext("2d"); ctx.lineWidth = 4; ctx.moveTo(0, 0); ctx.lineTo(50, 50); ctx.moveTo(0, 50); ctx.lineTo(50, 0); ctx.stroke(); var dt = event.dataTransfer; dt.setData('text/plain', 'Data to Drag'); dt.setDragImage(canvas, 25, 25); 第二部分 放置目标 web页面或应用程序的大多数区域都不是 drop 数据的有效位置。因此,这些事件的默认处理是不允许出现 drop。 如果您想要允许 drop,您必须通过取消事件来防止默认的处理, 在 dragover 事件中调用 preventDefault() 方法将表明在该位置允许 drop 。 1. dragover: 当元素或选中的文本被拖到一个可释放目标上时触发(每100毫秒触发一次)。 在 dragover 事件中调用 preventDefault() 方法, 但是这样的话, 会将所有拖动元素放置进来, 通常希望只在某些情况下调用 preventDefault() 方法, 这时可以通过检查拖放元素的 dataTransfer 的types属性(而使用ev.dataTransfer.getData("text/plain") 这种方式无用, 因为在dragover事件中无法获取到数据的) types属性: 拖动操作中使用的数据格式数组。每种格式都是字符串类型。如果拖动操作不包含数据,则此数组列表将为空。如果拖动操作中包含任何文件,则其中一个类型将是Files。 特别注意: 这是一个只读属性, 如果通过enent.dataTransfer.types直接查看数据 // 可以通过判断 types 中存放的数据类型来判断是否是需要的拖动元素 (因为图片, 链接也是默认可以拖动的) -- form/item(可以自定义类型的) if ([...e.dataTransfer.types].includes("form/item")) { e.preventDefault(); } 2. drop: 拖动元素放置的时候触发 处理放置效果, 在drop事件中处理, 在这个事件中可以调用event.dataTransfer.getData()来获取数据 注意每个处理程序调用 preventDefault() 来阻止对这个事件的其它处理过程(如触点事件或指针事件) // 拖动第四步: 在拖动元素放置到 放置目标 , 执行一系列的操作 // drop事件: 当元素或选中的文本在可释放目标上被释放时触发 box.addEventListener("drop", function(e) { console.log(e.dataTransfer.getData("form/item")); e.preventDefault(); this.innerText = e.dataTransfer.getData("form/item"); }); 第三部分 简单实例 Document
最后 只是简单学习了一下H5的拖放过程, 没有深入的细究, 还有好多事件 和 属性在一定的场景下有作用的 参考资料 MDN 菜鸟教程

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):