将eventListener附加到javascript中的动态元素

时间:2014-10-31 03:27:49

标签: javascript javascript-events event-delegation

我正在制作待办事项列表,并且在添加新列表项时我动态添加了li和按钮标记。该按钮是一个x,它应该删除列表项。我已经尝试过几个但是无法弄清楚如何为每个单独的x按钮创建一个eventListener,并在单击它时删除相应的列表项。

renderTodos函数是创建所有动态添加内容的地方。我有一个数据索引设置到每个按钮,我试图用它来访问每个按钮,在每个动态按钮上附加一个eventListener,但我不知道如何实现它。根据我的阅读,应该有一种方法可以使用currentTarget或事件的目标来做到这一点,但我不明白它是如何工作的。

var input = document.querySelector('input[name=todoItem]'),

btnAdd = document.querySelector('button[name=add]'),
btnClear = document.querySelector('button[name=clear]'),
list = document.querySelector('.todo'),
storeList = [];

function renderTodos(){
  var el = document.createElement('li'),
  x = document.createElement('button');
  listLength = storeList.length;

  //Set text for remove button
  x.innerHTML = 'x';

  for(var i = 0; i < listLength; i++){
    el.innerHTML = storeList[i];
    list.appendChild(el);
    x.setAttribute('data-index', i);
    el.appendChild(x);
  }

  // check for correct data-index property on x button
}

function addTodos(){
  storeList.push(input.value);

  // Check that input is getting pushed to list array
  console.log(storeList);
  renderTodos();
}


function clearList(){
  // make list empty
  list.innerHTML = '';
  storeList.splice(0, storeList.length);
  //render empty list
  renderTodos();

  //Check that list array is empty
  console.log(storeList);
}

btnAdd.addEventListener('click', addTodos);
btnClear.addEventListener('click', clearList);

列表中的其他所有内容到目前为止我都无法弄清楚如何实现此eventListener。

3 个答案:

答案 0 :(得分:1)

一个简单的例子可以是

//a click hadler is added to #mylist which is already present in the dom
document.querySelector('#mylist').addEventListener('click', function(e) {
  //assuming that the the `x` is in a span and it is the only span in the `li` we check for that, we can improve this check more to make sure we have actually clicked on the delete button
  if (e.target.tagName == 'SPAN') {
    //if so then since we know the structure we can delete the parent node of the target which is the span element
    e.target.parentNode.parentNode.removeChild(e.target.parentNode);
  }
}, false);

//kindly forgive the use of jQuery here
for (var i = 0; i < 10; i++) {
  $('<li />', {
    text: i
  }).append('<span class="x">X</span>').appendTo('#mylist');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul id="mylist"></ul>

这是事件委托的一个非常基本的实现,其中实际事件绑定到祖先元素,但我们使用实际事件目标来确定是否对其执行操作。我们可以改进if条件来测试任何其他属性的类!!!

答案 1 :(得分:0)

您可以使用以下内容为每个按钮添加一个监听器:

 x.innerHTML = '';
 x.onclick = function(){
   var node = this.parentNode;
   node.parentNode.removeChild(node);
 };

或者您可以按原样保留 renderTodos 代码,并将删除委托给父级UL:

// Add the listener
list.addEventListener('click', removeItem);

// The listener function
function removeItem(event) {
  var node = event.target;

  // Check that the click came from an X button
  // better to check against a class name though
  if (node.tagName &&
      node.tagName.toLowerCase() == 'button' &&
      node.innerHTML == 'x') {
    node = node.parentNode;
    node.parentNode.removeChild(node);
  }
}

答案 2 :(得分:0)

基本上你想要做的是在父容器上添加一个事件并等待事件冒泡并确定事件源自你的x标记,然后是否触发回调函数..这是概念我认为大多数图书馆使用..

或者使用像jQuery这样的库,为什么要解决其他人已经解决的问题。