HTML table鼠标拖拽排序功能

yizhihongxing

下面是关于"HTML table鼠标拖拽排序功能"的完整攻略。

一、原理说明

在HTML表格中添加鼠标拖拽排序功能,本质上是通过监听鼠标在表格中的操作事件,动态调整表格中行或列的位置。

其中,主要的步骤可以分为以下几点:

  1. 监听鼠标操作事件,包括鼠标按下、鼠标移动、鼠标松开等事件;
  2. 在鼠标按下时,记录当前鼠标所在行或列的位置信息,包括其所在的表格、行或列号,以及点击时相对于其左上角的偏移量;
  3. 在鼠标移动时,根据鼠标当前的位置信息,计算出相对于按下时的偏移量,然后动态调整表格中行或列的位置;
  4. 在鼠标松开时,更新表格的行或列顺序,同时移除拖拽过程中添加的样式和事件监听。

二、示例说明

1. 示例一:拖拽排序表格行

下面是一个简单的示例,演示如何在HTML表格中添加拖拽排序表格行的功能。

<table>
  <thead>
    <tr>
      <th>姓名</th>
      <th>性别</th>
      <th>年龄</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>小明</td>
      <td>男</td>
      <td>18</td>
    </tr>
    <tr>
      <td>小红</td>
      <td>女</td>
      <td>20</td>
    </tr>
    <tr>
      <td>小刚</td>
      <td>男</td>
      <td>22</td>
    </tr>
  </tbody>
</table>

实现步骤如下:

  1. 通过JavaScript代码,遍历表格中的每个行元素,设置鼠标按下、移动和松开事件监听器;
  2. 在鼠标按下时,记录当前行的信息,包括其当前的位置、所在的表格、行数和鼠标相对于其左上角的偏移量;
  3. 在鼠标移动时,更新当前拖拽行的位置,同时检测是否需要交换位置;
  4. 在鼠标松开时,更新表格的行顺序,同时移除拖拽过程中添加的样式和事件监听。

具体实现方式可以参考下面的代码示例:

// 获取表格元素
const table = document.querySelector('table');

// 获取所有行元素
const rows = table.querySelectorAll('tr');

// 记录拖拽行的信息
let dragRow = null;
let dragY = 0;
let targetRow = null;

// 遍历所有行元素
rows.forEach((row, index) => {
  // 设置鼠标按下事件监听
  row.addEventListener('mousedown', (event) => {
    // 记录鼠标按下时的偏移量
    dragY = event.clientY - row.getBoundingClientRect().top;
    // 记录拖拽行的信息
    dragRow = {
      table: table,
      rowNum: index,
      top: row.getBoundingClientRect().top,
      height: row.getBoundingClientRect().height,
      y: event.clientY - row.getBoundingClientRect().top
    };
    // 添加样式
    row.style.opacity = '0.5';
    row.style.position = 'absolute';
    row.style.top = dragRow.top + 'px';
    row.style.left = row.getBoundingClientRect().left + 'px';
    // 阻止事件冒泡
    event.stopPropagation();
  });

  // 设置鼠标移动事件监听
  row.addEventListener('mousemove', (event) => {
    if (dragRow === null) return;
    // 计算偏移量
    const offset = event.clientY - dragRow.y - dragRow.top;
    // 移动行
    row.style.top = (dragRow.top + offset) + 'px';
    // 计算目标行
    targetRow = null;
    rows.forEach((r, i) => {
      if (i === dragRow.rowNum) return;
      const top = r.getBoundingClientRect().top + r.getBoundingClientRect().height / 2;
      if (event.clientY >= top) {
        targetRow = {
          table: table,
          rowNum: i,
          top: top,
          height: r.getBoundingClientRect().height
        };
      }
    });
  });

  // 设置鼠标松开事件监听
  row.addEventListener('mouseup', (event) => {
    if (dragRow === null) return;
    if (targetRow !== null) {
      // 交换位置
      const target = rows[targetRow.rowNum];
      target.parentNode.insertBefore(row, target);
      target.parentNode.insertBefore(target, rows[dragRow.rowNum + 1]);
    }
    // 移除样式
    row.style.opacity = '1';
    row.style.position = '';
    row.style.top = '';
    row.style.left = '';
    // 清除记录
    dragRow = null;
    targetRow = null;
  });

  // 设置鼠标松开事件监听
  row.addEventListener('mouseleave', (event) => {
    if (dragRow === null) return;
    // 更新目标行为最后一行
    targetRow = {
      table: table,
      rowNum: rows.length - 1,
      top: rows[rows.length - 1].getBoundingClientRect().bottom,
      height: rows[rows.length - 1].getBoundingClientRect().height
    };
    // 更新位置
    row.style.top = (targetRow.top - row.getBoundingClientRect().height) + 'px';
  });
});

2. 示例二:拖拽排序表格列

除了拖拽排序表格行,我们也可以通过类似的方式实现拖拽排序表格列的功能。下面是一个示例代码,演示如何实现该功能。

<table>
  <thead>
    <tr>
      <th>姓名</th>
      <th>性别</th>
      <th>年龄</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>小明</td>
      <td>男</td>
      <td>18</td>
    </tr>
    <tr>
      <td>小红</td>
      <td>女</td>
      <td>20</td>
    </tr>
    <tr>
      <td>小刚</td>
      <td>男</td>
      <td>22</td>
    </tr>
  </tbody>
</table>

实现步骤如下:

  1. 在表头中的每个列元素上添加鼠标按下、移动和松开事件监听器;
  2. 在鼠标按下时,记录当前列的信息,包括其当前的位置、所在的表格、列数和鼠标相对于其左上角的偏移量;
  3. 在鼠标移动时,更新当前拖拽列的位置,同时检测是否需要交换位置;
  4. 在鼠标松开时,更新表格的列顺序,同时移除拖拽过程中添加的样式和事件监听器。

具体实现方式可以参考下面的代码示例:

// 获取表格元素
const table = document.querySelector('table');

// 获取表头中每个列元素
const headers = table.querySelectorAll('thead th');

// 记录拖拽列的信息
let dragCol = null;
let dragX = 0;
let targetCol = null;

// 遍历所有列元素
headers.forEach((col, index) => {
  // 设置鼠标按下事件监听
  col.addEventListener('mousedown', (event) => {
    // 记录鼠标按下时的偏移量
    dragX = event.clientX - col.getBoundingClientRect().left;
    // 记录拖拽列的信息
    dragCol = {
      table: table,
      colNum: index,
      left: col.getBoundingClientRect().left,
      width: col.getBoundingClientRect().width,
      x: event.clientX - col.getBoundingClientRect().left
    };
    // 添加样式
    col.style.opacity = '0.5';
    col.style.position = 'absolute';
    col.style.left = dragCol.left + 'px';
    col.style.top = col.getBoundingClientRect().top + 'px';
    // 设置列宽度
    table.querySelectorAll('col')[index].style.width = dragCol.width + 'px';
    // 阻止事件冒泡
    event.stopPropagation();
  });

  // 设置鼠标移动事件监听
  col.addEventListener('mousemove', (event) => {
    if (dragCol === null) return;
    // 计算偏移量
    const offset = event.clientX - dragCol.x - dragCol.left;
    // 移动列
    col.style.left = (dragCol.left + offset) + 'px';
    // 计算目标列
    targetCol = null;
    headers.forEach((c, i) => {
      if (i === dragCol.colNum) return;
      const left = c.getBoundingClientRect().left + c.getBoundingClientRect().width / 2;
      if (event.clientX >= left) {
        targetCol = {
          table: table,
          colNum: i,
          left: left,
          width: c.getBoundingClientRect().width
        };
      }
    });
  });

  // 设置鼠标松开事件监听
  col.addEventListener('mouseup', (event) => {
    if (dragCol === null) return;
    if (targetCol !== null) {
      // 交换位置
      const target = headers[targetCol.colNum];
      target.parentNode.insertBefore(col, target);
      const cols = table.querySelectorAll('tr td:nth-child(' + (dragCol.colNum + 1) + ')');
      cols.forEach((cell, index) => {
        const target = target.parentNode.querySelectorAll('td:nth-child(' + (targetCol.colNum + 1) + ')')[index];
        target.parentNode.insertBefore(cell, target);
      });
      table.querySelectorAll('col')[dragCol.colNum].style.width = targetCol.width + 'px';
      table.querySelectorAll('col')[targetCol.colNum].style.width = dragCol.width + 'px';
    }
    // 移除样式
    col.style.opacity = '1';
    col.style.position = '';
    col.style.left = '';
    col.style.top = '';
    // 清除记录
    dragCol = null;
    targetCol = null;
  });

  // 设置鼠标松开事件监听
  col.addEventListener('mouseleave', (event) => {
    if (dragCol === null) return;
    // 更新目标列为最后一列
    targetCol = {
      table: table,
      colNum: headers.length - 1,
      left: headers[headers.length - 1].getBoundingClientRect().right,
      width: headers[headers.length - 1].getBoundingClientRect().width
    };
    // 更新位置
    col.style.left = targetCol.left - col.getBoundingClientRect().width + 'px';
  });
});

三、总结

HTML table鼠标拖拽排序功能的实现有很多种方式,上面的示例只是其中的一种。在实际开发中,需结合实际情况进行应用。另外,在实现时,需要注意操作的流畅性和界面的美观度。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:HTML table鼠标拖拽排序功能 - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • css3发光搜索表单分享

    CSS3发光搜索表单分享是一种简单而有趣的CSS3特效,可以为搜索表单增加闪亮的发光效果,提高用户体验和网站的视觉吸引力。以下是攻略的详细说明: 确定HTML结构 首先,需要在HTML中添加一个搜索表单的结构,例如: <form> <input type="text" placeholder="Search..…

    css 2023年6月11日
    00
  • 分享30个新鲜的CSS3打造的精美绚丽效果(附演示下载)

    关于“分享30个新鲜的CSS3打造的精美绚丽效果(附演示下载)”的完整攻略,可以分为以下几个部分进行说明: 标题 首先,需要给这篇攻略一个合适的标题,比如:“CSS3实现精美炫酷效果的30个案例分享及代码解析”,这样可以更好地表达文章的主题和内容。 简介 接下来需要写一份简介,简要介绍一下这篇攻略的内容和意义,比如:“本篇攻略将分享30个采用CSS3技术实现…

    css 2023年6月10日
    00
  • js点击按钮实现水波纹效果代码(CSS3和Canves)

    JS点击按钮实现水波纹效果是一种很炫酷的UI效果,可以为网站增加动态和交互的效果,本文将详细讲解实现这种效果的完整攻略。实现方法有两种,分别是使用CSS3和使用Canvas。 CSS3 实现 js 点击按钮水波纹效果 HTML 结构 首先需要在HTML文件中添加一个按钮,如下所示: <button class="wave-button&quo…

    css 2023年6月10日
    00
  • 响应式网页设计的快速教程(适合个人站点)

    响应式网页设计是一种能够自适应不同设备屏幕大小的网页设计技术。本文将详细讲解响应式网页设计的完整攻略,包括使用 CSS3 媒体查询、使用 Bootstrap 框架等方法。 1. 使用 CSS3 媒体查询 CSS3 媒体查询是一种根据设备特性(如屏幕大小、分辨率、方向等)来应用不同样式的技术。可以使用 CSS3 媒体查询来实现响应式网页设计。具体步骤如下: 1…

    css 2023年5月18日
    00
  • 利用css设置元素垂直居中的解决方法汇总

    下面我将详细讲解如何利用 CSS 设置元素垂直居中的解决方法汇总。 什么是垂直居中 在 CSS 中,垂直居中指的是将一个元素在垂直方向上居中对齐。垂直居中比较常用的场景包括父元素和子元素高度不一致、子元素固定高度等。 方法一:利用 flexbox 利用 Flexbox 布局可以非常简单地实现垂直居中。首先需要设定父元素的 display 属性为 flex,然…

    css 2023年6月10日
    00
  • PHP模板引擎Smarty自定义变量调解器用法

    下面是关于PHP模板引擎Smarty自定义变量调解器用法的详细攻略。 什么是Smarty模板引擎? Smarty是一款开源的基于PHP的模板引擎,它允许开发者在PHP脚本内部定义并使用模板,从而将业务逻辑与视图分离。Smarty模板引擎使用标记语言,可以轻松的在模板中引用变量,实现数据与视图的分离。 什么是Smarty自定义变量调解器? Smarty的自定义…

    css 2023年6月9日
    00
  • 深入理解CSS height属性设置元素的高度

    深入理解CSS height属性设置元素的高度 在CSS中,height属性用于设置元素的高度,可以应用于大部分的HTML元素。 基本语法 element { height: value; } 其中,value可以是具体的数值,也可以是百分比。 数值作为height属性值 数值可以作为height属性值,可以用像素(px)、点(pt)、厘米(cm)、英寸(i…

    css 2023年6月9日
    00
  • css3动画效果小结(推荐)

    对于“css3动画效果小结(推荐)”这一话题,以下是详细的攻略: 1. 前置知识 在学习和实践 CSS3 动画效果之前,需要掌握一些基本的前端知识,包括但不限于: HTML 和 CSS 的基本语法和使用方法 DOM 结构和节点的概念 CSS 中的选择器和优先级 CSS 盒模型和布局 CSS3 中新特性的概念和用法 同时也需要了解一些与动画相关的 CSS 属性…

    css 2023年6月9日
    00
合作推广
合作推广
分享本页
返回顶部