Javascript 为多个事件配置同一按钮
我在我的web应用程序中有一个表单按钮(纯用Vanilla Js制作),表单用于从用户那里获取数据,当单击该按钮时,数据将进入HTML表,以此类推 要编辑表格行,我已在表格列(每行)上放置了“编辑”按钮,下面附上的图片将有助于获得清晰的想法: 蓝色提交按钮命名为“addButton”,当用户点击表中特定行的“Edit”时,相应的数据显示在输入字段中,用户可以填写新的详细信息 到目前为止一切正常,现在真正的问题开始了:在用户编辑输入字段中的信息后,蓝色的提交按钮用于保存这些更改,并自动在表中显示更改。(这是必需的行为) 相反,所发生的情况是:表中显示修改后的行,行中生成一个具有相同详细信息的新条目(“addButton”事件侦听器执行两次,一次用于保存用户所做的更改,一次用于在行中添加新项) 我已经放置了两次此事件侦听器(相同的名称,因为我不想使用单独的按钮来保存已编辑的信息)。 为清晰起见,请查看代码: (这是全局范围内的第一个addButton事件侦听器-用于向表中添加新条目) 对于第行中的“编辑和删除”按钮,我有:Javascript 为多个事件配置同一按钮,javascript,dom-events,Javascript,Dom Events,我在我的web应用程序中有一个表单按钮(纯用Vanilla Js制作),表单用于从用户那里获取数据,当单击该按钮时,数据将进入HTML表,以此类推 要编辑表格行,我已在表格列(每行)上放置了“编辑”按钮,下面附上的图片将有助于获得清晰的想法: 蓝色提交按钮命名为“addButton”,当用户点击表中特定行的“Edit”时,相应的数据显示在输入字段中,用户可以填写新的详细信息 到目前为止一切正常,现在真正的问题开始了:在用户编辑输入字段中的信息后,蓝色的提交按钮用于保存这些更改,并自动在表中显示
modifyBtn
绑定到表,所以我可以用它来获得click target
(存在第二个addButton事件侦听器,用于保存更改并在表中显示输出)
因此,在编辑之后,当用户单击蓝色提交按钮时,我只希望执行addButton
事件侦听器中的modifyBtn
事件侦听器,
当前正在执行两个
addButton
事件侦听器。很抱歉解释得太多。正如您可能知道的,问题在于您正在同时将多个单击侦听器分配给同一元素(您想要的行为)(您不想要的行为)。有几种方法可以解决这个问题
最快的修复 解决问题的最快方法是使用。这样,在创建设置编辑数据的第二个单击侦听器之前,可以删除上一个单击侦听器(向
info
数组添加新元素的侦听器)
在第二个click listener函数结束时,您将再次绑定第一个click listener,使行为恢复正常
此解决方案的优点
.removeEventListener(“单击”,listenerFunction)
。由于您当前使用的是,您必须将当前在单击侦听器中的函数移动到其他位置,并将其命名(这样您就可以将它们传递给removeEventListener
函数addButton
addButton
的函数声明移到.addEventListener
之外,并为其命名。我已将其命名为addItemClickHandler
,但您可以随意调用它:
function addItemClickHandler(e) {
var obj = {
id : object.count,
date : formatDate(inDate.value, inMonth.value),
day : inDay.value,
item : inItem.value,
price : parseInt(inPrice.value),
};
object.info.push(obj);
object.count += 1;
refreshDOM();
}
addButton.addEventListener("click", addItemClickHandler);
这应该是完全相同的。现在我们需要将第二个事件侦听器函数移动到它自己的命名函数中。因为我们只是从函数本身内部引用该函数的名称,我们甚至不需要将其移出,只需给它一个名称。我将给它一个editItemClickHandler
:
addButton.removeEventListener("click", addItemClickHandler);
addButton.addEventListener("click", function editItemClickHandler(e){
object.info[eindex]['day'] = inDay.value;
object.info[eindex]['date'] = formatDate(inDate.value, inMonth.value);
object.info[eindex]['item'] = inItem.value;
object.info[eindex]['price'] = parseInt(inPrice.value);
refreshDOM();
addButton.removeEventListener("click", editItemClickHandler);
addButton.addEventListener("click", addItemClickHandler);
});
- 如您所见,我们首先删除侦听器
,这样当您单击“添加”按钮时,它就不会做任何事情addItemClickHandler
- 然后我们绑定一个不同的click listener,我们给它命名为
,这样我们可以在编辑完成后删除它editItemClickHandler
- 我们做了所有需要做的编辑
- 最后,我们删除了我们创建的新的编辑点击监听器,并重新添加了原始的点击监听器,使功能恢复正常
更健壮的修复 上面的解决方案是解决问题的最快方法,但还有更可靠的方法来确保解决方案的有效性。在这个解决方案中,我将整理一些代码,使其更清晰、更易于理解 此解决方案的优点
对象
的正下方创建一个名为编辑
的对象:
var editing = {
mode: false,
index: null
};
这将使我们能够跟踪是否正在编辑任何内容(editing.mode
),以及正在编辑的项目的索引是什么(editing.index
)
步骤2:更新addButton
事件侦听器以使用编辑对象
接下来,我们需要修改我们的addButton.addEventListener
以使用这个新的编辑对象:
addButton.addEventListener("click", function(e){
if (editing.mode) {
var info = object.info[editing.index];
info['day'] = inDay.value;
info['date'] = formatDate(inDate.value, inMonth.value);
info['item'] = inItem.value;
info['price'] = parseInt(inPrice.value);
editing.mode = false;
} else {
var obj = {
id : object.count,
date : formatDate(inDate.value, inMonth.value),
day : inDay.value,
item : inItem.value,
price : parseInt(inPrice.value),
};
object.info.push(obj);
object.count += 1;
}
refreshDOM();
});
- 如果
editing.mode
为true
,当单击add按钮
时,它将更新值,然后禁用editing.mode
,使其恢复到以前的状态
- 如果
editing.mode
为false
,则只需将该项添加到数组中(与之前的代码相同)
- 无论发生什么情况,DOM都将被刷新
步骤3:更新modifyBtn
事件侦听器以使用编辑
ob
var editing = {
mode: false,
index: null
};
addButton.addEventListener("click", function(e){
if (editing.mode) {
var info = object.info[editing.index];
info['day'] = inDay.value;
info['date'] = formatDate(inDate.value, inMonth.value);
info['item'] = inItem.value;
info['price'] = parseInt(inPrice.value);
editing.mode = false;
} else {
var obj = {
id : object.count,
date : formatDate(inDate.value, inMonth.value),
day : inDay.value,
item : inItem.value,
price : parseInt(inPrice.value),
};
object.info.push(obj);
object.count += 1;
}
refreshDOM();
});
<td><a href="#" data-id={{id}} data-action="edit">Edit</a> | <a href="#" data-id={{id}} data-action="delete">Delete</a></td>
modifyBtn.addEventListener('click', function(e){
e.preventDefault();
var el = e.target;
var id = parseInt(el.dataset.id);
var index = object.info.findIndex(item => item.id === id);
var info = object.info[index];
var action = el.dataset.action;
if (action === "edit") {
editing.mode = true;
editing.index = index;
inDay.value = info['day'];
inDate.value = parseInt(info['date'].substr(0,2));
inMonth.value = info["date"].substr(4);
inItem.value = info['item'];
inPrice.value = info['price'];
}
if (action === "delete") {
object.info.splice(index, 1);
}
refreshDOM();
});
<h2 id="form-header">Add Item</h2>
formHeader = getElement('form-header');
formHeader.textContent = editing.mode ? "Edit Item" : "Add Item";