我有多个html元素,其中包含一个数字。
每次单击按钮都会将该数字减少-1。
当数字等于0时,必须删除元素。
我的代码仅删除了一半的元素,我不明白为什么...
JsFiddle DEMO
<div class='moo'>3</div>
<div class='moo'>3</div>
<div class='moo'>3</div>
<div class='moo'>3</div>
<div class='moo'>3</div>
<div class='moo'>3</div>
<div class='moo'>3</div>
<div class='moo'>3</div>
<div class='moo'>50</div>
<button id='bubu'>Remove</button>
JS:
$(document).on('click','#bubu',function(){
var x = document.getElementsByClassName('moo');
for(var i = 0; i < x.length; i++){
if( Number(x[i].innerHTML) > 0 ) {
x[i].innerHTML = Number(x[i].innerHTML) - 1;
}
if( Number(x[i].innerHTML) == 0 ){
x[i].remove();
}
}
});
(i)用replace和innerHTML删除是不可能的,这是一个简化的html。
答案 0 :(得分:2)
这是因为当您删除项目时,x
节点列表的长度会变小,并且您使用该长度作为循环条件,直到。
如果从节点列表的末尾删除项目并向后工作,则此方法将起作用,因为从末尾删除允许循环条件缩小,而无需跳过节点列表中的任何元素:
$(document).on('click','#bubu',function(){
var x = document.getElementsByClassName('moo');
for(var i = x.length-1; i >= 0 ; i--){
if( Number(x[i].innerHTML) > 0 ) {
x[i].innerHTML = Number(x[i].innerHTML) - 1;
}
if( Number(x[i].innerHTML) == 0 ){
x[i].remove();
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='moo'>3</div>
<div class='moo'>3</div>
<div class='moo'>3</div>
<div class='moo'>3</div>
<div class='moo'>3</div>
<div class='moo'>3</div>
<div class='moo'>50</div>
<div class='moo'>3</div>
<div class='moo'>3</div>
<button id='bubu'>Remove</button>
话虽如此,但是您的方法存在许多问题:
.getElementsByClassName()
返回“活动”节点列表,实际上不应该使用。阅读another post of mine,其中会对此进行详细说明。
.innerHTML
具有安全和性能方面的意义,仅当您使用的字符串包含HTML时才应使用。如果字符串中没有HTML,请使用.textContent
。
使用数组及其内置的.forEach()
方法进行迭代,而不是依赖于必须通过循环管理的数字计数器。
这是相同的结果,以更加简洁和高效的方式完成:
$('#bubu').on('click', function(){
// Get the elements into an Arrray without a live node list
var elements = Array.prototype.slice.call(document.querySelectorAll(".moo"));
// Loop over the array
elements.forEach(function(element){
// Get the text of the element and convert to a number. The prepended + symbol does this.
let elNum = +element.textContent;
// Instead of two consecutive if/then statements, use one with an else if
if(elNum > 0) {
element.textContent = --elNum; // Just set the content to 1 less
} else if(elNum === 0){
element.remove();
}
});
});
.moo { display:inline-block; font-size:1.5em; color:#f00; border:1px solid grey; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='moo'>3</div>
<div class='moo'>3</div>
<div class='moo'>4</div>
<div class='moo'>3</div>
<div class='moo'>3</div>
<div class='moo'>3</div>
<div class='moo'>50</div>
<div class='moo'>3</div>
<div class='moo'>5</div>
<button id='bubu'>Remove</button>
答案 1 :(得分:1)
getElementsByClassName返回一个动态集合,因此当您从DOM中删除项目时,集合的大小会减小,解决此问题的最简单方法是将集合隐式转换为标准数组
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:webfeed/webfeed.dart';
class Food extends StatelessWidget{
final client = http.Client();
rssStream(){
client.get("https://developer.apple.com/news/releases/rss/releases.rss").then((response) {
return response.body;
}).then((bodyString) {
var channel = new RssFeed.parse(bodyString);
print(channel);
return channel;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: Image.asset('assets/icon.png'),
title: Text('App'),
),
body: rssStream(),
);
}
}