您的问题似乎是您只更改了已滚动到视图中的元素的背景颜色。您的代码期望浏览器在浏览器重绘其视图之前等待您的代码处理滚动事件。这很可能不是 HTML 规范给出的保证。这就是它闪烁的原因。
相反,您应该做的是更改将要滚动到视图中的元素。这与计算机游戏编程中所称的离屏渲染或双缓冲有关。您在屏幕外构建场景并将完成的场景复制到可见帧缓冲区。
我修改了您的第一个 JSFiddle 以包含滚动区域高度的乘数:http: //jsfiddle.net/2YeZG/13/。
dad.bind('scroll', function() {
// new: query multiplier from input field (for demonstration only) and print message
var multiplier = +($("#multiplier")[0].value);
$("#message")[0].innerHTML=(multiplier*100)-100 + "% of screen rendering";
// your original code
var newScrollY = newScrollY = dad.scrollTop();
var isForward = newScrollY > oldScrollY;
var minVal = bSearch(bots, newScrollY, true);
// new: expand covered height by the given multiplier
// multiplier = 1 is similar to your code
// multiplier = 2 would be complete off screen rendering
var newScrollYHt = newScrollY + multiplier * dadHeight;
// your original code (continued)
var maxVal;
for (maxVal = minVal; maxVal < botsLen; maxVal++) {
var nxtTopSide = tops[maxVal];
if (nxtTopSide >= newScrollYHt) {
break;
}
}
maxVal = Math.min(maxVal, botsLen);
$(dadKids.slice(minVal, maxVal)).css('background', 'pink');
});
您的代码的乘数为 1,这意味着您更新了当前可见的元素(滚动区域高度的 100%)。如果将乘数设置为 2,您将获得所有元素的完整屏幕外更新。浏览器将足够多的元素更新为新的背景颜色,因此即使 100% 滚动也会显示更新的元素。由于浏览器很少一步滚动 100% 的区域(取决于操作系统和滚动方法!),将乘数降低到例如 1.5(意味着屏幕渲染减少 50%)可能就足够了。在我的机器(Google Chrome、带触摸板的 Mac OS X)上,如果乘数为 1.7 或更高,我无法产生任何闪烁。
顺便说一句:如果你做的事情比仅仅改变背景颜色更复杂,你不应该一次又一次地这样做。相反,您应该检查元素是否已经更新并仅在之后执行更改。