简体   繁体   English

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

[英]How to handle events in dynamically created elements in js

I want to add the click event to a created Element dynamically that when user click on button create some elements (elements that show in code below) and when user click on element named remov must run function named deltion BUT that doesnt work .How can I implemented that?我想动态地将点击事件添加到创建的元素中,当用户单击按钮时创建一些元素(在下面的代码中显示的元素)并且当用户单击名为remov 的元素时必须运行名为删除的 function 但不起作用。我该如何实施了吗?

I use Vue js我使用 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();
     }

There are three issues with your code.您的代码存在三个问题。

First Issue: invoking a function on the event listener第一个问题:在事件监听器上调用 function

you are calling the deltion (maybe you mean deletion:P) function when you register the event listener.当您注册事件侦听器时,您正在调用 deltion(也许您的意思是删除:P)function。

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

the correct form is正确的形式是

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

Because you want to pass the function body to the event listener, not the function result.因为您想将 function 主体传递给事件侦听器,而不是 function 结果。 (you can wrap the function in an arrow function if you want to call it, but at the end is the same). (如果你想调用它,你可以将 function 包裹在箭头 function 中,但最后是一样的)。

Second Issue: this is not this第二个问题:这不是这个

If you fix the first one, you'll find another one (the life of programmers).如果你修复了第一个,你会找到另一个(程序员的生活)。 this is a special keyword in js, the context of this will change depending on the caller. this是 js 中的一个特殊关键字,它的上下文根据调用者的不同而改变。

  1. showinfo is called the this keyword refers to the component instance. showinfo 被称为this关键字是指组件实例。
  2. db.collection("Studnets").get().then(function(querySnapshot) {}) promise is called and on resolve it will call the function that has querySnapshot parameter. db.collection("Studnets").get().then(function(querySnapshot) {}) promise 被调用,解析时它将调用具有 querySnapshot 参数的 function。 **this** keyword context changes. **this**关键字上下文更改。
  3. you iterate the collection with a foreach querySnapshot.forEach(function(doc) {}) **this** keyword context is changed again.您使用 foreach querySnapshot.forEach(function(doc) {}) **this**关键字上下文再次更改集合。

A solution will be to use arrow functions so this don't get bonded to the parent function.一个解决方案是使用箭头函数,这样它就不会绑定到父 function。

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

If for some reason you can't use arrow functions, you can add a variable that "shadows" the context of the this keyword on the showinfo function.如果由于某种原因您不能使用箭头函数,您可以在 showinfo function 上添加一个“隐藏” this关键字上下文的变量。

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

Third Issue: clicking the arrow image will delete the button but not the tr Use currentTarget instead of the target, the target is the element the user click, it can be any element inside the button like the image, currentTarget is the element that the event listener is attached aka the button.第三个问题:点击箭头图片会删除按钮但不会删除tr使用currentTarget代替target,target是用户点击的元素,可以是按钮内的任意元素,比如图片,currentTarget是事件发生的元素侦听器附加了又名按钮。

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

Unsolicited Advice不请自来的建议

Vue excels with its simplicity and declarative code. Vue 以其简单性和声明性代码而著称。 You can solve the problem like your original code, but there is a simpler way to let the component manage its state .您可以像原始代码一样解决问题,但有一种更简单的方法可以让组件管理其 state

I replicated your code with the original version fixed and the simplest vue way (with a simple empty and loading state toggle).我使用固定的原始版本和最简单的 vue 方式复制了您的代码(使用简单的空和加载 state 切换)。 Hope you find it useful and learn from this.希望你觉得它有用并从中学习。 :) https://codesandbox.io/s/student-list-ammar-yasir-b5sxo?file=/src/App.vue :) https://codesandbox.io/s/student-list-ammar-yasir-b5sxo?file=/src/App.vue

Learning references学习参考

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM