前端——html拖拽原理

简介: 前端——html拖拽原理

⭐前言

大家好,我是yma16,本文分享关于 前端——html拖拽原理。

vue3系列相关文章:

vue3 + fastapi 实现选择目录所有文件自定义上传到服务器

前端vue2、vue3去掉url路由“ # ”号——nginx配置

csdn新星计划vue3+ts+antd赛道——利用inscode搭建vue3(ts)+antd前端模板

认识vite_vue3 初始化项目到打包

python_selenuim获取csdn新星赛道选手所在城市用echarts地图显示

让大模型分析csdn文章质量 —— 提取csdn博客评论在文心一言分析评论区内容

前端vue3——html2canvas给网站截图生成宣传海报

html draggable属性

dragabble属性是HTML5中新增加的属性,可以应用于任何HTML元素上,实现拖拽效果。当该属性设置为true时,元素就可以被拖拽。当元素被拖拽时,会触发dragstart、drag、dragend等事件。

例如:

<div draggable="true">
  拖拽我
</div>

上面的代码会在一个div元素上添加draggable属性,使其可拖拽。通过设置属性值为true,我们就可以实现该元素的拖拽效果。

⭐draggable属性

分解拖动动作

  1. 鼠标选择div
  2. 鼠标按住不放拖拽div
  3. 拖拽的div(源数据)在目标区域div外侧移动
  4. 拖拽的div(源数据)在目标区域div内侧移动
  5. 拖拽的div(源数据)在目标区域div内侧掉落

draggable属性:全局属性 draggable 是一种枚举 (en-US)属性,用于标识元素是否允许使用浏览器原生行为或 HTML 拖放操作 API 拖动。

true: 可以拖动

false: 禁止拖动

auto: 跟随浏览器定义是否可以拖动。

draggable 可以有如下取值:

true:表示元素可以被拖动

false:表示元素不可以被拖动

如果该属性没有设值,则默认值 为 auto,表示使用浏览器定义的默认行为。

注意:

这个属性是枚举类型 (en-US),而不是布尔类型。这意味着必须显式指定值为 true 或者 false,像 这样的简写是不允许的。正确的用法是

💖 api

对象 事件 说明
被拖动对象 drag 拖动时反复触发 drag ,事件在用户拖动元素或选择的文本时,每隔几百毫秒就会被触发一次。
被拖动对象 dragstart 拖动开始时触发,事件在用户开始拖动元素或被选择的文本时调用
被拖动对象 dragend 拖动结束时触发,事件在拖放操作结束时触发(通过释放鼠标按钮或单击 escape 键)
目标对象 drop 事件在元素或文本选择被放置到有效的放置目标上时触发。为确保 drop 事件始终按预期触发,应当在处理 dragover 事件的代码部分始终包含 preventDefault() 调用
目标对象 dragenter 进入区域时触发,事件在可拖动的元素或者被选择的文本进入一个有效的放置目标时触发
目标对象 dragover 悬浮区域时触发,事件在可拖动的元素或者被选择的文本被拖进一个有效的放置目标时(每几百毫秒)触发
目标对象 dragleave 离开区域时触发,事件在拖动的元素或选中的文本离开一个有效的放置目标时被触发

💖 单向拖动示例

元素单方向拖动

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="style.css" rel="stylesheet" type="text/css" />
    <title>drag</title>
    <style>
      html {
        height: 100%;
        width: 100%;
        background: #005AA7;  /* fallback for old browsers */
        background: -webkit-linear-gradient(to bottom, #FFFDE4, #005AA7);  /* Chrome 10-25, Safari 5.1-6 */
        background: linear-gradient(to bottom, #FFFDE4, #005AA7); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
      }
      .container {
        text-align: center;
        padding: 64px;
        display: flex;
        justify-content: space-between;
      }
      .container-left {
        width: 40%;
      }
      .container-right {
        width: 40%;
      }
      .container-left-box {
        min-height: 100px;
        line-height: 100px;
        min-width: 400px;
        color:#fff;
        background: #b92b27;  /* fallback for old browsers */
        background: -webkit-linear-gradient(to right, #1565C0, #b92b27);  /* Chrome 10-25, Safari 5.1-6 */
        background: linear-gradient(to right, #1565C0, #b92b27); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
        cursor: pointer;
        border-radius: 8px;
      }
      .container-right-box {
        min-height: 100px;
        line-height: 100px;
        min-width: 400px;
        color:#fff;
        background: #12c2e9;  /* fallback for old browsers */
        background: -webkit-linear-gradient(to right, #f64f59, #c471ed, #12c2e9);  /* Chrome 10-25, Safari 5.1-6 */
        background: linear-gradient(to right, #f64f59, #c471ed, #12c2e9); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
        cursor: pointer;
        border-radius: 8px;
      }
      .dragging {
        opacity: .5;
      }
      
      .dragover{
        opacity: .5;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="container-left">
        <div class="container-left-box" draggable="true" id="source">
          左侧可以拖动
        </div>
      </div>
      <div class="container-right">
        <div class="container-right-box dropzone" id="droptarget">
          可以拖到这里
        </div>
      </div>
    </div>
    <script>
      // 配置项
      const config = {
        draged: null
      }
      function init() {
        console.log('window onload');
        /* 在可拖动的目标上触发的事件 */
        const source = document.getElementById("source");
        source.addEventListener("drag", (event) => {
          console.log("dragging");
        });
        source.addEventListener("dragstart", (event) => {
          // 保存被拖动元素的引用
          config.draged = event.target;
          // 设置为半透明
          event.target.classList.add("dragging");
        });
        source.addEventListener("dragend", (event) => {
          // 拖动结束,重置透明度
          event.target.classList.remove("dragging");
        });
        /* 在放置目标上触发的事件 */
        const target = document.getElementById("droptarget");
        target.addEventListener(
          "dragover",
          (event) => {
            // 阻止默认行为以允许放置
            event.preventDefault();
          },
          false,
        );
        target.addEventListener("dragenter", (event) => {
          // 在可拖动元素进入潜在的放置目标时高亮显示该目标
          if (event.target.classList.contains("dropzone")) {
            event.target.classList.add("dragover");
          }
        });
        target.addEventListener("dragleave", (event) => {
          // 在可拖动元素离开潜在放置目标元素时重置该目标的背景
          if (event.target.classList.contains("dropzone")) {
            event.target.classList.remove("dragover");
          }
        });
        target.addEventListener("drop", (event) => {
          // 阻止默认行为(会作为某些元素的链接打开)
          event.preventDefault();
          // 将被拖动元素移动到选定的目标元素中
          if (event.target.classList.contains("dropzone")) {
            event.target.classList.remove("dragover");
            // 删除自身
            // config.draged.parentNode.removeChild(config.draged);
            event.target.appendChild(config.draged);
          }
        });
      }
      window.onload = init;
    </script>
  </body>
</html>

拖动效果

💖 双向拖动示例

元素可以左右拖动

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="style.css" rel="stylesheet" type="text/css" />
    <title>drag</title>
    <style>
      html {
        height: 100%;
        width: 100%;
        background: #005AA7;
        /* fallback for old browsers */
        background: -webkit-linear-gradient(to bottom, #FFFDE4, #005AA7);
        /* Chrome 10-25, Safari 5.1-6 */
        background: linear-gradient(to bottom, #FFFDE4, #005AA7);
        /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
      }
      .container {
        text-align: center;
        padding: 64px;
        display: flex;
        justify-content: space-between;
      }
      .container-left {
        width: 40%;
        border: 1px solid #1565C0;
        border-radius: 8px;
      }
      .container-right {
        width: 40%;
      }
      .container-left-box {
        min-height: 100px;
        min-width: 100px;
        line-height: 100px;
        min-width: 400px;
        color: #fff;
        background: #b92b27;
        /* fallback for old browsers */
        background: -webkit-linear-gradient(to right, #1565C0, #b92b27);
        /* Chrome 10-25, Safari 5.1-6 */
        background: linear-gradient(to right, #1565C0, #b92b27);
        /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
        cursor: pointer;
        border-radius: 8px;
        
      }
      .container-right-box {
        min-height: 100px;
        line-height: 100px;
        min-width: 400px;
        color: #fff;
        background: #12c2e9;
        /* fallback for old browsers */
        background: -webkit-linear-gradient(to right, #f64f59, #c471ed, #12c2e9);
        /* Chrome 10-25, Safari 5.1-6 */
        background: linear-gradient(to right, #f64f59, #c471ed, #12c2e9);
        /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
        cursor: pointer;
        border-radius: 8px;
      }
      .dragging {
        opacity: .5;
      }
      .dragover {
        opacity: .5;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="container-left dropzone" id='left-box'>
        <div class="container-left-box" draggable="true" id="yma16">
          yma16
        </div>
      </div>
      <div class="container-right" id='right-box'>
        <div class="container-right-box dropzone" id="csdn">
          csdn
        </div>
      </div>
    </div>
    <script>
      // 配置项
      const config = {
        draged: null
      }
      const drag = (event) => {
        console.log("dragging");
      }
      const dragStart = (event) => {
        // 保存被拖动元素的引用
        config.draged = event.target;
        // 设置为半透明
        event.target.classList.add("dragging");
      }
      const dragEnd = (event) => {
        // 拖动结束,重置透明度
        event.target.classList.remove("dragging");
      }
      // 目标
      const dragOver = (event) => {
        // 阻止默认行为以允许放置
        event.preventDefault();
      }
      const dragLeave = (event) => {
        // 在可拖动元素离开潜在放置目标元素时重置该目标的背景
        if (event.target.classList.contains("dropzone")) {
          event.target.classList.remove("dragover");
        }
      }
      const dragEnter = (event) => {
        // 在可拖动元素进入潜在的放置目标时高亮显示该目标
        if (event.target.classList.contains("dropzone")) {
          event.target.classList.add("dragover");
        }
      }
      const drop = (event) => {
        // 阻止默认行为(会作为某些元素的链接打开)
        event.preventDefault();
        // 将被拖动元素移动到选定的目标元素中
        if (event.target.classList.contains("dropzone")) {
          event.target.classList.remove("dragover");
          // 删除自身
          config.draged.parentNode.removeChild(config.draged);
          // 添加元素
          event.target.appendChild(config.draged);
        }
      }
      function yma16ToLeft() {
        /* 在放置目标上触发的事件 */
        const target = document.getElementById("left-box");
        if(!target.classList.contains('dropzone')){
          target.classList.add('dropzone')
        }
        target.addEventListener(
          "dragover",
          dragOver,
          false,
        );
        target.addEventListener("dragenter", dragEnter);
        target.addEventListener("dragleave", dragLeave);
        target.addEventListener("drop", drop);
      }
      function yma16ToRight() {
        
        const source = document.getElementById("yma16");
        source.addEventListener("drag", drag);
        source.addEventListener("dragstart", dragStart);
        source.addEventListener("dragend", dragEnd);
        /* 在放置目标上触发的事件 */
        const target = document.getElementById("csdn");
        
        target.addEventListener(
          "dragover",
          dragOver,
          false,
        );
        target.addEventListener("dragenter", dragEnter);
        target.addEventListener("dragleave", dragLeave);
        target.addEventListener("drop", drop);
      }
      function init() {
        console.log('window onload');
        /* 在可拖动的目标上触发的事件 */
        yma16ToLeft()
        yma16ToRight()
      }
      window.onload = init;
    </script>
  </body>
</html>

效果如下:

⭐总结

HTML的draggable属性可以将元素设置为可拖动的。它可以帮助我们实现拖拽功能,让用户可以将元素拖拽到指定的位置或者执行拖拽结束后的某些操作。draggable属性有以下几个取值:

  1. draggable=“true”:表示元素可以被拖动。
  2. draggable=“false”:表示元素不可以被拖动。
  3. draggable=“auto”:表示元素可以被拖动,但是浏览器会根据元素类型和属性自动决定是否允许拖动。

在使用draggable属性时,需要注意以下几点:

  1. 可以设置辅助属性dataTransfer来传输数据。
  2. 可以设置ondragstart、ondrag、ondragenter、ondragover、ondragleave和ondragend等事件来实现一些特定操作。
  3. 需要在ondrop事件中阻止默认行为,否则拖拽的元素将会被打开或者在浏览器中进行导航。

综上所述,draggable属性是一个非常实用的属性,可以帮助我们实现一些常用的拖拽功能。

⭐结束

本文分享到这结束,如有错误或者不足之处欢迎指出!

目录
相关文章
|
4天前
|
JavaScript 前端开发 UED
【Web 前端】如何将一个 HTML 元素添加到 DOM 树中的?
【5月更文挑战第2天】【Web 前端】如何将一个 HTML 元素添加到 DOM 树中的?
|
4天前
|
存储 前端开发 JavaScript
【Web 前端】如何找到所有 HTML select 标签的选中项?
【5月更文挑战第2天】【Web 前端】如何找到所有 HTML select 标签的选中项?
|
5天前
|
缓存 移动开发 前端开发
【专栏:HTML与CSS前端技术趋势篇】HTML与CSS在PWA(Progressive Web Apps)中的应用
【4月更文挑战第30天】PWA(Progressive Web Apps)结合现代Web技术,提供接近原生应用的体验。HTML在PWA中构建页面结构和内容,响应式设计、语义化标签、Manifest文件和离线页面的创建都离不开HTML。CSS则用于定制主题样式、实现动画效果、响应式布局和管理字体图标。两者协同工作,保证PWA在不同设备和网络环境下的快速、可靠和一致性体验。随着前端技术进步,HTML与CSS在PWA中的应用将更广泛。
|
5天前
|
前端开发 JavaScript 开发者
【专栏:HTML与CSS前端技术趋势篇】前端框架(React/Vue/Angular)与HTML/CSS的结合使用
【4月更文挑战第30天】前端框架React、Vue和Angular助力UI开发,通过组件化、状态管理和虚拟DOM提升效率。这些框架与HTML/CSS结合,使用模板语法、样式管理及组件化思想。未来趋势包括框架简化、Web组件标准采用和CSS在框架中角色的演变。开发者需紧跟技术发展,掌握新工具,提升开发效能。
|
5天前
|
前端开发 JavaScript UED
【专栏:HTML 与 CSS 前端技术趋势篇】Web 性能优化:CSS 与 HTML 的未来趋势
【4月更文挑战第30天】本文探讨了CSS和HTML在Web性能优化中的关键作用,包括样式表压缩、选择器优化、DOM操作减少等策略。随着未来趋势发展,CSS模块系统、自定义属性和响应式设计将得到强化,HTML新特性也将支持复杂组件构建。同时,应对浏览器兼容性、代码复杂度和性能功能平衡的挑战是优化过程中的重要任务。通过案例分析和持续创新,我们可以提升Web应用性能,创造更好的用户体验。
|
5天前
|
移动开发 前端开发 UED
【专栏:HTML与CSS前端技术趋势篇】渐进式增强与优雅降级在前端开发中的实践
【4月更文挑战第30天】前端开发中的渐进式增强和优雅降级是确保跨浏览器、跨设备良好用户体验的关键策略。渐进式增强是从基础功能开始,逐步增加高级特性,保证所有用户能访问基本内容;而优雅降级则是从完整版本出发,向下兼容,确保低版本浏览器仍能使用基本功能。实践中,遵循HTML5/CSS3规范,使用流式布局和响应式设计,检测浏览器特性,并提供备选方案,都是实现这两种策略的有效方法。选择合适策略优化网站,提升用户体验。
|
5天前
|
前端开发 开发者 UED
【专栏:HTML与CSS前端技术趋势篇】网页设计中的CSS Grid与Flexbox之争
【4月更文挑战第30天】本文对比了CSS Grid和Flexbox两种布局工具。Flexbox擅长一维布局,简单易用,适合导航栏和列表;CSS Grid则适用于二维布局,能创建复杂结构,适用于整个页面布局。两者各有优势,在响应式设计中都占有一席之地。随着Web标准发展,它们的结合使用将成为趋势,开发者需掌握两者以应对多样化需求。
|
5天前
|
前端开发 JavaScript 搜索推荐
【专栏:HTML 与 CSS 前端技术趋势篇】HTML 与 CSS 在 Web 组件化中的应用
【4月更文挑战第30天】本文探讨了HTML和CSS在Web组件化中的应用及其在前端趋势中的重要性。组件化提高了代码复用、维护性和扩展性。HTML提供组件结构,语义化标签增进可读性,支持用户交互;CSS实现样式封装、布局控制和主题定制。案例展示了导航栏、卡片和模态框组件的创建。响应式设计、动态样式、CSS预处理器和Web组件标准等趋势影响HTML/CSS在组件化中的应用。面对兼容性、代码复杂度和性能优化挑战,需采取相应策略。未来,持续发掘HTML和CSS潜力,推动组件化开发创新,提升Web应用体验。
|
7天前
|
JavaScript 前端开发 数据安全/隐私保护
优秀的前端框架vue,原理剖析与实战技巧总结【干货满满】(二)
优秀的前端框架vue,原理剖析与实战技巧总结【干货满满】(二)
|
7天前
|
JavaScript 前端开发 Python
优秀的前端框架vue,原理剖析与实战技巧总结【干货满满】(一)
优秀的前端框架vue,原理剖析与实战技巧总结【干货满满】(一)