7

我想更改视口内元素的背景颜色(使用overflow: scroll

所以这是我的第一次尝试:http: //jsfiddle.net/2YeZG/

如您所见,在绘制新颜色之前,先前的颜色会短暂闪烁。其他人也类似的问题

按照HTML5 Rocks 的说明,我尝试引入requestAnimationFrame来解决这个问题,但无济于事:

http://jsfiddle.net/RETbF/

我在这里做错了什么?


这是一个显示相同问题的更简单示例:http: //jsfiddle.net/HJ9ng/


在此处提交了 Chromium 的错误:http ://code.google.com/p/chromium/issues/detail?id=151880

4

3 回答 3

1

如果它只是背景颜色,那么为什么不将父背景颜色更改为红色,一旦滚动就将其更改为粉红色?

我将您的 CSS 更改为

#dad
{
    overflow-y: scroll;
    overflow-x: hidden;
    width: 100px;
    height: 600px;
    background-color:red;
}​

我删除了你们中的一些 Jquery 并将其更改为

dad.bind('scroll', function() {
    dad.css('background-color', 'pink');
});

我删除了这条线

iChild.css('backgroundColor', 'red');

但是红色很重要,它肯定不会起作用 http://jsfiddle.net/2YeZG/5/

于 2012-09-21T02:33:40.320 回答
0

我喜欢曼努埃尔的解决方案。但即使我不明白你到底想要做什么,我还是想指出一些事情。在您的小提琴代码中,我看到您将 Paul Irish 的 Shim 包含在 requestAnimationFrame 中。但你从不使用它。(它基本上是一个可靠的 setTimeOut,仅此而已)它来自基于帧的动画。)

因此,既然您只想更改一些 CSS 属性,我不明白您为什么需要它。即使你想要过渡,你也应该依赖 CSS 过渡。

除此之外,您的代码可能看起来像

dad.bind('scroll', function() {
  dad.css('background-color', 'pink');
  eachElemNameHere.css('background-color','randomColor');
});

另外,如果可以提供帮助,最好不要使用类似的东西。您应该只添加和删除类名并在 CSS 中添加所有这些属性。使其工作得更快。

此外,我还是不太明白,但您可以使用 jQuery 函数从顶部找出每个元素的位置,以便更好地控制。

于 2012-10-20T19:26:07.520 回答
0

您的问题似乎是您只更改了已滚动到视图中的元素的背景颜色。您的代码期望浏览器在浏览器重绘其视图之前等待您的代码处理滚动事件。这很可能不是 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 或更高,我无法产生任何闪烁。

顺便说一句:如果你做的事情比仅仅改变背景颜色更复杂,你不应该一次又一次地这样做。相反,您应该检查元素是否已经更新并仅在之后执行更改。

于 2012-10-21T12:26:05.827 回答