html 拖拽事件详解

为了使元素可拖拽,需要在标签上设置draggable='true'属性。

文本、图片和链接是默认可以拖放的,它们的draggable属性自动被设置成了true

图片和链接按住鼠标左键选中,就可以拖放。

文本只有在被选中的情况下才能拖放。如果显示设置文本的draggable属性为true,按住鼠标左键也可以直接拖放。

拖拽元素上的事件

给元素设置draggable属性后监听。

语法: <element draggable="true | false | auto" ></element>

  • true: 可以拖动
  • false:禁止拖动
  • auto:默认值,使用浏览器定义的默认行为

在网页中,对于选中文本、图片和链接,浏览器会使用默认的拖动行为。当图片或者链接在拖动时,会自动设置图片或链接的地址为拖动数据(通过dragEvent.dataTransfer.getData('url'),如果拖动的是链接,那么同时也可以通过dragEvent.dataTransfer.getData('text')可获取);如果使用鼠标选中图片后拖动,那就不会设置图片的链接为拖动数据,当选中文本在拖动时,会自动设置文本为拖动数据(通过dragEvent.dataTransfer.getData('text')获取).

<a
  href="https://developer.mozilla.org/static/media/github-mark-small.348586b8904b950b8ea8.svg"
  >https://developer.mozilla.org/static/media/github-mark-small.348586b8904b950b8ea8.svg</a
>
<script>
  const a = document.getElementsByTagName("a")[0];
  a.addEventListener("dragstart", (e) => {
    // 均可以获取链接
    console.log("text: " + e.dataTransfer.getData("text"));
    console.log("url: " + e.dataTransfer.getData("url"));
    e.preventDefault();
  });![请添加图片描述](https://img-blog.csdnimg.cn/0b1a4c8add5445f5b7c4bea6b3196b61.gif)

</script>

链接拖动默认执行:

请添加图片描述

选中链接拖动默认执行:

请添加图片描述

<img
  src="https://developer.mozilla.org/static/media/github-mark-small.348586b8904b950b8ea8.svg"
  width="100px"
  height="100px"
/>

<script>
  const img = document.getElementsByTagName("img")[0];
  img.addEventListener("dragstart", (e) => {
    // 只有getData('url')能获取
    console.log("text: " + e.dataTransfer.getData("text"));
    console.log("url: " + e.dataTransfer.getData("url"));
    e.preventDefault();
  });
</script>

图片拖动默认执行:

请添加图片描述

选中图片后拖动默认执行:

请添加图片描述

默认情况下,只有已选中的文本、图片、链接可以拖动。对其它的元素来说,必须按拖动机制的顺序设置 ondragstart 事件才能正常工作。

设置了draggabletrue的元素不可选中

<div draggable="true">设置了draggable后不可选中</div>
<a
  draggable="true"
  href="https://developer.mozilla.org/static/media/github-mark-small.348586b8904b950b8ea8.svg"
  >https://developer.mozilla.org/static/media/github-mark-small.348586b8904b950b8ea8.svg</a
>
<img
  draggable="true"
  src="https://developer.mozilla.org/static/media/github-mark-small.348586b8904b950b8ea8.svg"
  width="100px"
  height="100px"
/>

设置了draggabletrue不可选中:

请添加图片描述

注意:设置了draggabletrue的元素都不能通过常规的鼠标点击拖动选中。不过可以通过按下Alt键同时点击来选中文本(通过dragEvent.dataTransfer.getData('text')获取)。

draggbale可以在所有元素上使用,包括图片和链接。不过,图片跟链接的draggable默认为true,所以通常只用来设置false来禁止拖动。

链接设置 draggable=false,如果行内同时存在图片,不会触发 dragstart

dragstart

该事件在拖拽元素或被选中的文本上触发,通常用来设置数据。

通过addEventListener或者onDragstart方法进行监听。

<div draggable="true">用于监听dragstart</div>
<script>
  const div = document.getElementsByTagName("div")[0];
  div.addEventListener("dragstart", (event) => {
    console.log("dragstart");
    console.log(event);
  });
  div.ondragstart = (event) => {
    console.log("ondragstart");
    console.log(event);
  };
</script>

请添加图片描述

由于拖动事件会冒泡,因此可以单独监听父元素来获取多个子元素的拖动事件。

<div id="bubble-drag">
  <a
    href="https://developer.mozilla.org/static/media/github-mark-small.348586b8904b950b8ea8.svg"
    >https://developer.mozilla.org/static/media/github-mark-small.348586b8904b950b8ea8.svg</a
  >
  <img
    src="https://developer.mozilla.org/static/media/github-mark-small.348586b8904b950b8ea8.svg"
    width="100px"
    height="100px"
  />
  <h1 draggable="true">拖动事件会冒泡</h1>
</div>
<script>
  const bubbleDrag = document.getElementById("bubble-drag");
  bubbleDrag.addEventListener("dragstart", (e) => {
    console.log(e);
    console.log(e.dataTransfer.getData("text"));
  });
</script>

dragstart事件中,可以设置拖动数据,反馈图片及拖动效应。

拖拉事件用一个DragEvent对象表示,该对象继承 MouseEvent 对象,因此也就继承了 UIEventEvent 对象。DragEvent 对象只有一个独有的属性 DataTransfer,其他都是继承的属性。DataTransfer 属性用来读写拖拉事件中传输的数据

所有的拖动事件都有一个dataTransfer属性用来保存拖动数据。当元素拖动时,数据必须是能表明是哪个元素在被拖动,比如拖动选中文本时,拖动数据就是文本本身,拖动链接时拖动数据就是对应链接的地址。

拖动数据(drag data)包含两个值,数据类型(推荐类型)跟数据值(都是string类型).在拖动期间,通过setData去设置拖动数据。

通过setData设置拖动数据

<h1 draggable="true">通过setData设置拖动数据</h1>
<script>
  const h1 = document.getElementsByTagName("h1")[0];
  h1.addEventListener("dragstart", (e) => {
    e.dataTransfer.setData("text/plain", "设置拖动数据");
    console.log(e.dataTransfer.getData("text"));
  });
</script>

请添加图片描述

一个拖动事件可以设置多个拖动数据。

h1.addEventListener("dragstart", (e) => {
  e.dataTransfer.setData("text/plain", "设置拖动数据");
  e.dataTransfer.setData("text/uri-list", "http://github.com");
  console.log(e.dataTransfer.getData("text"));
  console.log(e.dataTransfer.getData("url"));
});

请添加图片描述

当设置多个数据时,最好有一个text/plain类型作为替补防止有些drop目标不支持其他类型。

如果多次设置同一类型的数据,那么新数据会覆盖旧数据。

使用clearData移除某类型数据或全部数据。
clearData接受一个参数(数据类型),如果没传参数,就删除全部数据。

drag

该事件在拖拽元素上触发,在元素被拖动时反复触发

<h1 draggable="true">监听drag事件</h1>
<script>
  const h1 = document.getElementsByTagName("h1")[0];
  h1.addEventListener("drag", (e) => {
    console.log(e);
  });
</script>

请添加图片描述

dragend

该事件在拖拽元素上触发,在元素拖动完成时(释放鼠标键或按下escape键)触发

<h1 draggable="true">监听dragend事件</h1>
<script>
  const h1 = document.getElementsByTagName("h1")[0];
  h1.addEventListener("dragend", (e) => {
    console.log(e);
  });
</script>

请添加图片描述

可放置元素

对于大多数浏览器页面和应用来说都是不能直接放置拖拽数据的。不过浏览器提供了几个事件用来声明可放置目标。

通过取消dragenterdragover事件的默认执行动作就可以实现元素放置。

dragenter

该事件在拖动目标元素上触发,在拖动元素进入目标元素所占据的屏幕空间时触发

通常应该在这个事件的监听函数中,指定是否允许在当前节点放下(drop)拖拉的数据。如果当前节点没有该事件的监听函数,或者监听函数不执行任何操作,就意味着不允许在当前节点放下数据(dragleavedragoverdrop事件都不会触发)。在视觉上显示拖拉进入当前节点,也是在这个事件的监听函数中设置。

dragleave

该事件在拖动目标元素上触发,在拖动元素没有放下就离开目标元素时触发

dragover

该事件在拖动目标元素上触发,在拖动元素在目标元素内时持续触发

该事件的 target 属性是当前节点。该事件与dragenter事件基本类似,默认会重置当前的拖拉事件的效果(DataTransfer对象的dropEffect属性)为none,即不允许放下被拖拉的节点,所以如果允许在当前节点drop数据,通常会使用preventDefault方法,取消重置拖拉效果为none

drop

当被拖动元素或选中文本在目标元素里放下时触发,一般需要取消浏览器的默认行为。

<h1>拖拽元素</h1>
<div
  style="width: 300px; height: 300px; border: 1px solid black"
  id="drop-target"
>
  可放置元素
</div>
<script>
  const dropTarget = document.getElementById("drop-target");
  dropTarget.addEventListener("dragover", (e) => {
    e.preventDefault();
  });
  dropTarget.addEventListener("drop", (e) => {
    console.log(e);
  });
</script>

注意,如果当前节点不允许drop,即使在该节点上方松开鼠标键,也不会触发该事件。如果用户按下Escape键,取消这个操作,也不会触发该事件。该事件的监听函数负责取出拖拉数据,并进行相关处理

关于拖拉事件,有以下几点注意事项。

  • 拖拉过程只触发以上这些拖拉事件,尽管鼠标在移动,但是鼠标事件不会触发。

  • 将文件从操作系统拖拉进浏览器,不会触发 dragStart 和 dragend 事件。

  • dragenterdragover 事件的监听函数,用来指定可以放下(drop)拖拉的数据。由于网页的大部分区域不适合作为 drop 的目标节点,所以这两个事件的默认设置为当前节点不允许 drop。如果想要在目标节点上 drop 拖拉的数据,首先必须阻止这两个事件的默认行为,或者取消这两个事件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值