代码之家  ›  专栏  ›  技术社区  ›  Sviat Kuzhelev

闭包在循环中不能正常工作

  •  1
  • Sviat Kuzhelev  · 技术社区  · 8 年前

    我想做一个函数 getDelete() 那会 创建onclick事件 用于删除图元 text pointDel . 最后一个将由支持功能创建和包含 createPoindetDel() 用于创建3个元素 波因德尔 .

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

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

    附笔。 我必须使用这些结构。我不能简化它。

    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 回复  |  直到 8 年前
        1
  •  1
  •   SShah Marc B    8 年前

    将事件侦听器添加到“p”元素时,可以使用索引:

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

    删除元素时,会更改数组的长度(文本)。正当 然后,当您尝试删除另一个元素时,可以使用前面定义的索引进行尝试,例如索引位置2。但新数组的位置2没有元素。

    如果您尝试先单击最后一个“x”,则代码将毫无问题地运行。因为这样,您将删除最大的索引。

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

    编辑: 注意,我把 位置:相对 在您的 .文本块 类,并在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
  •  1
  •   Ziv Weissman    8 年前

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

    1. 您正在删除文本元素,在文本元素中有“.delete”元素。

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

    下面的代码将修复这些问题,但您必须处理已修复的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() {this.parentElement.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
  •   Ruslan    8 年前

    我认为可以简化一点:

    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>