闭包在循环

时间:2018-01-26 09:26:38

标签: javascript html function loops

我尝试创建一个功能getDelete()创建onclick事件,以删除元素textpointDel。最后一个将由支持函数createPoindetDel()创建并包含,用于创建3个元素pointDel

我尝试了几种方法来解决这个问题,但仍然没有正确的结果。我的函数结果仍然是未捕获的TypeError:无法读取未定义的属性'remove'我希望删除多个块。

我认为两个函数的闭包问题。

P.S。 我必须使用这些结构。我无法简化它。

function createPoindetDel(text) {

    for (var i = 0; i < text.length; i++ ) (function(i) {

  	var textCoords = text[i].getBoundingClientRect();	

	var pointDel = document.createElement('p');
            pointDel.innerHTML = '[x]';
	    pointDel.className = 'deleting';
	    pointDel.style.top = textCoords.top + pageYOffset + 'px';
	    pointDel.style.left = textCoords.right + pageXOffset + 'px';
				
	text[i].appendChild(pointDel);

	return pointDel;
    })(i);		
}

function getDelete() {

    var text = document.getElementsByClassName('text-block');
  	  		
    createPoindetDel(text); 

    var p = document.getElementsByClassName('deleting');

    for (var j = 0; j < text.length; j++ ) (function(j) {
    
  	p[j].addEventListener( 'click', function() {text[j].remove()} );
	p[j].addEventListener( 'click', function() {p[j].remove()} );	
 
    })(j);
}

getDelete();
.text-block {
 	max-width: 500px;
 	height: auto;
 	padding: 20px;
 	border-top: 2px #C4DF9B solid;
 	background-color: #EDF5E1;
 	margin-bottom: 0;
}

.text-block span {
 	font-size: 18px;
 	font-weight: bold;
 	color:  #111;
 	margin-top: 0;
}

 .text-block p {
 	font-size:  15px;
 	margin-bottom: 0;
 	color: #111;

}

.deleting {
   position:absolute;
   float:right;
   margin:0px;
   top: 0;
   right: -20px;
   display:inline;
   cursor:pointer;
}
<!DOCTYPE HTML>
<html>

<head>
  <meta charset="utf-8">
  <style>
  </style>
</head>
<body>
	<div class="text-block">
		<span>Horse</span>
		<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec.</p>
	</div>
	<div class="text-block">
		<span>Pig</span>
		<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec.</p>
	</div>
		<div class="text-block">
		<span>Mul</span>
		<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec.</p>
	</div>

<script>
</script>
</body>
</html>

3 个答案:

答案 0 :(得分:1)

这里有两个问题,实际上与闭包无关。

  1. 您正在删除文本元素,在文本元素中您有&#34; .delete&#34;元件。

  2. 您正在尝试挂起正在更改的数组指针。 (一旦删除,数组将会改变,但你仍然试图删除j = 2,例如数组中不存在 - 因为它只有2个元素)

  3. 下面的代码将解决这些问题,但您必须处理已修复的CSS。

    &#13;
    &#13;
    function createPoindetDel(text) {
    
        for (var i = 0; i < text.length; i++ ) (function(i) {
    
      	var textCoords = text[i].getBoundingClientRect();	
    
    	var pointDel = document.createElement('p');
                pointDel.innerHTML = '[x]';
    	    pointDel.className = 'deleting';
    	    pointDel.style.top = textCoords.top + pageYOffset + 'px';
    	    pointDel.style.left = textCoords.right + pageXOffset + 'px';
    				
    	text[i].appendChild(pointDel);
    
    	return pointDel;
        })(i);		
    }
    
    function getDelete() {
    
        var text = document.getElementsByClassName('text-block');
      	  		
        createPoindetDel(text); 
    
        var p = document.getElementsByClassName('deleting');
    
        for (var j = 0; j < text.length; j++ ) (function(j) {
        
      	p[j].addEventListener( 'click', function() {this.parentElement.remove()});
    	//p[j].addEventListener( 'click', function() {p[j].remove()} );	
     
        })(j);
    }
    
    getDelete();
    &#13;
    .text-block {
     	max-width: 500px;
     	height: auto;
     	padding: 20px;
     	border-top: 2px #C4DF9B solid;
     	background-color: #EDF5E1;
     	margin-bottom: 0;
    }
    
    .text-block span {
     	font-size: 18px;
     	font-weight: bold;
     	color:  #111;
     	margin-top: 0;
    }
    
     .text-block p {
     	font-size:  15px;
     	margin-bottom: 0;
     	color: #111;
    
    }
    
    .deleting {
       position:absolute;
       float:right;
       margin:0px;
       top: 0;
       right: -20px;
       display:inline;
       cursor:pointer;
    }
    &#13;
    <!DOCTYPE HTML>
    <html>
    
    <head>
      <meta charset="utf-8">
      <style>
      </style>
    </head>
    <body>
    	<div class="text-block">
    		<span>Horse</span>
    		<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec.</p>
    	</div>
    	<div class="text-block">
    		<span>Pig</span>
    		<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec.</p>
    	</div>
    		<div class="text-block">
    		<span>Mul</span>
    		<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec.</p>
    	</div>
    
    <script>
    </script>
    </body>
    </html>
    &#13;
    &#13;
    &#13;

答案 1 :(得分:1)

当您向'p'元素添加事件侦听器时,可以使用索引来执行此操作:

p[j].addEventListener( 'click', function() {text[j].remove()} );
// you are accessing the j index from the text array

删除元素时,可以更改数组的长度(文本)。对? 然后,当您尝试删除另一个元素时,可以使用之前定义的索引(例如索引位置2)尝试它。但是新数组在位置2中没有元素。

如果您尝试先单击最后一个'x',您的代码将运行没有问题。因为这样,你将删除最大的索引。

很难解释。 但您可以尝试使用事件的函数范围来解决:

编辑: 请注意,我将位置:相对放在 .text-block 类中,并在JS中注释了您的位置黑客。这也将修复你的CSS。

尝试更改您的事件功能:

function createPoindetDel(text) {

  for (var i = 0; i < text.length; i++ ) (function(i) {

    var textCoords = text[i].getBoundingClientRect();	
    var pointDel = document.createElement('p');
		
    pointDel.innerHTML = '[x]';
    pointDel.className = 'deleting';
    //pointDel.style.top = textCoords.top + pageYOffset + 'px';
    //pointDel.style.left = textCoords.right + pageXOffset + 'px';
			
    text[i].appendChild(pointDel);

    //return pointDel;
  })(i);		
}

function getDelete() {
  var text = document.getElementsByClassName('text-block');
  createPoindetDel(text); 
  var p = document.getElementsByClassName('deleting');

  for (var j = 0; j < text.length; j++ ) (function(j) {
    p[j].addEventListener( 'click', function() {
      //here 'this' is the element that was clicked, and parentElement you can supose! =)
      this.parentElement.remove() 
    });
  })(j);
}

getDelete();
.text-block {
  position:relative;
  max-width: 500px;
  height: auto;
  padding: 20px;
  border-top: 2px #C4DF9B solid;
  background-color: #EDF5E1;
  margin-bottom: 0;
}

.text-block span {
  font-size: 18px;
  font-weight: bold;
  color:  #111;
  margin-top: 0;
}

 .text-block p {
  font-size:  15px;
  margin-bottom: 0;
  color: #111;

}

.deleting {
   position:absolute;
   float:right;
   margin:0px;
   top: 0;
   right: -20px;
   display:inline;
   cursor:pointer;
}
<!DOCTYPE HTML>
<html>

<head>
  <meta charset="utf-8">
  <style>
  </style>
</head>
<body>
	<div class="text-block">
		<span>Horse</span>
		<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec.</p>
	</div>
	<div class="text-block">
		<span>Pig</span>
		<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec.</p>
	</div>
		<div class="text-block">
		<span>Mul</span>
		<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec.</p>
	</div>

<script>
</script>
</body>
</html>

答案 2 :(得分:0)

我认为可以简化一下:

function getDelete() {
  var text = document.getElementsByClassName('text-block');
  var pointDel;
  for (var i = 0; i < text.length; i++) {
    pointDel = document.createElement('div');
    pointDel.innerHTML = '[x]';
    pointDel.className = 'deleting';
    pointDel.addEventListener('click', function() {
      var text = this.parentNode;
      text.parentNode.removeChild(text);
    });
    text[i].appendChild(pointDel);
  }
}

getDelete();
.text-block {
  color: #111;
  max-width: 500px;
  padding: 20px;
  border-top: 2px #C4DF9B solid;
  background: #EDF5E1;
  position: relative;
}

.text-block span {
  font-size: 18px;
  font-weight: bold;
}

.text-block p {
  font-size: 15px;
  margin-bottom: 0;
}

.deleting {
  position: absolute;
  top: 0;
  right: -20px;
  cursor: pointer;
}
<div class="text-block">
  <span>Horse</span>
  <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec.</p>
</div>
<div class="text-block">
  <span>Pig</span>
  <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec.</p>
</div>
<div class="text-block">
  <span>Mul</span>
  <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec.</p>
</div>