jQuery 滚动事件 - 检测元素滚动到视图中 - Chrome 上的性能不佳

Posted

技术标签:

【中文标题】jQuery 滚动事件 - 检测元素滚动到视图中 - Chrome 上的性能不佳【英文标题】:jQuery scroll event - detecting element scrolled into view - poor performance on Chrome 【发布时间】:2011-07-13 03:31:28 【问题描述】:

以下代码在 IE 和 Firefox 上运行良好,但 Chrome 讨厌它(它可以运行但真的很滞后)。我相信它可以使浏览器更加友好,但是如何呢? itemPlaceholder 是数百个 100x100 的浮动 div(例如图像占位符)。我正在使用 jquery 1.4.4 和 Chrome v10.0.648.127。

$(function () 

   ReplaceVisible();
   $(this).scroll(function () 
      ReplaceVisible();
   );
);

function ReplaceVisible() 
    $('.itemPlaceholder').each(function (index) 
        if (HasBeenScrolledTo(this)) 
            $itemPlaceholder = $(this);

            $itemPlaceholder.replaceWith('<img src="bicycle.jpg" />');
        
        else 
            return false;
        
    );


function HasBeenScrolledTo(elem) 
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();
    var elemTop = $(elem).offset().top;

    return elemTop < docViewBottom;

编辑:append 替换为replaceWith,否则我们会在同一元素上附加大量图像。

【问题讨论】:

【参考方案1】:

这在 chrome 中运行缓慢,因为 chrome 在页面滚动时会不断触发 onscroll 事件(IE 和 firefox 仅在滚动停止时触发 onscroll)。

在这种情况下,您可以通过将 ReplaceVisible 的调用排队并只允许它在给定时间段内触发一次来提高 chrome 的性能。此处提供了排队调用的示例 (https://github.com/tilleryj/rio/blob/master/public/javascripts/lib/delayed_task.js)

【讨论】:

直接从马嘴里:ejohn.org/blog/learning-from-twitter 嗯,chrome 确实会产生更多的滚动事件,但不是数量级的。该问题似乎是由编辑 DOM(附加)引起的。去掉那条线,滚动就顺畅了。【参考方案2】:

我遇到了类似的问题,我必须检测调整大小事件,正如您所料,这会触发大量事件并锁定浏览器。不过我还没有测试过,所以如果它有效,请回来报告。 :)

$(function () 
   replaceVisible();
   $(this).scroll( replaceVisible );
);

var replaceVisible = (function()
    var last_scroll = null;    // Last time we scrolled
    var paused = false; // We've paused scrolling
    var delay = 1000; // Delay in between acting on the scroll (ms).
    return function()
        if( paused ) return;
        if( new Date() - last_scroll < delay )
            setTimeout( function() paused = false; replaceVisible(); , delay )
            paused = true;
        
        $('.itemPlaceholder').filter(HasBeenScrolledTo)
            .replaceWith('<img src="bicycle.jpg" />');
        last_scroll = new Date();
    
)();

function HasBeenScrolledTo(index) 
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();
    var elemTop = $(this).offset().top;
    return elemTop < docViewBottom;

【讨论】:

感谢您的代码,我从中学到了很多,我确信它减少了浏览器的负载。但是 Chrome 仍然不喜欢 DOM 编辑.. :( 您可以尝试加载所有内容,但将 隐藏,然后在您希望它可见时调用 show()?如果您需要更精确的帮助,您必须发布一个测试页面,因为我不确定为什么 Chrome 现在会出现代码问题。

以上是关于jQuery 滚动事件 - 检测元素滚动到视图中 - Chrome 上的性能不佳的主要内容,如果未能解决你的问题,请参考以下文章

ScrollViewer - 指示子元素滚动到视图中

SwiftUI Drag 事件如何限制仅检测水平/垂直滚动

jquery判断滚动条滚到页面底部并执行事件

仅当不在视图中时才滚动到元素 - jQuery

仅在不在视图中时滚动到元素 - jQuery

javascript 检测向下滚动和向上事件jQuery