如何在动态元素中添加eventListener?

时间:2017-12-17 07:53:36

标签: javascript



document.addEventListener('DOMContentLoaded', function() {

    var add = document.getElementById('addButton');
    var table = document.getElementById('table');
    var deleteBtn = document.querySelectorAll('.deleteButton');

    add.addEventListener('click', (e) => {
        table.innerHTML += `<div class="row">
                                <span></span>
                                <span></span>
                                <span></span>
                                <span></span>
                                <span></span>
                                <span class="deleteButton"><i class="fa fa-trash" aria-hidden="true"></i></span>
                            </div>`;
    });

    deleteBtn.forEach(function(btn) {
        btn.addEventListener('click', function() {
            console.log(this);
        })
    })

});
&#13;
body {
    width: 100vw;
    height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    background-color: #f5f5f5;
}

.wrapper {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

.table-wrapper {
    /* width: 90vw;
    max-width: 900px;
    min-height: 80px; */
    width: 600px;
    background-color: white;
    border: 1px solid #e6edf0;
    max-height: 400px;
    overflow-y: auto;
}

.table-wrapper>.row {
    height: 40px;
    width: 100%;
    border-bottom: 1px solid #ecf1f4
}

.table-wrapper>.row.header {
    background-color: #ecf1f4;
    font-weight: lighter;
    color: #b0b0b0;
    text-transform: uppercase;
}

.table-wrapper>.row>span {
    display: inline-block;
    line-height: 40px;
    text-align: center;
    font-size: 12px;
    position: relative;
}

.table-wrapper>.row>span:nth-child(1) {
    width: 40px;
}

.table-wrapper>.row>span:nth-child(2) {
    width: 80px;
}

.table-wrapper>.row>span:nth-child(3) {
    width: 60px;
}

.table-wrapper>.row>span:nth-child(4) {
    width: 60px;
}

.table-wrapper>.row>span:nth-child(5) {
    width: 80px;
}

.table-wrapper>.row>span:nth-child(6) {
    width: 40px;
    color: #c0c0c0;
}

.table-wrapper input[type=text],
.table-wrapper select {
    height: 30px;
    box-sizing: border-box;
    max-width: 50px;
    vertical-align: middle;
}

i.fa-trash {
    cursor: pointer;
    font-size: 16px;
}

.btn-wrapper {
    width: 100%;
    height: 40px;
    background-color: white;
    margin-top: 15px;
    border: 1px solid #e6edf0;
    box-sizing: border-box;
    line-height: 40px;
    text-align: center;
    font-size: 13px;
    cursor: pointer;
}
&#13;
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous>



<div class="wrapper">
        <div id="table" class="table-wrapper">
            <div class="row header">
                <span class="">idx</span>
                <span class="">name</span>
                <span class="">type</span>
                <span class="">options</span>
                <span class="">output</span>
                <span class=""> </span>
            </div>

            <div class="row">
                <span class="">1</span>
                <span class=""><input type="text" /></span>
                <span class=""><select><option>Name</option></select></span>
                <span class=""><select><option>Korean</option><option>English + Korean</option></select></span>
                <span class="">Kim</span>
                <span class="deleteButton"><i class="fa fa-trash" aria-hidden="true"></i></span>
            </div>
        </div>
        <div id="addButton" class="btn-wrapper">
            <i class="fa fa-plus" aria-hidden="true"></i> ADD ROW
        </div>
    </div>
&#13;
&#13;
&#13;

我试图用vanila JS进行开发。

我正在制作一张有add功能和delete功能的桌子。

我成功地设置了add功能,但我无法对动态元素进行delete功能。

当我点击 ADD ROW 按钮时,会在表格中添加一行。

我点击了删除图标,我希望看到console.log(this)

但是,它不起作用。

你有没有想过用vanilla JS解决这个问题?

我知道这是一个简单的问题,所以我想说对不起,非常感谢你。

摘要

如何有效地在动态元素中添加eventListener

2 个答案:

答案 0 :(得分:2)

我想做什么?

我想说一个清单。我可以通过单击按钮添加更多元素,如果单击列表项,列表的标题应该更改。

第一种方法是在代码中执行的操作。第二种方法是你应该做的修复它。

方法#1 - 这不起作用

您可以在代码段下面找到原因,为什么它不起作用。

<div class="article-img">
<img src="https://lorempixel.com/400/400/">
</div>
<div class="article-txt">
 ipsum dolor sit amet, consectetur adipiscing elit. 
</div>

<div class="article-img">
<img src="https://lorempixel.com/300/300/">
</div>
<div class="article-txt">
 ipsum dolor sit amet, consectetur adipiscing elit. Phasellus in ultrices elit. 
Nulla vel rhoncus dui.esent congue mi nibh, ut gravida tellus tincidunt at. Quisque commodo r
</div>
var title = document.getElementById("title"),
    parent = document.getElementById("parent"),
    child = document.querySelectorAll(".child"),
    add = document.getElementById("add");
    
add.addEventListener("click", function() {
  parent.innerHTML += '<li class="child">New element</li>';
});

child.forEach(function (child) {
  child.addEventListener("click", function() {
    title.innerHTML = this.innerHTML;
  });
});

这称为事件委派。首次加载页面时,动态生成的LI不在DOM中,而且没有附加到click事件。所以尝试下面的代码可以解决这个问题。

方法#2 - 应该有效

<h3 id="title">This is a title</h3>

<ul id="parent">
  <li class="child">First element</li>
  <li class="child">Second element</li>
  <li class="child">Third element</li>
  <li class="child">Fourth element</li>
</ul>

<button id="add">Add element</button>
var title = document.getElementById("title"),
    parent = document.getElementById("parent"),
    child = document.querySelectorAll(".child"),
    add = document.getElementById("add"),
    counter = 1;
    
add.addEventListener("click", function() {
  parent.innerHTML += '<li class="child">New element ' + counter + '</li>';
  counter++;
});

parent.addEventListener("click", function(e) {
  if ( e.target.nodeName == "LI" ) {
    title.innerHTML = e.target.innerHTML;
  }
});

希望此示例有助于理解事件委派。如果有任何问题,请在下方发表评论。

答案 1 :(得分:0)

使用事件委派,这是一个利用事件冒泡和事件对象Event.target(通常是单击,更改,悬停等元素)的过程。使用纯JavaScript进行事件委托的最有效方法是将一个事件监听器添加到所有目标元素共有的祖先元素(可以是parentElement(妈妈),parentElement.parentElement(祖母), ......,甚至documentwindow)。

详情在演示和Plunker

中发表了评论

演示

后的参考文献

演示

<!DOCTYPE html>
<html>

<head>
  <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
  <style>
    body {
      width: 100vw;
      height: 100vh;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      background-color: #f5f5f5;
    }
    
    .wrapper {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
    }
    
    .table-wrapper {
      /* width: 90vw;
    max-width: 900px;
    min-height: 80px; */
      width: 600px;
      background-color: white;
      border: 1px solid #e6edf0;
      max-height: 400px;
      overflow-y: auto;
    }
    
    .table-wrapper>.row {
      height: 40px;
      width: 100%;
      border-bottom: 1px solid #ecf1f4
    }
    
    .table-wrapper>.row.header {
      background-color: #ecf1f4;
      font-weight: lighter;
      color: #b0b0b0;
      text-transform: uppercase;
    }
    
    .table-wrapper>.row>span {
      display: inline-block;
      line-height: 40px;
      text-align: center;
      font-size: 12px;
      position: relative;
    }
    
    .table-wrapper>.row>span:nth-child(1) {
      width: 40px;
    }
    
    .table-wrapper>.row>span:nth-child(2) {
      width: 80px;
    }
    
    .table-wrapper>.row>span:nth-child(3) {
      width: 60px;
    }
    
    .table-wrapper>.row>span:nth-child(4) {
      width: 60px;
    }
    
    .table-wrapper>.row>span:nth-child(5) {
      width: 80px;
    }
    
    .table-wrapper>.row>span:nth-child(6) {
      width: 40px;
      color: #c0c0c0;
    }
    
    .table-wrapper input[type=text],
    .table-wrapper select {
      height: 30px;
      box-sizing: border-box;
      max-width: 50px;
      vertical-align: middle;
    }
    
    i.fa-trash {
      cursor: pointer;
      font-size: 16px;
    }
    
    .btn-wrapper {
      width: 100%;
      height: 40px;
      background-color: white;
      margin-top: 15px;
      border: 1px solid #e6edf0;
      box-sizing: border-box;
      line-height: 40px;
      text-align: center;
      font-size: 13px;
      cursor: pointer;
    }
  </style>
</head>

<body>




  <div class="wrapper">
    <div id="table" class="table-wrapper">
      <div class="row headed">
        <span class=" ">idx</span>
        <span class=" ">name</span>
        <span class=" ">type</span>
        <span class=" ">options</span>
        <span class=" ">output</span>
        <span class=" "> </span>
      </div>

      <div class="row">
        <span class=" ">1</span>
        <span class=" "><input type="text" /></span>
        <span class=" "><select><option>Name</option></select></span>
        <span class=" "><select><option>Korean</option><option>English + Korean</option></select></span>
        <span class=" ">Kim</span>
        <span class="btn deleteButton"><i class="fa fa-trash" aria-hidden="true"></i></span>
      </div>
    </div>
    <div id="addButton" class="btn btn-primary .btn-wrapper">
      <i class="fa fa-plus" aria-hidden="true"></i> ADD ROW
    </div>
  </div>





  <script>
    var add = document.getElementById('addButton');
    var table = document.getElementById('table');


    add.addEventListener('click', function(e) {

      /* insertAdjacentHTML() is like innerHTML on steroids
      || See references for details
      */
      table.insertAdjacentHTML('beforeend', `<div class="row">
                                <span></span>
                                <span></span>
                                <span></span>
                                <span></span>
                                <span></span>
                                <span class="btn deleteButton">
                                <i class="fa fa-trash" aria-hidden="true"></i>
                                </span>
                            </div>`);
    });

    /* Register table to click event...
    == if e.target (the element clicked i.e. .fa-trash) 
    || is NOT e.currentTarget 
    || (the element registered to event i.e. #table)...
    == if e.target has the class .fa-trash... 
    == Get the grandparent of e.target (i.e. .row)
    == Remove the .row
    */
    table.addEventListener('click', function(e) {
      if (e.target !== e.currentTarget) {
        if (e.target.classList.contains('fa-trash')) {
          var row = e.target.parentElement.parentElement;
          table.removeChild(row);
        }
        /* Prevent the event bubbling to keep
        || any unwanted elements from being 
        || triggered
        */
        e.stopPropagation();
      }
    }, false);
  </script>
</body>

</html>

参考

Event Delegation

insertAdjacentHTML()

Event.target

Event.currentTarget