我正在网格上实现虚拟滚动。滚动/按需加载功能工作非常顺利。但是,当检测到用户正在快速滚动(定义为超过450毫秒)时,会在处理过程中显示带有加载gif的半透明div。
我的问题是,在加载完成并且附加完成后,我会调用隐藏覆盖层,期望看到更新的网格。相反,我有2-3秒的延迟,然后覆盖隐藏,数据显示。
问题:
A部分:为什么div仍然保留在屏幕上,即使隐藏它的代码行在追加后...导致意外的2-3秒等待,没有进度/加载指示器用户?
B部分:在完成并渲染dom的添加之前,可以采取哪些措施来确保叠加层保持可见?
执行的行如下:
CheckToFetch(id, $(gridScrollElm).scrollTop(), true);
ToggleOverlay(gridScrollElm, false);
正如您所看到的那样,理想情况下,叠加层应在加载和渲染数据后隐藏。
CheckToFetch
后面有一系列方法调用,但我只会显示最相关的附加内容。
AppendData: function (id, data, firstTime)
{
var gd = SGrid.GetGridData(id);
var rowClass = (gd["RecordCount"] + 1) % 2; //sets us on correct course for adding AlternatingRow classes
var grid = $('#' + id)
var tbody = grid.children('tbody');
var rowsToAdd = data["Records"];
for (var r = 0; r < rowsToAdd.length; r++)
{
var elmsQueue = new Array(); //used to do efficient string concat, especially for IE
elmsQueue.push('<tr>');
for (var c = 0; c < gd['Columns'].length; c++)
{
elmsQueue.push('<td align="');
elmsQueue.push(gd['Columns'][c]['DataAlign']);
elmsQueue.push('" ');
var id = rowsToAdd[r]["id"];
var cell = rowsToAdd[r]["cell"];
if (rowClass % 2 == 0)
{
elmsQueue.push('class="AlternatingRow">');
}
else
{
elmsQueue.push('>');
}
elmsQueue.push(cell[c]);
elmsQueue.push('</td>');
}
elmsQueue.push('</tr>');
tbody.append(elmsQueue.join(''));
rowClass++;
}
答案 0 :(得分:1)
至于你的问题的 A部分,我只能假设,重绘操作(实际显示javascript操作结果的过程)可以独立于DOM操作和javascript执行运行。在您的代码中,您将多个元素附加到DOM,更新dom,向浏览器发出重排,但是(重排操作)不会将javascript执行保留。因此,如果重排持续一段时间,即使您还没有看到先前语句的结果,您最终会执行下一个javascript函数。
有几个资源涉及绘制事件和dom操作性能:http://www.html5rocks.com/en/tutorials/speed/html5/(查看优化策略部分),以及来自唯一的Paul Irish:{{3 }}
关于你问题的 B部分。如果我对A部分的假设是正确的,那么你唯一能做的就是确保将重绘操作限制在绝对最小值。为了实现这一目标,你应该暂时保留元素,直到你的全套准备好。
换句话说,继续收集新的&lt; tr&gt;数组(或字符串)中的元素,然后才进行tbody.append()
。简单来说:将DOM操作移出循环。
推迟实际的DOM修改这是一种常见的做法,也是推荐的使用脚本修改DOM的方法。
为了获得性能的每一点,您还可以尝试将实际对象(使用http://paulirish.com/2011/viewing-chromes-paint-cycle/创建)传递给append函数,而不是字符串,显然必须对其进行解析以获取列表你想要放在DOM中的元素。