繁体   English   中英

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

[英]Improving the performance of a pure Javascript smooth scroll with multiple list elements

我正在用纯CSS和Javascript复制最近30年的Apple Mac回顾,以期用于一小段项目。 我具有第一个全屏英雄的基本布局,并且扇贝形的,悬停扩展的功能正常工作。 但是,在屏幕的后半部分无法平滑滚动时间轴,即使在Mac OS X上的Google Chrome 32.0.1700.102中,即使滚动非常慢也显然会产生抖动 。您可以下载一个index.html这里需要CSS和JS。

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

  1. 修复此平滑滚动的纯CSS / JavaScript解决方案是什么? 我希望能调试一下此示例,而不是将我引向另一个正在运行的示例。

  2. 和相关的,我应该/应该做些什么来调试此问题以隔离问题? 我天真地尝试收集JavaScript CPU配置文件,但是没有什么需要注意的。


基本结构

时间轴的结构为包含有序列表的nav ,每个li包含项目,

带有重叠项目<code> li </ code>的<code> nav </ code>的屏幕截图

<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 -->

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

// 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);
    }
};

依次每10ms调用一次简单的滚动处理程序,

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;
    }
}

所有实际的滚动都是通过使用两个函数scrollRightscrollLeft来调整包含navleft属性来完成的,滚动函数取决于鼠标的位置,使用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是一个简单的实用程序函数,如果未显式设置该属性(我从此答案复制而来),则用于获取计算出的left属性):

// 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
}

我尝试过的

因此,在不考虑所有这些基础知识的情况下,我尝试过:

  • 删除一些创建扇形效果的CSS过渡
  • 使用一张图片代替六张图片
  • 循环left调整,一次调整一个像素,而不是小的跳跃
  • 删除任何包含的文本及其过渡。
  • 并删除nav包含的所有li这解决了问题,但是我不确定为什么/如何会导致观察到的抖动

谢谢!

原来的抖动是由于在CSS中使用saturate变换的开销所致。 我发现了使用requestAnimationFrame更好的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM