旁注:我使用的是JQuery,但没有使用任何第三方表组件(我现在也不能)。
我的问题是我应该能够显示很多(10000)正在传递的消息 - 每秒会有数百条新消息,它们应该被添加到底部。当我们达到10000限制时,旧消息将从头开始删除。
还应该有可能过滤这些消息,因此当用户在搜索框中输入内容时,只会显示包含这些字词的行。
网站结构很简单:
<div id="message_container">
<p>Message 1</p>
<p>Message 2</p>
<p>Message 3</p>
<p>Message 4</p>
</div>
目前我一次添加多条消息,速度非常快:
var newMessagesHtml = [];
// messages = new messages
for(var ii = 0; ii < messages.length; ii ++) {
newMessagesHtml.push("<p>Message</p>");
}
$("#message_container").append(newMessagesHtml.join(''));
我认为这不是问题(我缓存了message_container的查询)。但是,当我们达到10000限制并开始从顶部删除旧邮件时,这很慢。应该怎么做?我尝试使用jquery过滤n个第一条消息并将其删除,但浏览器开始变得无法响应。最好一次删除多条消息,还是一次删除多条消息?
除了JQuery之外,如果没有第三方组件,你会怎么做? 1)每秒添加和删除许多元素 2)过滤掉我们不想看到的元素
感谢所有的帮助和想法。
答案 0 :(得分:3)
对于实际的半实现,你可以试试这个。我在上面的@Jos de Jong中添加了提示,以便顺利添加/删除/搜索
QueryList类增加了添加/删除消息的可能性,queryList.items包含实际项目列表,通过设置maxItems,您可以轻松配置要查看的项目数量:)
在添加时,添加dom元素,删除dom元素也会被删除,搜索只是切换css类(删除父dom节点)
可以在此处找到示例:http://jsfiddle.net/Icepickle/j4nLh9k1/
queryList的代码
;(function($) {
function QueryItem(parentElement, value) {
this.parentElement = parentElement;
this.value = value;
this.element = undefined;
}
function QueryList(element, options) {
var that = this;
this.items = [];
this.currentQuery = undefined;
this.suspendLayout = function() {
element._oldNode = element.parentNode;
element.parentNode.removeChild(element);
};
this.resumeLayout = function() {
element._oldNode.appendChild(element);
};
this.add = function(item) {
var p, qry = new QueryItem(element, item);
var p = document.createElement('p');
if (this.currentQuery && item.indexOf(this.currentQuery) === -1) {
p.className = 'hidden';
}
p.innerHTML = qry.value;
qry.element = p;
qry.parentElement = element;
qry.parentElement.appendChild(p);
this.items.push(qry);
if (this.items.length > options.maxItems) {
this.remove(0, this.items.length - options.maxItems);
}
}
this.remove = function(index, length) {
var i, item, len;
for (i = 0, len = length || 1; i < len; i++) {
item = this.items[index];
item.parentElement.removeChild(item.element);
item.element = undefined;
}
this.items.splice(index, length);
};
this.search = function(txt) {
var i, len, item;
this.currentQuery = txt;
this.suspendLayout();
for (i = 0, len = this.items.length; i < len; i++) {
item = this.items[i];
if (txt && item.value.indexOf(txt) === -1) {
item.element.className = 'hidden';
} else {
item.element.className = '';
}
}
this.resumeLayout();
};
}
$.fn.queryList = function(options) {
if (typeof this.selector === 'undefined' || this.length !== 1) {
throw 'QueryList has to be linked to exactly one item';
}
var qry = new QueryList(this[0], options);
this.data('queryList', qry);
return qry;
};
})(jQuery);
并作为测试主要方法
$(function() {
var queryList = $('#msgContainer').queryList({
maxItems: 10000
}), index = 0, i, interval;
queryList.add('hi there');
for (i = 0; i < 7000; i++) {
queryList.add('item ' + i);
}
console.log(queryList.items);
$('#buttonSearch').on('click', function(e) {
var svalue = $('#inputSearch').val();
queryList.search(svalue);
});
interval = setInterval(function() {
queryList.suspendLayout();
for (var i = 0; i < 100; i++) {
queryList.add('Additional message ' + ((index * 100) + i));
}
queryList.resumeLayout();
index++;
}, 1000);
$('#buttonStopInterval').on('click', function(e) {
clearInterval(interval);
});
});
答案 1 :(得分:1)
选项1:
不要使用jQuery或HTML字符串。而是将您的消息创建为DOM元素,并使用JavaScript调用追加/删除它们,例如:
var newMessagesHtml = [];
var container = document.getElementById('message_container');
for(var ii = 0; ii < messages.length; ii ++) {
var msg = document.createElement('p');
msg.appendChild(document.createTextNode(messages[i]));
container.appendChild(msg);
}
如果您一次添加大量消息,可以从DOM中删除message_container
元素,向其添加所有消息,然后再将其附加到DOM,如:
var container = document.getElementById('message_container');
var parent = container.parentNode;
parent.removeChild(container);
// ...append a lot of messages...
parent.appendChild(container);
选项2:
您可以尝试React。它管理虚拟DOM并最小化真实DOM上的更新(这是瓶颈)。