HTML table鼠标拖拽排序功能

下面是关于"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实现酷炫的3D旋转透视效果

    关于“CSS3实现酷炫的3D旋转透视效果”的完整攻略,我给你详细讲解一下。 1. 理解3D变换 在介绍具体实现之前,我们首先需要理解3D变换。CSS3提供了四种基本的3D变换操作,包括平移(translate)、旋转(rotate)、缩放(scale)和矩阵变换(matrix)。这些变换可以分别应用于三个坐标轴:X轴、Y轴和Z轴。在使用3D变换时,需要注意的…

    css 2023年6月10日
    00
  • webpack 5.68.0版本教程示例详解

    webpack 5.68.0版本教程示例详解 什么是 webpack? Webpack 是一个模块化打包工具,它主要用于将应用程序所需的各种文件(例如 HTML、CSS、JavaScript、图片等)打包成一个或多个静态资源,以便于部署和运行。 Webpack 基础 Webpack 能够将项目中的模块(Module)打包成一个或多个 bundle,适用于各种…

    css 2023年6月9日
    00
  • AJAX实现瀑布流布局

    下面我将提供关于“AJAX实现瀑布流布局”的完整攻略,包含以下几个步骤: 步骤1:了解瀑布流布局 瀑布流布局是一种流式布局方式,在页面中按照列来展示数据。该布局的特点是: 每一列宽度相同,高度不同; 每一列数据按照从上到下,从左到右的顺序依次排列; 数据加载时通过 AJAX 异步请求,实现数据的无限滚动加载。 步骤2:布局HTML和CSS 在HTML中,我们…

    css 2023年6月11日
    00
  • css中padding和margin的异同点介绍

    CSS中padding和margin的异同点介绍 概念介绍 被称为“内边距”,padding是指元素内容边界与元素边框之间的距离。它会影响到元素的大小及内容与边框之间的间距。 被称为“外边距”,margin是指元素边框与相邻元素边框之间的距离。它会影响到元素与其他元素之间的间距。 使用方式 padding和margin可以通过简写属性和分别指定属性的方式进行…

    css 2023年6月9日
    00
  • CSS毛玻璃效果如何实现

    CSS毛玻璃效果如何实现 CSS毛玻璃效果是一种模糊的视觉效果,可以使图像或背景看起来更加柔和和模糊。本攻略将介绍两种实现CSS毛玻璃效果的方法,包括使用CSS滤镜和使用背景图像。 使用CSS滤镜 CSS滤镜是一种CSS属性,可以对元素应用各种视觉效果,包括模糊、颜色调整、亮度调整等。使用CSS滤镜可以轻松实现CSS毛玻璃效果。例如: .blur { bac…

    css 2023年5月18日
    00
  • CSS框架的利与弊(下)

    以下是详细讲解“CSS框架的利与弊(下)”的完整攻略: 什么是CSS框架 CSS框架是一种前端开发工具,它提供了一系列的CSS样式和布局模板,方便开发者快速的搭建网站及应用程序的UI界面。一般而言,CSS框架包括了CSS的基本样式和一些常用的组件,比如按钮、表格等等。 CSS框架的利与弊 利 快速开发:CSS框架提供了通用的样式和布局模板,使得开发者不必在每…

    css 2023年6月9日
    00
  • 可以浮动某个物体的jquery控件用法实例

    浮动某个物体的jquery控件通常称为”Sticky”,它可以让你的页面上的元素固定在页面的某个位置,用户可以在页面上进行滚动但是该元素仍然会保持在原位。这个特性在设计某些页面元素时非常有用,如导航栏或悬浮广告等。下面是使用jquery控件实现Sticky的详细过程。 步骤一:引入必要的库文件与CSS 首先,在你的HTML文件中引入必要的jquery库文件和…

    css 2023年6月10日
    00
  • CSS样式表与格式布局详解

    CSS样式表与格式布局详解 CSS(Cascading Style Sheets)是一种用于控制网页样式和布局的语言。本攻略将详细讲解CSS样式表的基本语法、选择器、盒模型、格式布局、浮动、定位、响应式设计等内容。 CSS样式表的基本语法 CSS样式表由选择器和声明块组成。选择器用于选择应用样式的HTML元素,声明块由一组属性和值组成,用于定义元素的样式。例…

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