目录
要求:
(1)页面中的数据表格通常承载了用户所需的数据,通常用户需要根据实际
情况对部分数据进行修改。
(2)当点击表格中可编辑数据时,在当前单元格中显示文本框并在其中显示
原数据,从而为用户提供修改该数据的输入域。
(a)在编辑模式下点击文本框之外的任何区域即可确认输入。
(b)在编辑模式下输入数据不符合要求时,应该给出适当的提示,并强制
改正后方可确认输入。
实现思路:
- 为表格中可编辑列的单元格添加 click 事件监听器;
- 在事件处理函数中,获取单元格中的原数据,并将其替换为一个文本框;
- 在文本框中显示原数据,并为其添加 blur 事件监听器;
- 在 blur 事件处理函数中,获取文本框中的新数据,并进行验证;
- 如果新数据符合验证规则,则更新单元格中的数据,并将文本框替换为新数据;
- 如果新数据不符合验证规则,则给出适当的提示,并保留文本框以便用户修改。
表单数据:
<table id="editable-table">
<thead>
<tr>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>邮箱</th>
</tr>
</thead>
<tbody>
<tr>
<td class="editable">张三</td>
<td class="editable">18</td>
<td>男</td>
<td class="editable">zhangsan@example.com</td>
</tr>
<tr>
<td class="editable">李四</td>
<td class="editable">20</td>
<td>女</td>
<td class="editable">lisi@example.com</td>
</tr>
<tr>
<td class="editable">王五</td>
<td class="editable">22</td>
<td>男</td>
<td class="editable">wangwu@example.com</td>
</tr>
</tbody>
</table>
逻辑代码:
function makeEditable(tableId, config) {
// 默认配置
const defaultConfig = {
editableColumns: [], // 可编辑列的下标(从 0 开始)
validationRules: {}, // 验证规则
style: {} // 样式
};
// 合并配置
const mergedConfig = Object.assign(defaultConfig, config);
// 获取表格元素
const table = document.getElementById(tableId);
// 获取表头和表体
const thead = table.querySelector('thead');
const tbody = table.querySelector('tbody');
// 获取所有可编辑单元格
const editableCells = Array.from(tbody.querySelectorAll('.editable'));
// 为每个可编辑单元格添加 click 事件监听器
editableCells.forEach(cell => {
cell.addEventListener('click', () => {
// 获取单元格中的原数据
const originalData = cell.textContent;
// 创建一个文本框
const input = document.createElement('input');
// 设置文本框的初始值为原数据
input.value = originalData;
// 将文本框插入到单元格中
cell.textContent = '';
cell.appendChild(input);
// 设置文本框的样式
Object.assign(input.style, mergedConfig.style.input);
// 为文本框添加 blur 事件监听器
input.addEventListener('blur', () => {
// 获取文本框中的新数据
const newData = input.value;
// 获取单元格的下标
const cellIndex = Array.from(cell.parentElement.children).indexOf(cell);
// 判断单元格是否可编辑
if (mergedConfig.editableColumns.includes(cellIndex)) {
// 获取验证规则
const validationRule = mergedConfig.validationRules[cellIndex];
// 验证新数据是否符合规则
if (validationRule && !validationRule.test(newData)) {
// 不符合规则,给出提示
alert('输入的数据不符合要求,请重新输入!');
// 保留文本框
input.focus();
} else {
// 符合规则,更新单元格中的数据
cell.textContent = newData;
}
} else {
// 单元格不可编辑,直接更新数据
cell.textContent = newData;
}
});
// 让文本框获得焦点
input.focus();
});
});
}
样例测试:
makeEditable('editable-table', {
editableColumns: [1, 3], // 年龄和邮箱列可编辑
validationRules: {
1: /^\d+$/, // 年龄必须是数字
3: /^.+@.+\..+$/ // 邮箱必须符合格式要求
},
style: {
input: {
width: '100%',
boxSizing: 'border-box',
padding: '4px',
border: '1px solid #ccc',
borderRadius: '4px'
}
}
});
效果图: