如何在js中动态创建的元素中处理事件



我想将click事件动态添加到创建的元素中,当用户点击按钮时,创建一些元素(下面代码中显示的元素(,而当用户点击名为remov的元素时,必须运行名为delion的函数,但这不起作用。我如何实现这一点?

我使用Vue js

methods: {
showinfo: function() {
db.collection("Studnets")
.get()
.then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
const student = document.createElement("tr");
const email = document.createElement("td");
email.innerText = doc.data().email;
const name = document.createElement("td");
name.innerText = doc.data().name;
const phone = document.createElement("td");
phone.innerText = doc.data().phone;
const stage = document.createElement("td");
stage.innerText = doc.data().stage;
const remov = document.createElement("button");
const pic = document.createElement("img");
pic.setAttribute("src","/dist/delete.svg?afdf9975229cdc15458e851b478bb6cb");
remov.classList.add("del");
//the problem
remov.addEventListener("click", this.deltion());
student.appendChild(email);
student.appendChild(name);
student.appendChild(phone);
student.appendChild(stage);
student.appendChild(remov);
remov.appendChild(pic);
document.getElementById("studentList").appendChild(student);
},
deltion: function(e) {
const rawStudent = e.target;
const raw = rawStudent.parentElement;
console.log(raw);
raw.remove();
}

您的代码有三个问题。

第一个问题:调用事件侦听器上的函数

当您注册事件侦听器时,您正在调用deltion(也许您的意思是delete:p(函数。

remov.addEventListener("click", this.deltion());

正确的形式是

remov.addEventListener("click", this.deltion);

因为您希望将函数体传递给事件侦听器,而不是函数结果。(如果您想调用该函数,可以将其封装在箭头函数中,但最后是一样的(。

第二个问题:这不是这个

如果你修复了第一个,你就会找到另一个(程序员的生活(this是js中的一个特殊关键字,this的上下文将根据调用方的不同而变化。

  1. showinfo被称为这个关键字指的是组件实例
  2. db.collection("Studnets"(.get((.then(function(querySnapshot({}(promise被调用,解析时它将调用具有querySnapshot参数的函数。**this**关键字上下文更改
  3. 使用foreach querySnapshot迭代集合。foreach(function(doc({}(**this**关键字上下文将再次更改

解决方案是使用箭头函数,这样就不会与父函数绑定。

db.collection("Studnets").get().then(querySnapshot => {
querySnapshot.data.forEach(doc => { 
// code
})
}) 

如果由于某种原因不能使用箭头函数,则可以添加一个变量";阴影";showinfo函数上的CCD_ 3关键字的上下文。

showinfo() {
const vm = this;
api.getStudentsCollection().then(function(querySnapshot) {
querySnapshot.data.forEach(function(doc) {
// setup code
remov.addEventListener("click", vm.deltion);
// setup code
});
});
}

第三个问题:单击箭头图像将删除按钮,但不会删除tr使用currentTarget而不是目标,目标是用户单击的元素,它可以是按钮内的任何元素,如图像,currentTarget是事件侦听器附加的元素,也就是按钮。

{
deltion: function(e) {
const rawStudent = e.currentTarget;
const raw = rawStudent.parentElement;
console.log(raw);
raw.remove();
}
}

未经请求的建议

Vue擅长其简单性和声明性代码。您可以像原始代码一样解决问题,但有一种更简单的方法可以让组件管理其状态

我用修复的原始版本和最简单的vue方式复制了您的代码(使用简单的空和加载状态切换(。希望你觉得它有用,并从中吸取教训。:(https://codesandbox.io/s/student-list-ammar-yasir-b5sxo?file=/src/App.vue

学习参考

  • https://javascript.info/
  • https://dev.to/cilvako/this-keyword-in-javascript-an-explanation-1con