Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在循环中应用addEventListener_Javascript_Loops_Addeventlistener - Fatal编程技术网

Javascript 在循环中应用addEventListener

Javascript 在循环中应用addEventListener,javascript,loops,addeventlistener,Javascript,Loops,Addeventlistener,这是我的第一个问题,因此我提前道歉,我可能会使用错误的网络礼仪 我正在探索只使用Javascript实现双向绑定的不同解决方案,在for循环中使用闭包时遇到了“常见错误”,因此计数器变量总是设置在最后一项上,我找到了解释(和解决方案)就在这个网站上,但后来我遇到了一个不同的问题,我希望能得到一些帮助 假设我们有两组数据,其中一组包含正确的数据,即: var data = { data1 : 0 }; 另一个是描述3个元素的对象集合: var elements = {

这是我的第一个问题,因此我提前道歉,我可能会使用错误的网络礼仪

我正在探索只使用Javascript实现双向绑定的不同解决方案,在for循环中使用闭包时遇到了“常见错误”,因此计数器变量总是设置在最后一项上,我找到了解释(和解决方案)就在这个网站上,但后来我遇到了一个不同的问题,我希望能得到一些帮助

假设我们有两组数据,其中一组包含正确的数据,即:

   var data = {
      data1 : 0
   };
另一个是描述3个元素的对象集合:

  var elements = {

    1 : {
      target  : 'main',
      value   : data,
      element : 'div',
      events  : {
        click : 'add'
      }
    },

    2 : {
      target  : 'main',
      value   : data,
      element : 'div',
      events  : {
        click : 'add'
      }
    },

    3 : {
      target  : 'main',
      value   : data,
      element : 'div',
      events  : {
        click : 'add'
      }
    }

  }
请参阅下面完整的代码片段

var数据={
数据1:0
};
变量元素={
1 : {
目标:'主要',
价值:数据,
元素:“div”,
活动:{
单击“添加”
}
},
2 : {
目标:'主要',
价值:数据,
元素:“div”,
活动:{
单击“添加”
}
},
3 : {
目标:'主要',
价值:数据,
元素:“div”,
活动:{
单击“添加”
}
}
}
//这是我们的主要对象,我们只定义属性。。。
var _elem=函数(道具,id){
this.id=id;
this.target=document.getElementById(props.target);
this.element=document.createElement(props.element);
this.events=props.events;
this.value=props.value;
}
//然后我们添加一个方法在页面上呈现它。。。
_elem.prototype.render=函数(){
//我添加对象Id是为了调试
this.element.innerHTML=this.value.data1+'['+this.id+']';
this.target.appendChild(this.element);
}
// ... 另一种方法是更改基础数据并重新呈现它
_elem.prototype.add=函数(){
//因为数据是对同一数据对象的引用
//我们希望更改所有元素的值
this.value.data1++;
这个。render();
}
//首先,我们使用元素定义和
//将每个项目转换为新元素
for(元素中的变量el){
元素[el]=新的元素(元素[el],el);
}
//然后我们应用事件侦听器(如果存在任何事件描述)
for(元素中的变量el){
如果(!elements[el].hasOwnProperty('events')){
继续;
} 
//我们在这里使用匿名函数以避免“常见错误”
(函数(){
var obj=元素[el];
var事件=obj.events;
用于(事件中的var ev){
addEventListener(ev,function(){obj[events[ev]]()});
}
})();    
}
//最后,我们呈现页面上的所有元素
for(元素中的变量el){
元素[el]。渲染(元素[el]);
}
div{
填充:10px;
边框:实心1px黑色;
保证金:5px;
显示:内联块;
}

问题似乎在于每次“刷新”时都要重新添加子元素,这会改变元素的顺序,并产生刷新多个元素的错觉

您需要区分初始渲染和后续刷新

我建议您从渲染函数中删除
append
,改为在最终for循环中处理append:

// And finally we render all the elements on the page  
for(el in elements){
  elements[el].render(elements[el]);
  elements[el].target.append(elements[el].element);
}
请注意,您的代码存在多个“问题”,包括多个位置的全局变量。我不相信您的体系结构能够很好地扩展。但是,这些问题超出了您的问题范围,您将边走边学习。。。没有理由期望每个人都知道一切,而且您可能会发现您当前的解决方案可以很好地满足您的需要

var数据={
数据1:0
};
变量元素={
1 : {
目标:'主要',
价值:数据,
元素:“div”,
活动:{
单击“添加”
}
},
2 : {
目标:'主要',
价值:数据,
元素:“div”,
活动:{
单击“添加”
}
},
3 : {
目标:'主要',
价值:数据,
元素:“div”,
活动:{
单击“添加”
}
}
}
//这是我们的主要对象,我们只定义属性。。。
var _elem=函数(道具,id){
this.id=id;
this.target=document.getElementById(props.target);
this.element=document.createElement(props.element);
this.events=props.events;
this.value=props.value;
}
//然后我们添加一个方法在页面上呈现它。。。
_elem.prototype.render=函数(){
//我添加对象Id是为了调试
this.element.innerHTML=this.value.data1+'['+this.id+']';
}
// ... 另一种方法是更改基础数据并重新呈现它
_elem.prototype.add=函数(){
//因为数据是对同一数据对象的引用
//我们希望更改所有元素的值
this.value.data1++;
这个。render();
}
//首先,我们使用元素定义和
//将每个项目转换为新元素
for(元素中的变量el){
元素[el]=新的元素(元素[el],el);
}
//然后我们应用事件侦听器(如果存在任何事件描述)
for(元素中的变量el){
if(!elements[e]