原生JS的拖拽属性draggable

定义和用法

draggable 属性规定元素是否可拖动。

提示: 链接和图像默认是可拖动的。

提示: draggable 属性经常用于拖放操作。

draggable 属性是 HTML5 新增的。

语法

html 复制代码
<element draggable="true|false|auto">

属性值

描述
true 规定元素是可拖动的。
false 规定元素是不可拖动的。
auto 使用浏览器的默认特性。

draggable属性的使用

draggable既然是拖放,那么主要是两个角色比较重要:

(1)被拖动的元素A

(2)A被拖动以后放置的元素B

举例

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .one{
      width: 100px;
      height: 100px;
      background-color: red;
    }
    .two{
      width: 200px;
      height: 200px;
      background-color: springgreen;
    }
  </style>
</head>
<body>
  <div class="one" draggable="true">11</div>
  <div class="two">22</div>
  <script>
  </script>
</body>
</html>

效果

现在有两个点:

(1)拖动的元素要赋予draggable属性,属性值为true。

(2)被拖进的元素要在dragover和dragenter事件值中阻止默认行为。

js 复制代码
<div class="one" draggable="true">11</div>
<div class="two" ondragover="handleOndragover(event)" ondragenter="handleOndragenter(event)">22</div>
<script>
  function handleOndragover(e){
    e.preventDefault();
  }
  function handleOndragenter(e){
    e.preventDefault();
  }
</script>

此时A元素可以拖入到B元素里面,但是只是视觉效果上的,一旦松开鼠标,就恢复原状了

draggable属性的API

针对被拖拽元素A

(1)dragstart方法

该方法在按下鼠标并且移动鼠标时,会在A上触发该方法。同时鼠标的光标会变成禁用的样子,直到拖动到允许放置A的元素上,禁用的效果就会消失。

而允许放置A的元素,就是刚刚说的在dragover和dragenter中阻止默认行为

举例:当拖动A时,改变A元素的背景颜色为蓝色

js 复制代码
<div class="one" draggable="true" ondragstart="handleOndragstart(event)">11</div>
<div class="two" ondragover="handleOndragover(event)" ondragenter="handleOndragenter(event)">22</div>
<script>
  function handleOndragstart(e){
    e.target.style.backgroundColor='blue';
  }
  function handleOndragover(e){
    e.preventDefault();
  }
  function handleOndragenter(e){
    e.preventDefault();
  }
</script>

(2)drag方法

该方法发生在dragstart之后,只要是在拖动过程之中,该方法就会持续触发

js 复制代码
<div class="one" draggable="true" ondragstart="handleOndragstart(event)" ondrag="handleOndrag(event)">11</div>
<div class="two" ondragover="handleOndragover(event)" ondragenter="handleOndragenter(event)">22</div>
<script>
  function handleOndragstart(e){
    console.log('ondragstart');
  }
  function handleOndrag(e){
    console.log('ondrag');
  }
  function handleOndragover(e){
    e.preventDefault();
  }
  function handleOndragenter(e){
    e.preventDefault();
  }
</script>

(3)dragend方法

该方法是在拖动结束的时候触发,也就是当你拖拽后,松开鼠标的一瞬间触发

xml 复制代码
<div class="one" draggable="true" ondragstart="handleOndragstart(event)" ondrag="handleOndrag(event)" ondragend="handleOndragend(event)">11</div>
<div class="two" ondragover="handleOndragover(event)" ondragenter="handleOndragenter(event)">22</div>
<script>
  function handleOndragstart(e){
    console.log('ondragstart');
  }
  function handleOndrag(e){
    console.log('ondrag');
  }

  function handleOndragend(e){
    console.log('ondragend');
  }

  function handleOndragover(e){
    e.preventDefault();
  }
  function handleOndragenter(e){
    e.preventDefault();
  }
</script>

一般我们比较常用的方法就是dragstrat方法,通过在这个方法中将被推拽的元素进行保存下来,再进行后续的操作。

拖入元素B的事件

针对于拖入元素的事件,它不需要元素具有draggable属性,只要你想,任何元素使用这些方法都是可以的。但要记住上面所说的那两个方法,阻止事件默认行为。

(1)dragenter方法

该方法是指拖拽元素A,在拖入到B之中,B所触发的事件。当然,任何具有draggable属性为true的元素,拖入到B中,都会触发该事件。

xml 复制代码
<div class="one" draggable="true" ondragstart="handleOndragstart(event)" ondrag="handleOndrag(event)" ondragend="handleOndragend(event)">11</div>
<div class="two" ondragover="handleOndragover(event)" ondragenter="handleOndragenter(event)">22</div>
<script>
  function handleOndragstart(e){
    console.log('ondragstart');
  }
  function handleOndrag(e){
    console.log('ondrag');
  }

  function handleOndragend(e){
    console.log('ondragend');
  }

  function handleOndragover(e){
    e.preventDefault();
  }
  function handleOndragenter(e){
    console.log('ondragenter');
    e.preventDefault();
  }
</script>

切记,这里事件的触发不需要松开鼠标

举例: 当A拖入到B中,我们希望A是真正成为B的子元素:

js 复制代码
<div class="one" draggable="true" ondragstart="handleOndragstart(event)" ondrag="handleOndrag(event)" ondragend="handleOndragend(event)">11</div>
<div class="two" ondragover="handleOndragover(event)" ondragenter="handleOndragenter(event)">22</div>
<script>
  function handleOndragstart(e) {
    console.log('ondragstart');
  }
  function handleOndrag(e) {
    console.log('ondrag');
  }

  function handleOndragend(e) {
    console.log('ondragend');
  }

  function handleOndragover(e) {
    e.preventDefault();
  }
  function handleOndragenter(e) {
    e.preventDefault();
    e.target.appendChild(document.querySelector('.one'))
  }
</script>

(2)dragover方法

该方法只要是,拖拽元素A在目标元素B中移动,就会持续触发。(就是如果A在B区域内悬浮,就会触发)

js 复制代码
function handleOndragover(e) {
  e.preventDefault();
  console.log('ondragover');
}

(3)dragleave方法

该方法指的是拖拽元素A,在从目标元素B中离开的时候,会触发该方法

这里记住,一定是先进入到B,再离开B的时候触发该事件,也就是说要先触发dragenter方法,才能触发dragleave方法

js 复制代码
function handleOndragleave(e){
  console.log('ondragleave');
}

(4)drop方法

该方法是指,拖拽元素A被放置了目标元素B中的时候触发,那它和dragenter方法的区别在于,该方法需要鼠标松开才会触发。而这个方法也是最常用的方法。

例: 当A拖入到B中,我们希望A是真正成为B的子元素:

js 复制代码
function handleOndrop(e){
  console.log('ondrop');
  e.target.appendChild(document.querySelector('.one'))
}

总结

如果要实现拖放,需要具备以下条件

(1)拖动的元素要赋予draggable属性,属性值为true。

(2)最重要的三个事件:dragstart、dragover、drop

  • 被托动元素A需要设置draggable属性、dragstart事件
  • 拖入元素B需要设置dragover、drop事件
html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .one {
      width: 100px;
      height: 100px;
      background-color: red;
    }

    .two {
      width: 200px;
      height: 200px;
      background-color: springgreen;
    }
  </style>
</head>

<body>
  <div class="one" draggable="true" ondragstart="handleOndragstart(event)">11</div>
  <div class="two" ondragover="handleOndragover(event)" ondrop="handleOndrop(event)">22</div>
  <script>
    function handleOndragstart(e){
      console.log(e);
    }
    function handleOndragover(e){
      e.preventDefault();
    }
    function handleOndrop(e){
      e.target.appendChild(document.querySelector('.one'))
    }
  </script>
</body>

</html>
相关推荐
AndyGoWei1 小时前
react react-router-dom history 实现原理,看这篇就够了
前端·javascript·react.js
小仓桑1 小时前
深入理解 JavaScript 中的 AbortController
前端·javascript
换个名字不能让人发现我在摸鱼1 小时前
裁剪保存的图片黑边问题
前端·javascript
小牛itbull1 小时前
Mono Repository方案与ReactPress的PNPM实践
开发语言·前端·javascript·reactpress
小宋10212 小时前
实现Excel文件和其他文件导出为压缩包,并导入
java·javascript·excel·etl
码喽哈哈哈2 小时前
day01
前端·javascript·html
mubeibeinv2 小时前
分页/列表分页
java·前端·javascript
林太白2 小时前
js属性-IntersectionObserver
前端·javascript
爱吃羊的老虎2 小时前
【WEB开发.js】getElementById :通过元素id属性获取HTML元素
前端·javascript·html
GISer_Jing3 小时前
Vue3常见Composition API详解(适用Vue2学习进入Vue3学习)
前端·javascript·vue.js