Javascript for loop firebase update
Javascript for loop firebase update
我有一个新闻提要,使用 Firebase,我希望能够 "check" 一键阅读所有新闻条目。
HTML:
<ul id="news" class="dropdown-menu" role="menu">
<li id="newsitem_read">Mark all as read</li>
<li id="-K230_cSX_TOYlXfSjul" class="newsitem unread-true">message</li>
<li id="-K247s6SLY4AGliAUIik" class="newsitem unread-true">message</li>
<li id="-K24820ZIQR8LqThIRFb" class="newsitem unread-true">message</li>
</ul>
Javascript:
var news = greatnonsens.child('users/<?=$_SESSION['user']['id']; ?>/news_feed/');
var read = document.getElementById('newsitem_read');
read.addEventListener('click', function() {
var to_read = document.getElementsByClassName('unread-true');
// Check news feed is not empty
if (typeof to_read[0] !== 'undefined') {
for (var i = 0; i < to_read.length; i++) {
news.child(to_read[i].id).update({unread: 'false'});
// document.getElementById(to_read[i].id).className = 'newsitem unread-false';
console.log(to_read[i].id);
}
}
});
这是可行的,但如果我也 运行 document.getElementById(to_read[i].id).className = 'newsitem unread-false' 它只会每隔一秒更新一次新闻(与 Firebase on.(child_changed) 函数相同)。如果我将其注释掉,所有新闻项目都会更新。
我错过了什么?
调用 getElementsByClassName
returns 所谓的 live 节点列表。当您删除 unread-true
class 时,该元素也会从 to_read
.
中删除
假设您从 to_read
中的 4 个项目开始:
0. item1
1. item2
2. item3
3. item4
在循环的第一次迭代中:i=0
,因此您删除了 item1
。由于列表是 live,item1
也立即从 to_read
:
中删除
0. item2
1. item3
2. item4
在第二次迭代中:i=1
,因此您删除了 item3
。这再次立即从 to_read
中删除,它变为:
0. item2
1. item4
在下一次迭代中:i=2
,因为 to_read.length
现在也是 2,我们退出循环。
解决方案
有很多方法可以解决这个问题。我将给出一个更简单的方法,即以相反的顺序循环遍历项目:
for (var i = to_read.length-1; i >= 0; i--) {
news.child(to_read[i].id).update({unread: 'false'});
// document.getElementById(to_read[i].id).className = 'newsitem unread-false';
console.log(to_read[i].id);
}
使用此代码,我们将从 i=3
开始。当我们从该元素中删除 unread-true
class 时,它也会再次从 to_read
中删除。但是现在在循环的下一次迭代中,i=3
和 to_read
仍然有 2 个项目,所以循环继续。
我有一个新闻提要,使用 Firebase,我希望能够 "check" 一键阅读所有新闻条目。
HTML:
<ul id="news" class="dropdown-menu" role="menu">
<li id="newsitem_read">Mark all as read</li>
<li id="-K230_cSX_TOYlXfSjul" class="newsitem unread-true">message</li>
<li id="-K247s6SLY4AGliAUIik" class="newsitem unread-true">message</li>
<li id="-K24820ZIQR8LqThIRFb" class="newsitem unread-true">message</li>
</ul>
Javascript:
var news = greatnonsens.child('users/<?=$_SESSION['user']['id']; ?>/news_feed/');
var read = document.getElementById('newsitem_read');
read.addEventListener('click', function() {
var to_read = document.getElementsByClassName('unread-true');
// Check news feed is not empty
if (typeof to_read[0] !== 'undefined') {
for (var i = 0; i < to_read.length; i++) {
news.child(to_read[i].id).update({unread: 'false'});
// document.getElementById(to_read[i].id).className = 'newsitem unread-false';
console.log(to_read[i].id);
}
}
});
这是可行的,但如果我也 运行 document.getElementById(to_read[i].id).className = 'newsitem unread-false' 它只会每隔一秒更新一次新闻(与 Firebase on.(child_changed) 函数相同)。如果我将其注释掉,所有新闻项目都会更新。
我错过了什么?
调用 getElementsByClassName
returns 所谓的 live 节点列表。当您删除 unread-true
class 时,该元素也会从 to_read
.
假设您从 to_read
中的 4 个项目开始:
0. item1
1. item2
2. item3
3. item4
在循环的第一次迭代中:i=0
,因此您删除了 item1
。由于列表是 live,item1
也立即从 to_read
:
0. item2
1. item3
2. item4
在第二次迭代中:i=1
,因此您删除了 item3
。这再次立即从 to_read
中删除,它变为:
0. item2
1. item4
在下一次迭代中:i=2
,因为 to_read.length
现在也是 2,我们退出循环。
解决方案
有很多方法可以解决这个问题。我将给出一个更简单的方法,即以相反的顺序循环遍历项目:
for (var i = to_read.length-1; i >= 0; i--) {
news.child(to_read[i].id).update({unread: 'false'});
// document.getElementById(to_read[i].id).className = 'newsitem unread-false';
console.log(to_read[i].id);
}
使用此代码,我们将从 i=3
开始。当我们从该元素中删除 unread-true
class 时,它也会再次从 to_read
中删除。但是现在在循环的下一次迭代中,i=3
和 to_read
仍然有 2 个项目,所以循环继续。