JavaScript拖拽API,ondragstart、ondragover、ondragenter、ondrop,使用详细(JavaScript常用原生拖拽API)

简述:JavaScript的拖拽api相必大家都不陌生,今天来分享下元素在拖动时触发的事件,顺便做下记录。

一、ondragstart事件

ondragstart事件在拖动元素时触发,通常用于设置拖动时的数据类型和数据。可以通过event.dataTransfer.setData()方法设置数据类型和数据。

示例代码:

// HTML
<div id="drag" draggable="true">拖动我</div>
<div id="drop">放置区域</div>

// JS
var drag = document.getElementById("drag");
// 拖拽开始 执行一次
drag.addEventListener("dragstart", function(event) {
  event.dataTransfer.setData("text/plain", "这是拖动的数据");
});

二、ondragover事件

ondragover事件在拖动元素在目标元素上方时触发,通常用于防止默认的拖放行为。可以通过event.preventDefault()方法阻止默认行为。

示例代码:

// HTML
<div id="drag" draggable="true">拖动我</div>
<div id="drop">放置区域</div>

// JS
var drop = document.getElementById("drop");
// 拖拽经过 一直执行(类似Mousemove事件)
drop.addEventListener("dragover", function(event) {
  event.preventDefault();
});

三、ondragenter事件

ondragenter事件在拖动元素进入目标元素时触发,通常用于设置拖动时的样式。

示例代码:

// HTML
<div id="drag" draggable="true">拖动我</div>
<div id="drop">放置区域</div>

// CSS
#drop {
  border: 2px dashed #ccc;
}
#drop.dragover {
  border-color: #f00;
}

// JS
var drop = document.getElementById("drop");
// 拖拽进入 执行一次
drop.addEventListener("dragenter", function(event) {
  drop.classList.add("dragover");
});
drop.addEventListener("dragleave", function(event) {
  drop.classList.remove("dragover");
});

四、ondrop事件

ondrop事件在拖动元素放置在目标元素上时触发,通常用于获取拖动时设置的数据。

示例代码:

// HTML
<div id="drag" draggable="true">拖动我</div>
<div id="drop">放置区域</div>

// JS
var drop = document.getElementById("drop");
// 拖拽放手 执行一次,table中的tr td默认禁止拖拽在上面
drop.addEventListener("drop", function(event) {
  var data = event.dataTransfer.getData("text/plain");
  console.log(data);
});

下面通过一个课程表小案例,来实际应用一下,使用JavaScript拖拽API实现的课程表案例,效果如下:

HTMl:

  <div class="demo_box">
    <div class="left" data-drop="move">
      <div data-effect="copy" draggable="true" class="subjects color1">语文</div>
      <div data-effect="copy" draggable="true" class="subjects color2">数学</div>
    </div>
    <table class="right_table" border="1">
      <thead>
        <tr>
          <td>星期一</td>
          <td>星期二</td>
          <td>星期三</td>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td data-drop="copy"></td>
          <td data-drop="copy"></td>
          <td data-drop="copy"></td>
        </tr>
        <tr>
          <td data-drop="copy"></td>
          <td data-drop="copy"></td>
          <td data-drop="copy"></td>
        </tr>
        <tr>
          <td data-drop="copy"></td>
          <td data-drop="copy"></td>
          <td data-drop="copy"></td>
        </tr>
        <tr>
          <td data-drop="copy"></td>
          <td data-drop="copy"></td>
          <td data-drop="copy"></td>
        </tr>
      </tbody>

    </table>
  </div>
  <script src="./draw.js"></script>


  // 用到的自定义属性
  // draggable="true"
  // data-effect="copy"
  // data-drop="copy"
  // data-drop="move"

JavaScript:

// 事件委托  获取父元素
const containerBox = document.querySelector('.demo_box');
// console.log(containerBox);

let source;//定义source ,用于拿到节点‘

// 拖拽开始 执行一次
containerBox.ondragstart = (e) => {
  // console.log("start", e.target);
  // 拖拽事件改为移动 此事拖拽时元素上没有加号 
  // e.dataTransfer.effectAllowed = "move";
  // 默认是copy复制 此事拖拽时元素上有加号
  // e.dataTransfer.effectAllowed = "copy";

  // 自定义事件data-effect = "copy" ,此事件可共享, 所以
  e.dataTransfer.effectAllowed = e.target.dataset.effect;
  // 拿到节点
  source = e.target;
};

// 拖拽经过 一直执行,类似Mousemove事件
containerBox.ondragover = (e) => {
  // console.log("over", e.target);
  //  阻止默认行为 这里就是开启表格的drop事件
  e.preventDefault();
};

function claerStyle() {
  // 清除之前的背景颜色over_bg
  document.querySelectorAll(".over_bg").forEach((node) => {
    node.classList.remove("over_bg");
  });
}
// 判断父元素
function getDropNode(node) {
  while (node) {
    if (node.dataset && node.dataset.drop) {
      return node;
    }
    node = node.parentNode;
  }
}
// 拖拽进入 执行一次
containerBox.ondragenter = (e) => {
  // 清除之前的背景调用
  claerStyle();
  // console.log("enter", e.target);
  // 改变背景颜色 添加over_bg时父子都会触发
  // e.target.classList.add('over_bg');
  // 所以给right里的td添加data-drop="copy"只接受复制
  // 给left添加data-drop="move"
  // const dropNode = e.target;
  // 判断父元素
  const dropNode = getDropNode(e.target);
  if (dropNode && dropNode.dataset.drop === e.dataTransfer.effectAllowed) {
    //如果相等 表示该节点能够接受目前拖拽的节点
    dropNode.classList.add('over_bg');
  }

};

// 拖拽放手 执行一次,table中的tr td默认禁止拖拽在上面,所以需要阻止默认行为;
containerBox.ondrop = (e) => {
  // console.log("drop", e.target);
  // 首先清除之前的背景颜色
  claerStyle();
  const dropNode = getDropNode(e.target);
  if (dropNode && dropNode.dataset.drop === e.dataTransfer.effectAllowed) {
    //如果相等 表示该节点能够接受目前拖拽的节点
    // 分为两种情况
    if (dropNode.dataset.drop === "copy") {
      dropNode.innerHTML = '';
      // 克隆元素 source是上面拿到的元素
      const cloned = source.cloneNode(true);
      cloned.dataset.effect = "move";
      // 添加克隆的元素
      dropNode.appendChild(cloned);
    }
    else {
      source.remove();
    }
  }
};

视频讲解:

使用方式:拖拽API,课程表小案例讲解(复制后,打开抖音搜索)

1.02 lPX:/ 拖拽API # 前端开发工程师 # JavaScript # 编程 # 程序员 # web前端 # 前端 # 前端开发 https://v.douyin.com/UuyyMjc/

猜你喜欢

转载自blog.csdn.net/weixin_65793170/article/details/130941302