首页 > 其他分享 >原生手动排序

原生手动排序

时间:2024-03-28 10:44:07浏览次数:21  
标签:原生 触发 元素 target dom 拖动 手动 item 排序

原生手动排序

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <style>
    .content-list {
      display: flex;
      flex-direction: column;
      gap: 8px;
    }

    .list-item {
      cursor: pointer;
      width: 50%;
      border: 1px solid red;
      background-color: aqua;
    }

    .moving {
      background-color: unset;
      border: 1px solid;
      border-style: dashed;
    }
  </style>

  <body>
    <div class="content-list">
      <div draggable="true" class="list-item">1</div>
      <div draggable="true" class="list-item">2</div>
      <div draggable="true" class="list-item">3</div>
      <div draggable="true" class="list-item">4</div>
      <div draggable="true" class="list-item">5</div>
    </div>
  </body>
  <script>
    let dom = document.querySelector(".content-list");
    let currentDom;
    dom.ondragstart = (e) => {
      setTimeout(() => {
        e.target.classList.add("moving");
      }, 0);
      currentDom = e.target;
    };
    dom.ondragover = (e) => {
      e.preventDefault();
    };
    dom.ondragenter = (e) => {
      e.preventDefault();
      if (e.target !== dom && e.target !== currentDom) {
        console.log(e.target);
      }
      const children = Array.from(dom.children);
      const currentIndex = children.findIndex((item) => item === currentDom);
      const dropIndex = children.findIndex((item) => item === e.target);
      if (currentIndex > dropIndex) {
        dom.insertBefore(currentDom, e.target);
      } else {
        dom.insertBefore(currentDom, e.target.nextElementSibling);
      }
      console.log(children, currentIndex);
    };
    dom.ondragend = (e) => {
      setTimeout(() => {
        e.target.classList.remove("moving");
      }, 0);
    };
  </script>
</html>

拖放事件

  1. dragstart: 当用户开始拖动一个元素或选中的文本时触发。
  2. dragover: 当某被拖动的元素或选中的文本在另一个元素上方时触发。
  3. dragenter: 当某被拖动的元素或选中的文本进入有效的放置目标时触发。
  4. dragleave: 当某被拖动的元素或选中的文本离开有效的放置目标时触发。
  5. drag: 当元素或选中的文本被拖动时触发。
  6. drop: 当被拖动的元素或选中的文本在放置目标上被释放时触发。
  7. dragend: 当拖动操作结束时(释放鼠标按钮或按下 ESC 键)触发。

实现思路和代码解读

  1. 设置元素可拖动:为了使元素可拖动,你需要设置 draggable="true"属性。在你的代码中,每个.list-item 都设置了这个属性。

  2. 处理 dragstart 事件:当拖动开始时,一个 dragstart 事件被触发。在你的事件处理函数里,你使用 setTimeout 设置了一个微任务,延迟将拖动元素的类名设置为.moving,从而使其变为虚线框(类似占位符的效果)。同时,你保存了当前拖动的元素,以便之后使用。

  3. 处理 dragover 事件:dragover 事件在元素被拖动到另一个元素上方时触发。为了让元素能够放置,你需要阻止默认行为(默认情况下,数据/元素不能被放置到其他元素上)。

  4. 处理 dragenter 事件:dragenter 事件在拖动的元素进入放置目标时触发。在事件处理函数中,你检查了进入的目标,如果它既不是容器本身也不是当前拖动的元素,你会计算当前拖动元素和进入元素的索引,然后根据索引将当前拖动元素放置在适当的位置(前面或后面)。

  5. 处理 dragend 事件:dragend 事件在拖动结束时触发,无论操作成功与否。在事件处理函数中,你移除了.moving 类,恢复元素的原始样式。

关键点

  1. e.preventDefault(): 在 dragover 和 dragenter 事件中使用,是为了允许将元素放置到其他元素上(改变默认不允许放置的行为)。

  2. setTimeout(..., 0): 通过将操作推迟到调用栈清空之后,避免了在拖动过程中对元素样式的立即更改,这可以防止出现不必要的渲染问题。

  3. insertBefore: 这个 DOM 操作方法用来在指定的子节点前插入一个新的子节点,如果参照节点为 null,则插入到子节点列表的末尾。

  4. 整体上,你的代码利用了 HTML5 拖放 API 执行元素的垂直排序。用户通过拖放操作可以重新安排.list-item 元素的顺序,而代码则负责处理所有必要的事件来使这些操作可能。

标签:原生,触发,元素,target,dom,拖动,手动,item,排序
From: https://www.cnblogs.com/gjzsa/p/18101026

相关文章

  • net 6 手动注入
    Program.cs EnginContex为静态类//注册服务EnginContext.SetServiceProvider(app.Services);EnginContex.cspublicsealedclassEnginContext{privatestaticIServiceProvider_serviceProvider;[MethodImpl(MethodImplOptions.Synchroni......
  • 常用排序算法
    本博客将讲述常见的几种排序算法在日常码代码时,常常会用到排序,排序算法又有很多,每种排序都会有自己的特点和适用情况,我在这将总结几种排序算法,废话少说,开始!冒泡排序(bubblesort)冒泡排序,因像水泡一样一个接一个地冒出水面(排序),而得名。冒泡排序的思想是每次将最大的一次一次......
  • 云原生最佳实践系列 4:基于 MSE 和 SAE 的微服务部署与压测
    方案概述云原生应用平台为基于SpringCloud/Dubbo开发的微服务应用提供了完善的能力支撑,例如服务注册发现、Serverless无服务部署、实例弹性伸缩、微服务链路跟踪、全链路压力测试等,应用能够方便快捷的部署在阿里云上。阿里云原生产品完全兼容SpringCloud框架的主流版本......
  • 左手医生:医疗 AI 企业的云原生提效降本之路
    相信这样的经历对很多人来说并不陌生:为了能到更好的医院治病,不惜路途遥远奔波到大城市;或者只是看个小病,也得排上半天长队。这些由于医疗资源分配不均导致的就医问题已是老生长谈。云计算、人工智能、大数据等技术的发展和融合,让医疗行业的智能诊断不再是遥不可及的事情,近年来不少......
  • 选择排序的练习题及答案(共三种方式实现选择排序)
    习题1班级里五个人成绩比较升序排列,成绩分别为64,75,88,92,21packagexuanze;importjava.util.*;publicclasschapter1{ publicstaticvoidmain(String[]args){ //TODOAuto-generatedmethodstub Scannerscan=newScanner(System.in); intn=scan.nextInt......
  • 冒泡排序的习题全集(含答案)
    习题11.给定一个包含红色,白色和蓝色,共n个元素的数组nums,原地对他们进行排序,使得相同颜色的元素相邻,并按照共色,白色,蓝色顺序排列。我们使用整数0,1,2分别表示红色,白色,蓝色packagemaopao;importjava.util.*;publicclasschapter1{ publicstaticvoidmain(String[]ar......
  • Android原生ViewPager控件实现卡片翻动效果
    本文实例为大家分享了Android控件ViewPager实现卡片翻动效果的具体代码,供大家参考,具体内容如下先放一张效果图:想要实现这样的效果其实并不是太难,需要对ViewPager的一些细节属性更深入的了解和认识,下面介绍下一个小demo的实现过程:**第一步、**创建卡片viewpager适配器的i......
  • 八大排序——希尔排序
    希尔排序算法思想希尔排序核心思想就是:1,分组;2,直接插入排序:越有序越快希尔排序就是多次利用直接插入排序的一个排序算法.希尔排序的算法思想:间隔式分组,利用直接插入排序让组内有序,然后缩小分组再次排序,直到组数为1希尔排序的理论基础就是直接插入排序越有序越快;1......
  • 0. 基础环境,适用于手动安装
    0.基础环境,适用于手动安装虽然发行版不同,但是管理方式大多一致,以下未标注发行版,则为通用命令。Centos镜像:清华源根据官方指路,使用的2207,默认2009Rocky镜像:科大源Debian镜像:清华源Ubuntu镜像:清华源1.配置静态IP在系统安装时,可引导配置net.ifnames=0biosdevname=0​......
  • 基数排序详解
    基数排序详解一、基数排序的基本概念二、基数排序的特点二、基数排序的工作过程三、基数排序的伪代码四、基数排序的C语言代码示例五、基数排序的稳定性六、基数排序的优化与变体七、基数排序的应用场景八、结论在计算机科学中,排序算法是一种非常基础和重要的算法类型......