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

How to handle events in dynamically created elements in js

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

I use 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();
     }

您的代码存在三个问题。

第一期:在事件侦听器上调用函数

你在注册事件侦听器时正在调用删除(也许你的意思是删除:P)函数。

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

正确的形式是

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

因为你要将函数体传递给事件监听器,而不是函数结果。 (如果要调用函数可以用箭头函数包裹起来,但最后还是一样)。

第二期:这不是

如果你修好了第一个,你会发现另一个(程序员的生活)。 this是js中的一个特殊关键字,this的上下文会根据调用者的不同而变化

  1. showinfo调用this关键字引用组件实例
  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 函数中 this 关键字的上下文。

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 而不是 target,target 是用户点击的元素,它可以是按钮内的任何元素,比如图像,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

学习参考