【问题标题】:Attaching Event handlers to dynamically created elements with a class using plain JavaScript使用纯 JavaScript 将事件处理程序附加到具有类的动态创建的元素
【发布时间】:2015-09-29 14:59:37
【问题描述】:

我构建了一个将事件处理程序附加到类的函数。它适用于页面加载期间已存在于 DOM 中的元素,但在页面加载后动态添加到 DOM 的元素上静默失败。我很感激任何建议。下面的代码是我正在开发的名为 launchjs https://github.com/bytewarestudios/launchjs 的 JavaScript 库的一部分。建议的其他解决方案仅指向我已经知道如何使用的 JQuery 代码,并且我需要一个没有 JQuery 的 JavaScript 解决方案。

我认为有一种解决方案与我在 Ram swaroop 提供的Event binding on dynamically created elements? 所需要的解决方案接近,但我不认为它指向我在将事件附加到动态创建的元素时遇到的根本问题,但它没有没有像此页面上接受的答案那样彻底地解释它。

代码的最终结果应该允许用户使用以下代码结构将事件附加到具有类的元素。

l(".className").on("click",function(event){

//do something here

});

JavaScript:

/*
  The type parameter passed in to this function is "click" and the 
  selector variable value equals .view
  Note: the isClass function returns true if the selector value is prefixed
 with a .
 */

this.on = function(type,fn){//begin on function


    //store the events
    var events = ["click","mouseover","mouseout","submit","dblclick"];


    //if the event array contains the event and the selector is not a class
    if(events.indexOf(type) !== -1 && !isClass()){//begin if then  


   //add the event listenter to the document
   document.addEventListener(type,function(event){//begin function           

           /*
            if the event listener target id equals the selector id passed to the launch
           function and the selectors doesn't contain the . prefix or class prefix.
             */
    if(event.target.id === selector){//begin if then      




              //call the function passed in as a parameter, pass the event so it can be used.
              fn(event);              


           }//end if then

      });//end function    

    }//end if then


    //if the event array contains the event and the selector is a class
    if(events.indexOf(type) !== -1 && isClass()){//begin if then  





            //store the collection of classes
            var classes = document.getElementsByClassName(selector.split(".")[1]);     

        //loop through the classes and add the event listeners
        for(var i = 0; i < classes.length; i++){

            classes[i].addEventListener(type,function(event){//begin addEventListener function        

           //add functionality for classes
           if(event.target.className === selector.split(".")[1] && isClass()){//begin if then  



              //call the function passed in as a parameter,pass the event so it can be used.
              fn(event);

           }//end if then

            });//end addEventListener function

   }//end for loop

        }//end if then         


    };//end on function  

【问题讨论】:

  • 这段代码是在添加元素后运行,还是只在 DOM 准备好的时候运行一次?
  • 只在 dom 准备好时执行一次。

标签: javascript


【解决方案1】:

您需要在每次添加新元素时运行此代码,同时确保不会将事件侦听器两次附加到旧元素,或者您可以使用委托事件技术,例如 .on()来自 jQuery。

简而言之,您将事件侦听器附加到全局容器,并检查指定类的单击元素。这是一篇关于这个概念的文章:DOM Event Delegation without jQuery

还有一个库,由同一个人针对特定案例编写:https://github.com/ftlabs/ftdomdelegate

请看我关于这个概念的简短示例:

var area = document.getElementsByClassName('clickable-area')[0];

area.onclick = function(e) {
  if (e.target.className === 'add-children') {

    var button = document.createElement('button');
    button.className = 'child-button';
    button.innerText = 'Child button';
    area.appendChild(button);

  } else if (e.target.className === 'child-button') {
    e.target.innerText = 'Dynamically added child is clicked';
  }
}
html,
body {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
}
.clickable-area {
  display: block;
  cursor: pointer;
  background: #eee;
  width: 100%;
  height: 100%;
}
<div class="clickable-area">
  <button class="add-children">Add children</button>
</div>

【讨论】:

  • 谢谢你,你的回答是一个很好的解释,我能够满足我的工作原理。
  • @LarryLane 很乐意为您提供帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-29
  • 1970-01-01
相关资源
最近更新 更多