在前端开发中,表格行内编辑、动态表单列表等场景经常需要监听输入框的值变化,并且把修改后的值同步到对应的对象数组中,保证数据和视图的一致性。下面我们就来一步步实现这个功能。

核心实现思路
要实现输入框值变化同步对象数组,核心分为三步:首先给每个输入框绑定对应的事件监听,其次在事件触发时获取输入框的最新值,最后根据输入框的标识找到对象数组中对应的元素,更新对应属性的值。
事件选择
常用的输入框监听事件有两种,适用场景不同:
- input事件:输入框内容每次变化都会触发,比如输入、删除、粘贴等操作,适合需要实时同步的场景。
- change事件:输入框失去焦点并且内容相比聚焦时有变化才会触发,适合不需要实时同步、希望用户完成输入后再更新的场景。
对象数组定位
我们可以在渲染输入框的时候,给输入框添加自定义属性,比如data-id用来标识对象数组中对应元素的唯一ID,data-field用来标识要更新的字段名,这样在事件回调中就能快速定位到目标数据。
完整代码示例
下面是一个简单的列表编辑场景的完整实现,每个列表项有名称和价格两个可编辑的输入框,修改后实时同步到对象数组:
// 初始对象数组
let dataList = [
{ id: 1, name: '商品A', price: 100 },
{ id: 2, name: '商品B', price: 200 },
{ id: 3, name: '商品C', price: 300 }
];
// 渲染列表到页面
function renderList() {
const container = document.getElementById('listContainer');
container.innerHTML = '';
dataList.forEach(item => {
const div = document.createElement('div');
div.className = 'list-item';
div.innerHTML = `
<span>ID: ${item.id}</span>
<input type="text" value="${item.name}" data-id="${item.id}" data-field="name" class="edit-input">
<input type="number" value="${item.price}" data-id="${item.id}" data-field="price" class="edit-input">
`;
container.appendChild(div);
});
// 绑定事件监听
bindInputEvents();
}
// 绑定输入框事件
function bindInputEvents() {
const inputs = document.querySelectorAll('.edit-input');
inputs.forEach(input => {
// 使用input事件实时同步
input.addEventListener('input', function(e) {
const target = e.target;
const id = Number(target.dataset.id);
const field = target.dataset.field;
const value = field === 'price' ? Number(target.value) : target.value;
// 找到对象数组中对应的元素并更新
const targetItem = dataList.find(item => item.id === id);
if (targetItem) {
targetItem[field] = value;
console.log('更新后的对象数组:', dataList);
}
});
});
}
// 初始化渲染
renderList();配套HTML结构
页面中只需要一个容器元素即可:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>输入框同步对象数组示例</title>
<style>
.list-item {
margin: 10px 0;
padding: 10px;
border: 1px solid #eee;
}
.edit-input {
margin: 0 10px;
padding: 5px;
}
</style>
</head>
<body>
<div id="listContainer"></div>
<script src="index.js"></script>
</body>
</html>注意事项
实际开发中需要注意几个问题:
- 如果对象数组是响应式数据(比如Vue、React中的状态),直接修改数组元素可能不会触发视图更新,需要遵循对应框架的更新规则,比如Vue2需要用
Vue.set或者替换整个数组,React需要通过setState更新状态。 - 如果输入框是动态新增的,需要在新增后重新绑定事件,或者使用事件委托的方式,把事件绑定到父容器上,避免事件丢失。
- 输入值的类型需要根据字段要求做转换,比如价格字段需要转成数字类型,避免存成字符串导致后续计算出错。
事件委托的实现方式可以参考下面的代码,不需要每次新增元素后重新绑定事件:
// 事件委托方式绑定,父容器监听input事件
document.getElementById('listContainer').addEventListener('input', function(e) {
const target = e.target;
// 判断触发事件的是不是编辑输入框
if (target.classList.contains('edit-input')) {
const id = Number(target.dataset.id);
const field = target.dataset.field;
const value = field === 'price' ? Number(target.value) : target.value;
const targetItem = dataList.find(item => item.id === id);
if (targetItem) {
targetItem[field] = value;
console.log('更新后的对象数组:', dataList);
}
}
});