返回
拖动表格头:实现代码如何编写?
前端
2023-11-16 03:06:04
实现拖动表格头功能的步骤:
- 准备 HTML 结构:
<table>
<thead>
<tr>
<th data-field="name">姓名</th>
<th data-field="age">年龄</th>
<th data-field="city">城市</th>
</tr>
</thead>
<tbody>
<tr>
<td>张三</td>
<td>20</td>
<td>北京</td>
</tr>
<tr>
<td>李四</td>
<td>25</td>
<td>上海</td>
</tr>
<tr>
<td>王五</td>
<td>30</td>
<td>广州</td>
</tr>
</tbody>
</table>
- 添加必需的 CSS 样式:
table {
width: 100%;
border-collapse: collapse;
}
th {
padding: 5px 10px;
text-align: center;
cursor: pointer;
}
th.active {
background-color: #ccc;
}
.drag-indicator {
position: absolute;
top: 0;
left: 0;
width: 1px;
height: 100%;
background-color: #ccc;
opacity: 0;
}
- 编写 JavaScript 代码:
// 获取表格元素
const table = document.querySelector('table');
// 获取表头元素
const headers = table.querySelectorAll('th');
// 为每个表头元素添加事件监听器
headers.forEach(header => {
header.addEventListener('mousedown', startDrag);
});
// 开始拖动表头元素的函数
function startDrag(e) {
// 获取被拖动的表头元素
const header = e.target;
// 获取被拖动的表头元素的字段名称
const field = header.dataset.field;
// 创建拖动指示器元素
const dragIndicator = document.createElement('div');
dragIndicator.classList.add('drag-indicator');
// 将拖动指示器元素添加到表格中
table.appendChild(dragIndicator);
// 获取拖动指示器元素的宽度
const dragIndicatorWidth = dragIndicator.offsetWidth;
// 获取拖动指示器元素的高度
const dragIndicatorHeight = dragIndicator.offsetHeight;
// 获取被拖动的表头元素的宽度
const headerWidth = header.offsetWidth;
// 获取被拖动的表头元素的高度
const headerHeight = header.offsetHeight;
// 获取被拖动的表头元素的偏移量
const headerOffset = header.getBoundingClientRect();
// 获取表格的偏移量
const tableOffset = table.getBoundingClientRect();
// 计算拖动指示器元素的初始位置
const dragIndicatorX = headerOffset.left - tableOffset.left + headerWidth;
const dragIndicatorY = headerOffset.top - tableOffset.top + headerHeight;
// 设置拖动指示器元素的初始位置
dragIndicator.style.left = dragIndicatorX + 'px';
dragIndicator.style.top = dragIndicatorY + 'px';
// 设置拖动指示器元素的宽度
dragIndicator.style.width = dragIndicatorWidth + 'px';
// 设置拖动指示器元素的高度
dragIndicator.style.height = dragIndicatorHeight + 'px';
// 设置拖动指示器元素的透明度
dragIndicator.style.opacity = 1;
// 鼠标移动事件的监听器
document.addEventListener('mousemove', drag);
// 鼠标抬起事件的监听器
document.addEventListener('mouseup', endDrag);
// 拖动表头元素的函数
function drag(e) {
// 获取鼠标的当前位置
const mouseX = e.clientX;
const mouseY = e.clientY;
// 计算拖动指示器元素的当前位置
const dragIndicatorX = mouseX - tableOffset.left - dragIndicatorWidth / 2;
const dragIndicatorY = mouseY - tableOffset.top - dragIndicatorHeight / 2;
// 设置拖动指示器元素的当前位置
dragIndicator.style.left = dragIndicatorX + 'px';
dragIndicator.style.top = dragIndicatorY + 'px';
// 获取所有表头元素
const allHeaders = table.querySelectorAll('th');
// 找到拖动指示器元素所在的表头元素
let headerElement = null;
for (let i = 0; i < allHeaders.length; i++) {
const header = allHeaders[i];
const headerOffset = header.getBoundingClientRect();
if (dragIndicatorX + dragIndicatorWidth / 2 >= headerOffset.left && dragIndicatorX + dragIndicatorWidth / 2 <= headerOffset.right) {
headerElement = header;
break;
}
}
// 如果拖动指示器元素所在的表头元素不是被拖动的表头元素,则交换两个表头元素的位置
if (headerElement && headerElement !== header) {
const headerField = header.dataset.field;
header.dataset.field = headerElement.dataset.field;
headerElement.dataset.field = headerField;
const headerIndex = Array.from(headers).indexOf(header);
const headerElementIndex = Array.from(headers).indexOf(headerElement);
headers[headerIndex] = headerElement;
headers[headerElementIndex] = header;
// 重新渲染表格
table.innerHTML = '';
renderTable();
}
}
// 结束拖动表头元素的函数
function endDrag(e) {
// 移除拖动指示器元素
dragIndicator.parentNode.removeChild(dragIndicator);
// 移除鼠标移动事件的监听器
document.removeEventListener('mousemove', drag);
// 移除鼠标抬起事件的监听器
document.removeEventListener('mouseup', endDrag);
}
}
// 渲染表格
function renderTable() {
const tableBody = table.querySelector('tbody');
// 获取所有数据行
const rows = tableBody.querySelectorAll('tr');
// 排序数据行
rows.sort((a, b) => {
const field = a.querySelector('th[data-field]').dataset.field;
const aValue = a.querySelector(`td[data-field="${field}"]`).textContent;
const bValue = b.querySelector(`td[data-field="${field}"]`).textContent;
if (aValue < bValue) {
return -1;
} else if (aValue > bValue) {
return 1;
} else {
return 0;
}
});
// 将排序后的数据行添加到表格中
for (let i = 0; i < rows.length; i++) {
tableBody.appendChild(rows[i]);
}
}
// 调用渲染表格函数
renderTable();
通过以上步骤,您就可以实现表格头拖动排序的功能。希望本指南对您有所帮助。