在javascript中将事件附加到动态元素

Man*_*nju 50 javascript

我正在尝试将html数据动态插入到动态创建的列表中,但是当我尝试为动态创建的按钮附加onclick事件时,事件不会触发.解决方案将非常感激.

Javascript代码:

document.addEventListener('DOMContentLoaded', function () {
document.getElementById('btnSubmit').addEventListener('click', function () {
    var name = document.getElementById('txtName').value;
    var mobile = document.getElementById('txtMobile').value;
    var html = '<ul>';
    for (i = 0; i < 5; i++) {
        html = html + '<li>' + name + i + '</li>';
    }
    html = html + '</ul>';

    html = html + '<input type="button" value="prepend" id="btnPrepend" />';
    document.getElementsByTagName('form')[0].insertAdjacentHTML('afterend', html);
});

document.getElementById('btnPrepend').addEventListener('click', function () {
    var html = '<li>Prepending data</li>';
    document.getElementsByTagName('ul')[0].insertAdjacentHTML('afterbegin', html);
});
Run Code Online (Sandbox Code Playgroud)

});

HTML代码:

<form>
    <div class="control">
        <label>Name</label>
        <input id="txtName" name="txtName" type="text" />
    </div>
    <div class="control">
        <label>Mobile</label>
        <input id="txtMobile" type="text" />
    </div>
    <div class="control">
        <input id="btnSubmit" type="button" value="submit" />
    </div>
</form>
Run Code Online (Sandbox Code Playgroud)

jil*_*ate 118

这是因为您的元素是动态创建的,您应该使用事件委托来处理事件.

 document.addEventListener('click',function(e){
    if(e.target && e.target.id== 'brnPrepend'){
          //do something
     }
 });
Run Code Online (Sandbox Code Playgroud)

jquery让它更容易:

 $(document).on('click','#btnPrepend',function(){//do something})
Run Code Online (Sandbox Code Playgroud)

这是一篇关于事件委托事件委托文章的文章

  • @Kholiavko我想说的是,只要不是动态创建“父”元素,它就可以工作。我将事件处理程序绑定到动态create d元素的第一个父对象,以便不同的事件处理程序之间没有冲突。 (2认同)
  • @Kholiavko 这只是因为 codepen 使用沙箱来包装所有内容。如果您真的在普通页面中编写这些代码,它将起作用 (2认同)
  • 考虑添加额外的等号 (===) 以防止意外的类型强制 (2认同)

Man*_*iel 11

通过捕获点击document.body然后检查事件目标,有一种解决方法.

document.body.addEventListener( 'click', function ( event ) {
  if( event.srcElement.id == 'btnSubmit' ) {
    someFunc();
  };
} );
Run Code Online (Sandbox Code Playgroud)

  • 注意:event.srcElement 已弃用。建议使用 event.target 代替。 (8认同)
  • 或最近的集装箱 (4认同)

Ric*_*ard 10

不同之处在于您如何在 DOM 中创建和附加元素。

如果您通过 来创建元素document.createElement,请添加一个事件侦听器,并将其附加到 DOM。你的事件会触发。

如果您将元素创建为这样的字符串:html += "<li>test</li>"`,则元素在技术上只是一个字符串。字符串不能有事件监听器。

一种解决方案是创建每个元素,document.createElement然后直接将它们添加到 DOM 元素。

// Sample
let li = document.createElement('li')
document.querySelector('ul').appendChild(li)
Run Code Online (Sandbox Code Playgroud)

  • 您的代码示例缺少添加侦听器的重要部分,因此给人一种错误的印象,认为这是通过使用“document.createElement”神奇地实现的。 (2认同)

R3t*_*tep 9

您需要在创建元素后附加事件.喜欢 :

document.addEventListener('DOMContentLoaded', function() {
  document.getElementById('btnSubmit').addEventListener('click', function() {
    var name = document.getElementById('txtName').value;
    var mobile = document.getElementById('txtMobile').value;
    var html = '<ul>';
    for (i = 0; i < 5; i++) {
      html = html + '<li>' + name + i + '</li>';
    }
    html = html + '</ul>';

    html = html + '<input type="button" value="prepend" id="btnPrepend" />';
    document.getElementsByTagName('form')[0].insertAdjacentHTML('afterend', html);

    document.getElementById('btnPrepend').addEventListener('click', function() {
      var html = '<li>Prepending data</li>';
      document.getElementsByTagName('ul')[0].insertAdjacentHTML('afterbegin', html);
    });

  });
});
Run Code Online (Sandbox Code Playgroud)
<form>
  <div class="control">
    <label>Name</label>
    <input id="txtName" name="txtName" type="text" />
  </div>
  <div class="control">
    <label>Mobile</label>
    <input id="txtMobile" type="text" />
  </div>
  <div class="control">
    <input id="btnSubmit" type="button" value="submit" />
  </div>
</form>
Run Code Online (Sandbox Code Playgroud)

  • 此方法仅适用于 CSR(客户端渲染)。这不适用于 SSR(服务器端渲染)。为了使其同时适用于 CSR 和 SSR,[事件委托](/sf/ask/118110751/) 是解决方案: ```javascript document.addEventListener(' click',function(e){ if(e.target &amp;&amp; e.target.id== 'brnPrepend'){ //做某事 } });``` (2认同)

Pik*_*er2 6

这是一个利用element.matches的可重用函数:

function delegate_event(event_type, ancestor_element, target_element_selector, listener_function)
{
    ancestor_element.addEventListener(event_type, function(event)
    {
        if (event.target && event.target.matches && event.target.matches(target_element_selector))
        {
            (listener_function)(event);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

以下是如何将其用于点击事件:

delegate_event('click', document, '.alert-button', your_function_here);
Run Code Online (Sandbox Code Playgroud)