使用多个列表元素提高纯Javascript平滑滚动的性能

时间:2014-01-30 19:44:53

标签: javascript html css performance scroll

我正在使用纯CSS和Javascript中的the recent, 30-year Apple Mac retrospective复制项目的小时间线。我有第一个全屏英雄的基本布局和扇形,扩展悬停工作适当。但是在屏幕的后半部分平滑滚动时间轴无法正常工作,即使在Mac OS X上的Google Chrome 32.0.1700.102中滚动速度非常慢obviously jittery。您可以下载一个包含{{{3}的文件夹。 1}}和必要的CSS和JS here

具体来说,我的两个问题是:

  1. 什么是纯CSS / JavaScript解决方案来修复此平滑滚动?我很感激调试这个例子的东西,而不是指向另一个,工作的。

  2. 相关的,我可以/应该做些什么来调试这个以隔离问题?我天真地试图收集一个JavaScript CPU配置文件,但没有任何东西跳出来需要注意。


  3. 基本结构

    时间轴的结构为index.html,其中包含一个有序列表,每个nav包含项目,

    Screenshot of the <code>nav</code> with overlapping project <code>li</code>'s

    li

    我有一个简单的事件循环来检测全局鼠标位置并处理滚动检测,

    <nav id='timeline'>
        <ol>
            <li class='project' id='zero'>
                <div class='description'>
                    <h2> Project 0 </h2>
                    <span> The project that changed everything </span>
                    <div class='icon'></div>
                </div> <!-- div.description -->
            </li> <!-- li.project#zero -->
        </ol>
    </nav> <!-- nav#timeline -->
    

    反过来每10ms调用一个简单的滚动处理程序,

    // 20ms event loop to update a global mouseX, mouseY position and handle scroll detection
    var mouseX = null;
    var mouseY = null;
    var scrollTimeline = null;
    var updateInterval = 10;
    var scrolling = false;
    window.onmousemove = function(event) {
        mouseX = event.clientX;
        mouseY = event.clientY;
        if (!scrollTimeline) {
            scrollTimeline = window.setInterval(scroll, updateInterval);
        }
    };
    

    所有实际滚动都是通过以function scroll(event) { var buffer = window.innerWidth/4; var distanceToCenter = Math.abs(window.innerWidth/2-mouseX); var speed = distanceToCenter/(window.innerWidth/2); if (mouseX < buffer) { scrolling = true; scrollLeft(speed); } else if ((window.innerWidth - mouseX) < buffer) { scrolling = true; scrollRight(speed); } else { scrolling = false; window.clearInterval(scrollTimeline); scrollTimeline = null; } } left两个函数调整包含nav的{​​{1}}属性来完成的,scrollRightscrollLeft参数取决于鼠标位置。

    speed

    function scrollRight(speed) { var leftPixels = parseInt(getStyleProp(timeline, 'left'), 10); var toShift = Math.pow(speed,3)*updateInterval; var newLeft = leftPixels - toShift; if (newLeft >= -1400 && newLeft <= 0) { timeline.style.left = newLeft + 'px'; } } 是一个简单的实用函数,用于获取计算出的getStyleProp属性(如果尚未显式设置,我从this answer复制):

    left

    我尝试了什么

    所以,在完成所有这些基础知识之后,我尝试过:

    • 删除一些创建扇形效果的CSS过渡
    • 使用一张图片而不是六张
    • 在循环中调整// Utility function to grab style properties when unset function getStyleProp(elem, prop){ if(window.getComputedStyle) return window.getComputedStyle(elem, null).getPropertyValue(prop); else if(elem.currentStyle) return elem.currentStyle[prop]; //IE } ,一次调整一个像素,而不是小跳跃
    • 删除任何包含的文本及其转换。
    • 删除left中包含的任何li - 这解决了问题,但我不确定为什么/如何导致observed jitter

    谢谢!

1 个答案:

答案 0 :(得分:0)

原来的抖动是由于在CSS中使用saturate转换的开销。我使用requestAnimationFrame找到了更好的解决方案。